Giter VIP home page Giter VIP logo

eth-random's Introduction

RNG on Ethereum blockchain

Obtaining a reliable source of randomness on Ethereum is no easy task. The best pattern we chose to ultimately implement on CryptoKitties is known as commit-reveal. See original GeneScience contract here for an example

The main constraints we conformed to are:

  1. Get an arbitrary amount of random numbers per block
  2. Run cheaply
  3. Be unpredictable and not manipulable

At the time a kitty gets pregnant we know from which block it will be able to be born, let's call the block height DDB. Therefore we save DDB to the kitty struct at time of pregnancy.
Then after DDB is achieved, a birther will call the give birth function, which is roughly: R = uint256(block.blockhash(DDB-1)) [1].

For Cryptokitties purposes, other elements go into this hash as well, BUT it's important that any elements that go into that hashing are unable to be changed.

Then R can be bitsliced to make power of 2 numbers that make random slices of it [2]. If more random numbers are necessary, it's possible to continually re-hash R and obtain equaly strong random numbers.

[1] Can only get the last 256 block hashes, otherwise it will return 0, which sucks. Cryptokitties implement 2 fallbacks: first an economic measure, anyone is able to give birth to kitties and get an Ether reward for that. The second one is to check if R==0, and (loosely speaking) add 256 until we get a R != 0.

[2] May use a bit slicing function and keep an index of how many bits have been used so far as a variable that you increment.

Analysis

In addition to good quality of number generation, several concerns play when harvesting random numbers from blockchains, so let's address the main points.

Predictability

Since the block hash in the future is unknown, it's unpredictable at the time of commit.

User manipulation

No user should be able to seed or tamper with the RNG input. As we discussed in item [1] above, counter measures must be in place to prevent "re-rolls".

Miner manipulation

Miners are a powerful force in every aspect that comes into play when creating a block, because well, they create the blocks. Block hashes happen to be the hardest element to meddle with due to how PoW functions, miners are lucky to mine a block and get it's reward, by essentially finding a fitting hash, and if a miner is to keep on re-hashing the block until it's satisfied with the hashing result, it will end up failing to be the winner for that block height, as other miners will propose a block before them.

Given the current state of Ethereum, the described RNG method seems safe, as long as the possible reward from the RNG result is not big enough to have miners altering their mining behaviour. Such value is estimated at 0.25ETH.

With Casper PoS changes in 2020, RNG methods that rely on blockhash entropy might become more easily exploitable.

Low cost

This technique gas cost is pretty low. The most costly element requires the cost of 1 update in an existing storage word, and that would happen anyways as kitties get pregnant. Hashing and bit manipulation operations are not expensive.

Links of interest:

  1. Presentation at Ethdenver 2019 about random-number generation
  2. Cryptokitties blog post on GeneScience
  3. @Razor talk on the topic
  4. Consensys Smart contract recommendations
  5. A multi input based random generation

Contributing

PR > new issue. Welcome pull requests that:

  1. Improve the quality of the information
  2. Adds an example in solidity #8
  3. Adds links of interest

Acknowledgement

While the final mechanism implemented in Cryptokitties was developed and implemented by @dete and @flockonus, @Arachnid had a major contribution to the mechanism. Also thanks to constructive criticism by @MicahZoltu and @Raz0r, among others.

eth-random's People

Contributors

flockonus avatar kaicode2 avatar wfossett avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

eth-random's Issues

Random numbers can be predicted

The current implementation can be predicted:

  • block.blockhash(block.number) will always be zero, since block hash is not known until block is mined;
  • seed can be looked up in the contract storage on the blockchain prior to the call, e.g. using web3.eth.getStorageAt();
  • now is shared within internal messages in the same transaction, so we can make an exploit contract that will call target contract.

Consider switching to commit-reveal approach or using an externally updated seed.

Why does RPG.sol example use Random at another address rather than inheriting it?

Hi,

Just wondering about the RPG.sol example:
https://github.com/axiomzen/eth-random/blob/master/example/contracts/RPG.sol#L18

Would it be just as good if RPG inherited from Random so you wouldn't have to pay the extra gas for calling another contract? CALL costs 700 gas whereas JUMP only costs 1 gas. If you're doing this (and/or the network gets overloaded and gas prices), seems like you'd make a good saving by inheriting from Random rather than calling it from an external contract.

Is the above accurate?

Make README more clear about tradeoffs and purpose

Received a great feedback at OpenZeppelin's #article channel, ended up discussing about a lot of tradeoffs and design decisions we talked about a lot with @KaiCode2 and @jordanschalm and we absolutely should make room for those on the README

Namely:

  1. State clearly our motivation pursuing this implementation
  2. List the tradeoffs made in the process, make recommendations around mitigating the potential dominant miner possible exploit (there could be a case if the smart contract that is using random has reward that is large enough)
  3. Explore possibilities around micah.zoltu suggestion on eliminating the use of now

In addition to those, it would make sense to use Github release feature to release of a Smart Contract to a certain commit, as we are likely to release other versions of Random with more features in the near future.

Add alternative: https://github.com/randao/randao

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.