Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create PoW mining validation contracts #727

Closed
1 of 2 tasks
maraoz opened this issue Feb 9, 2018 · 8 comments
Closed
1 of 2 tasks

Create PoW mining validation contracts #727

maraoz opened this issue Feb 9, 2018 · 8 comments
Labels
contracts Smart contract code. feature New contracts, functions, or helpers.

Comments

@maraoz
Copy link
Contributor

maraoz commented Feb 9, 2018

馃帀 Description

Idea taken from @shrugs' image, in turn taken from 0xBitcoin:
1_w262dszig5yxzaf2zg5uwq

  • 馃悰 This is a bug report.
  • 馃搱 This is a feature request.

I'd make it generic, i.e not tied to token minting, as in the image, and maybe then add a MinedToken that uses the generic mining validation contracts

@maraoz maraoz added the feature New contracts, functions, or helpers. label Feb 9, 2018
@arisAlexis
Copy link

interesting! how would a miner interact with this contract? you need to pay gas for each submission?

@alcuadrado
Copy link

This implementation is vulnerable to front-running. But you can easily fix that with something like
bytes32 digest = keccak256(lastNonce, nonce, msg.sender);.

This way the proof of work is tied to whoever did it, and no front-running is possible.

@shrugs
Copy link
Contributor

shrugs commented Feb 9, 2018

Updated contract should be

contract MineableToken is MintableToken {
  public uint256 blockHeight = 0;
  public uint256 lastNonce = 0;

  function getDifficulty() public returns (uint256) {
    return <some-difficulty-function>
  }

  function mint(uint256 nonce) public returns (bool success) {
    bytes32 digest = keccak256(msg.sender, lastNonce, nonce);
    require(uint256(digest) < getDifficulty());

    lastNonce = nonce
    blockHeight += 1
    return super.mint(msg.sender, 1);
  }
}

Mining would look like

const coinbase = web3.eth.accounts[0]
const lastNonce = await mineableToken.lastNonce()
const difficulty = await mineableToken.getDifficulty()
const randomNonce = () => BigNumber.random(78).mul(10 ** 78)  // this probably works, idk
let isValid = false
let nonce
while (!isValid) {
  nonce = randomNonce()
  const digest = web3.utils.keccack256(coinbase, lastNonce, nonce)
  // ^ make sure the bytes workout here, idk
  isValid = digest < difficulty
}

await mineableToken.mint(nonce)
// yay

@AugustoL
Copy link
Contributor

Super interesting !! want to see it in zeppelin

It can also have a getReward() function, that returns the reward of the block number mined, it can be deflationary.

Also it can have a fee per transfer, like take 1 wei for each transfer and claim all the feeBalance every time a block is mined, this way when you reach a block reward of cero you still have the fee reward.

The difficulty can be calculated knowing only how much time it took to mine the last block ? smth like:

if (lastBlockTime < blockTime)
  increaseDifficulty( blockTime.sub(lastBlockTime) )
else
  decreaseDifficulty( lastBlockTime.sub(blockTime) )

@alcuadrado
Copy link

alcuadrado commented Feb 11, 2018

I like the idea of validating PoW in a smart contract, but I wouldn't couple its implementation to minting a token.

  1. While miners do PoW for earning cryptocurrencies, that's not the purpose of the PoW. Block rewards are just a way of incentivize people to secure a blockchain. If obtaining new tokens is the entire purpose of the PoW it would only model the distribution of the tokens. The same distribution can probably be obtained in a more environmentally friendly way.

  2. It inhibit other (IMO more interesting) uses of it. The first uses that come to my mind: making spam and sibyl attacks more expensive, and hopefully impractical.

@shrugs
Copy link
Contributor

shrugs commented Feb 11, 2018

Yeah totally agreed, glad you brought that up!

So now we've got a Mineable interface that implements PoW checking and exports a verifyProofOfWork(nonce, difficulty) function.

Then MineableToken is Mineable, MintableToken and mint looks like

function mint(_to, uint256 nonce) external returns (bool success) {
  require(verifyProofOfWork(nonce, getDifficulty()));
  
  adjustDifficulty();
  return mint(msg.sender, getReward();
}

@nventuro
Copy link
Contributor

nventuro commented Mar 8, 2019

It inhibit other (IMO more interesting) uses of it. The first uses that come to my mind: making spam and sibyl attacks more expensive, and hopefully impractical.

I really liked the whole PoW idea, but had never come up with a use case that went beyond toy projects such as minting tokens. This, however, seems super neat.

@nventuro nventuro added the contracts Smart contract code. label Mar 8, 2019
@nventuro nventuro added this to the v2.3 milestone Mar 8, 2019
@nventuro nventuro removed this from the v2.3 milestone Apr 8, 2019
@nventuro
Copy link
Contributor

nventuro commented Apr 8, 2019

After discussing this further with @alcuadrado, we came to the conclusion that placing PoW requirements for prevent spam wouldn't really be a great solution, since it is not very expensive to purchase computing power (much) more powerful than the equivalent of running JavaScript inside a browser.

I think many of us like this idea because it sounds cool, but it lacks a real use-case. Closing until one comes up.

@nventuro nventuro closed this as completed Apr 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contracts Smart contract code. feature New contracts, functions, or helpers.
Projects
None yet
Development

No branches or pull requests

6 participants