Openzeppelin-contracts: Create PoW mining validation contracts

Created on 9 Feb 2018  路  8Comments  路  Source: OpenZeppelin/openzeppelin-contracts

馃帀 Description

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

  • [ ] 馃悰 This is a bug report.
  • [x] 馃搱 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

contracts feature

Most helpful comment

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.

All 8 comments

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

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.

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

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) )

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.

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();
}

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.

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.

Was this page helpful?
0 / 5 - 0 ratings