Random Number Generator in Contracts. Image Credit: Nick Hillier from Unsplash
Blockchain-based contracts often need to generate random numbers for use cases such as gaming, gambling, simulation and more.
Furthermore, these random numbers must be non-predictable so that developers, users, and block generators cannot predict them in advance and use this knowledge to make a profit.
The key to be able to generate reproducible non-predictable random numbers are:
During normal operation, a blockchain generates data which is somewhat random like block ids or transaction ids. The problem is that a transaction id is simple to manipulate by the account submitting the transaction, and a block id is simple to manipulate by the block generator. This means that using this information alone to initialize a random seed will provide power users and block generators an unfair advantage.
As we can see, since you cannot rely directly on data generated within the blockchain, generating this reproducible and non-predictable seed is not a simple task.
You may ask, can we use some kind of Oracle contract to obtain random data from an external source (like random.org)? Sure we can, but this opens up other attack vectors like DNS spoofing or potential for a direct hack of random.org. In addition, it is expensive to write this data into the blockchain for later use by other contracts. With that in mind, who is financing the operation of this Oracle contract, and what are their motives?
Another approach for generating random numbers, which is promoted by the Ethereum team, is Randao. The idea is to use a two-stage approach and a complex incentive structure to compensate users for registering random data on the blockchain. This idea is slow and expensive, and surely we can do better.
Introducing the Ardor Lightweight Contract Random Seed Generation
Fast forward to lightweight contracts. In the Ardor platform, we can use two properties unique to lightweight contracts.
First, only specific nodes execute contracts. This provides us with a unique source of random data unavailable to other protocols, namely the contract runner node itself.
Second, the ability to send encrypted messages is built natively into the Ardor blockchain. This allows users to provide random data directly to the contract runner account without revealing it to anyone else.
Given these properties the contract can now compose the random seed from three different independent sources:
The contract runner concatenates and hashes these three sources of randomness together to generate a reproducible seed. This seed is difficult to predict as the account submitting the transaction and the block generator need to cooperate and collude with the contract runner. The block generator and the account triggering the contract cannot predict the random numbers alone.
But as always with lightweight contracts, we still need to trust the contract runner not to cheat, and to verify this, the contract runner must share its secret random seed securely with a validator node before executing the contract. Validators can then repeat the seed calculation and verify that the contract runner indeed executed the contract stored in the blockchain and calculated the random seed according to the protocol. In this case, a multi-signature setup where the validator account needs to approve every transaction submitted by the contract runner provides extra protection.
Lightweight contracts provide a simple and pragmatic solution to the complex problem of generating reproducible non-predictable random numbers.
Learn more about Lightweight Contracts in Ardor.