I read somewhere that smart contract languages need to be deterministic. Why?
2 Answers
As reminded in the first comment from Richard, smart contracts have to be deterministic because each nodes of the network have to be able to find the same result given the same input for a contract method. Otherwise each node that executes the contract method to validate the transaction would end with different results and no consensus would be possible.
But why the smart contract language itself such as Solidity have to be deterministic? It doesn't have to be.
Solidity is deterministic because it's a convenient language well designed for its purpose, but the Lisk network for instance uses standard JavaScript which is not deterministic. That means that nothing can avoid the use of a method to generate a random value in Lisk smart contracts. Developers thus have to be very careful to avoid using non deterministic functions. Sometimes this can be tricky. Math.random() function is obvious, but some other math methods can use roundings that won't always give the same result or some date functions as the new Date() which gives the current date and is thus non deterministic. As you can read in the Lisk documentation developers are warned not to use this functions. But if you are not careful you can completely wreck your contract.
The power of Solidity and other deterministic languages is that developers don't even have to care about determinism because there is no non deterministic functions in the language.
-
1How do blockchain platforms (ex. Lisk and Fabric) make sure if the code of the non deterministic language (ex. Javascript and Golang) is deterministic? Or they don't check if the smart contract code is deterministic, then consensus just fails? May 4, 2016 at 0:35
-
2They use a type of sharding, where each contract runs on its own chain, so consensus on the state of that contract can fail without harming other contracts. This cannot happen on Ethereum, since it would break network consensus May 4, 2016 at 4:03
-
How does sharding work in this context? Is a contract deployed in one of blockchains? It sounds like the contract needs to reach consensus in that blockchain, so the contract code still needs to be deterministic. May 5, 2016 at 0:39
-
-
@Nicolas Massart The more fundamental question I have is what does it mean to say Solidity is deterministic? so solidity does not return error or exception? for a given input to a function in solidity, there is only one output? Aug 19, 2018 at 18:07
The determinism prevent any fork in the network. The same goes for Solidity which uses the EVM.
To complete @NicolasMassart 's answer and @user1870400 comment that proposes to generate random values based on a possible Solidity implementation of the Go code used for random number generation, based on https://golang.org/src/math/rand/rng.go you can notice that this code doesn't rely on any random at all but uses hard coded entropy.
If you try it twice without specifying entropy, you'll get the same predictable result. To use this in a concrete use-case, you're supposed to bring your own source of entropy, i.e.: rand.NewSource(time.Now().UnixNano()) for example.
Hopefully inside the EVM, each source of entropy generate the same value for a single transaction across each node of the network, whether you use the timestamp (aka block.timestamp or now -- because it's the timestamp of the time the block was issue by the single miner of this block) or any other pseudo random value.
So even implementing this algorithm in a smart contract using Solidity will lead to a deterministic result.
-
How about using previous block hash as an entropy source during a fork? I understand the longest chain wins and in the end(after consensus) everyone will have same blockchain. But say during the fork where multiple chains are competing what if a function uses previous block hash as an entropy source? There is a point in time where I tend to think it is nondeterministic although the end result (after consensus) is the same. May 29, 2019 at 6:05
-
If you use the previous block hash: 1. you have about 15 sec during which everyone know the randomness and can create transactions fitting their needs 2. a miner who's about to publish a block with a specific block hash can refrain from doing it if it generates a unpleasant randomness for him. Jun 7, 2019 at 11:52
-
Sure I am not questioning the validity of the end result and I understand consensus is there to guard. But your response sounds like we are in an agreement that is we should be able to observe the random behaviour during the fork when a user invokes a transaction that calls the rand function which uses previous block hash as a seed implemented in the contract itself. Let me know if you disagree Jun 8, 2019 at 9:29