以太坊solidity
This article was created in partnership with iOlite. Thank you for supporting the partners who make SitePoint possible.
本文是与iOlite合作创建的。 感谢您支持使SitePoint成为可能的合作伙伴。
Solidity is a fairly new language and as no code is perfect, it contains issues related to the code and what you want to accomplish with it. This article will guide you through the best practices and pitfalls when using a random number as input for your Ethereum smart contract.
Solidity是一种相当新的语言,并且因为没有完美的代码,所以它包含与代码有关的问题以及您希望使用它完成的工作。 本文将指导您在使用随机数作为以太坊智能合约输入时的最佳做法和陷阱。
固体随机数生成 (Solidity Random Number Generation)
Solidity is not capable of creating random numbers. Actually, every algorithm for creating random numbers is pseudorandom — no language is capable of creating completely random numbers. The problem with Solidity is that complex algorithms cost too much, so more basic solutions are used. Besides that, Solidity code should be deterministic, as it will run on multiple nodes. We need an algorithm that is able to generate a random number once, and use it on multiple nodes. Things like a clock time are not available for generating random numbers, so we have to look at other options. As a developer, you should be aware of this problem because an attacker is able to predict the result in some specific cases.
实体不能创建随机数。 实际上,每种用于创建随机数的算法都是伪随机的,没有一种语言能够创建完全随机的数。 Solidity的问题在于复杂算法的成本过高,因此使用了更多基本解决方案。 除此之外,Solidity代码应具有确定性,因为它将在多个节点上运行。 我们需要一种能够一次生成随机数并在多个节点上使用的算法。 诸如时钟时间之类的东西不可用于生成随机数,因此我们必须考虑其他选项。 作为开发人员,您应该意识到此问题,因为攻击者可以在某些特定情况下预测结果。
One of the most commonly used algorithms is ‘linear congruential generator’ (LCG). It’s one of the oldest algorithms, fast, and easy to understand. LCG is a good option for embedded systems as they have a limited amount of memory. However, it is not well-suited for cryptographically secure applications. Although, this is still being used in smart contracts as a fast algorithm is much cheaper to implement in terms of gas costs.
最常用的算法之一是“线性同余生成器”(LCG)。 它是最古老的算法之一,快速且易于理解。 对于嵌入式系统,由于内存量有限,LCG是一个不错的选择。 但是,它不适用于密码安全的应用程序。 虽然,这种方法仍在智能合约中使用,因为就天然气成本而言,快速算法的实现成本要低得多。
The algorithm itself performs these steps:
该算法本身执行以下步骤:
- Accept input 接受输入
- Execute algorithm on the input 在输入上执行算法
- Take modulus of output (divide by max number in the range you require) 取输出模数(在所需范围内除以最大数量)
- Output between 0 and max number in the range you require 输出0到所需范围内的最大数字
Let’s explore the different ways of creating random numbers using a Lottery smart contract example. Users are able to join the Lottery by sending 0.1 Ether to the contract together with an integer between 0 and 250.
让我们使用彩票智能合约示例探索创建随机数的不同方法。 用户可以通过向合约发送0.1个以太币以及0到250之间的整数来加入彩票。
1. Block.timestamp和Block.difficulty (1. Block.timestamp & Block.difficulty)
A block.timestamp
is assigned by the miner whenever he confirms the transaction. No player of our Lottery contract is able to control it. Let’s take a look at this piece of code for creating a random number.
每当矿工确认交易时,便block.timestamp
分配block.timestamp
。 我们的彩票合同的任何玩家都无法控制它。 让我们看一下用于创建随机数的这段代码。
function random() private view returns (uint8) {
return uint8(uint256(keccak256(block.timestamp, block.difficulty))%251);
}
在这里找到要点 。
This piece of code first hashes a block timestamp and difficulty. Next, we convert the hash to an integer and divide it by 251 to get an integer between 0 and 250. However, the problem with this piece of code is that we shouldn’t trust a miner for picking a winner.
这段代码首先散列了块的时间戳和难度。 接下来,我们将哈希转换为整数,然后将其除以251,得到0到250之间的整数。但是,这段代码的问题在于,我们不应该信任矿工来选择获胜者。
2.彩票输入-任意数据 (2. Lottery Input – Arbitrary Data)
We need more arbitrary data for picking our winner. We can use the addresses of the players that have entered our lottery smart contract, but we have to hide it from other players as they can abuse it. Hiding this information is not possible as it’s all recorded on the blockchain.
我们需要更多任意数据来挑选我们的赢家。 我们可以使用已进入彩票智能合约的玩家的地址,但是我们必须对其他玩家隐藏该地址,因为他们可能会滥用它。 隐藏这些信息是不可能的,因为它们都记录在了区块链上。
The numbers submitted to our lottery smart contract can be used. Users have to hash the number they pick together with their Ethereum address. This gives us a pretty random number.
可以使用提交给我们的彩票智能合约的号码。 用户必须对他们选择的数字以及以太坊地址进行哈希处理。 这给了我们一个相当随机的数字。
3.其他机制 (3. Other Mechanisms)
3.1以太坊闹钟 (3.1 Ethereum Alarm Clock)
Developers need to think about when to pick a winner. Things like clock time are not available in the Ethereum Virtual Machine, as the code will run on multiple nodes, on a different time. This makes it even harder to pick a winner. One way to do it is by implementing a function in your smart contract that will close the lottery and pick a winner. This is not as decentralized as we want it to be. The owner of the contract can close the lottery when he is sure a friend of theirs will win. We want to avoid this kind of cheating.
开发人员需要考虑何时选择获胜者。 以太坊虚拟机中不提供时钟时间之类的功能,因为代码将在不同的时间在多个节点上运行。 这使得选择获胜者变得更加困难。 一种方法是在智能合约中实现一项功能,该功能将关闭彩票并选择中奖者。 这并不像我们希望的那样分散。 合同的所有者确定自己的朋友会中奖时,可以关闭彩票。 我们要避免这种作弊行为。
A better option is to use the Ethereum Alarm Clock. It is a service that allows scheduling transactions to be executed at a later time on the Ethereum blockchain. This service is completely trustless, meaning that the entire service operates as a smart contract. Basically, the Ethereum Alarm Clock is using the block number to schedule transactions. Watch out, it doesn’t mean that the contract wakes up on its own. It relies on users having an interest (Ether reward) for calling the ‘pick winner’ function. Of course, if nobody calls your function, your lottery will fail.
更好的选择是使用以太坊闹钟。 它是一项服务,允许计划在以后在以太坊区块链上执行交易。 该服务是完全不信任的,这意味着整个服务都作为智能合约运行。 基本上,以太坊闹钟使用区块号来安排交易。 注意,这并不意味着合约会自动唤醒。 它依赖于具有兴趣(以太坊奖励)的用户来调用“拣选获胜者”功能。 当然,如果没有人调用您的函数,您的彩票将失败。
3.2随机数据输入 (3.2 Random Data Input)
Random.org provides an API which gives you a random source of data through JSON. An Ethereum smart contract can use this source of data to feed an algorithm that picks a random number. As security is important, it is possible to use digital signing. The random data will be signed by Random.org. You can verify the integrity of the data so you can prove it really came from Random.org and the data hasn’t been tampered with.
Random.org提供了一个API,可通过JSON为您提供随机数据源。 以太坊智能合约可以使用此数据源来提供选择随机数的算法。 由于安全性很重要,因此可以使用数字签名。 随机数据将由Random.org签名。 您可以验证数据的完整性,从而可以证明数据确实来自Random.org,并且数据未被篡改。
RANDAO is a new project in the blockchain space that is solely focused on providing random numbers. They use a combination of oracles and smart contracts to provide you with random numbers. However, the RANDAO service is pretty slow at the moment. This is not ideal if you have an application that is often used.
RANDAO是区块链领域的一个新项目,仅专注于提供随机数。 他们结合使用oracle和智能合约为您提供随机数。 但是,目前RANDAO服务非常慢。 如果您拥有经常使用的应用程序,那么这是不理想的。
3.3块号观察器 (3.3 Blocknumber Watcher)
You can also use a watcher in your code, which checks the block number until it matches the target number you have set.
您还可以在代码中使用观察程序,该监视程序检查块编号,直到与您设置的目标编号匹配为止。
function f( blocknumber, to_address, value_) {
var filter = web3.eth.filter('latest').watch(
function(err, blockHash) {
var target=blocknumber;
if(web3.eth.blockNumber==target) {
filter.stopWatching(); // your function here
web3.eth.sendTransaction({to:to_address, from:web3.eth.coinbase, value: web3.toWei(value_,"ether")});
filter = null;
console.warn('Block reached');
if (callback) return callback(false);
else return false;
} else {
console.log('Waiting the block');
}
});
};
3.4 iOlite智能合约创建 (3.4 iOlite Smart Contract Creation)
iOlite is creating a product that accepts natural language to create smart contracts. It is using a Stanford Natural Language Processing (NLP) engine called Fast Adaptation Engine (FAE). iOlite relies on community training by Solidity experts. Solidity experts (contributors) can define structures containing one or more sentences and attach it to the corresponding smart contract code.
iOlite正在创建一种接受自然语言的产品来创建智能合约。 它使用的是斯坦福自然语言处理(NLP)引擎,称为快速适应引擎(FAE)。 iOlite依靠Solidity专家进行的社区培训。 团结专家(贡献者)可以定义包含一个或多个句子的结构,并将其附加到相应的智能合约代码。
The Stanford NLP engine has been created to understand complex language. The level of language complexity depends on the amount of machine training. After appropriate training, the engine will be capable of creating complex smart contracts. The FAE is capable of creating such contracts, as a complex contract is actually not that complex. Experts can split the request into multiple smaller pieces of code and attach it to one sentence.
斯坦福大学NLP引擎已经创建,可以理解复杂的语言。 语言复杂程度取决于机器培训的数量。 经过适当的培训,引擎将能够创建复杂的智能合约。 FAE能够创建此类合同,因为复杂的合同实际上并不那么复杂。 专家可以将请求分成多个较小的代码段,并将其附加到一个句子中。
When someone inputs multiple sentences, it will look for corresponding structures/sentences to build the ‘complex’ contract. Contributors will be rewarded with iOlite tokens via the mining process of new structures.
当有人输入多个句子时,它将寻找相应的结构/句子以构建“复杂”合同。 通过新结构的挖掘过程,贡献者将获得iOlite代币奖励。
The benefit of using iOlite is that smart contract experts can solve difficult problems for you like the generation of random numbers. You can find more information at iOlite.io.
使用iOlite的好处是,智能合约专家可以为您解决难题,例如生成随机数。 您可以在iOlite.io上找到更多信息。
结论 (Conclusion)
As you can see, it isn’t an easy task to generate true random input. Do not rely on block.timestamp
, now
and block.blockhash
as a source of randomness. A good solution includes a combination of several pseudorandom data inputs and the use of oracles or smart contracts to make it more reliable. You need to be 100% sure nobody can tamper with the data that’s being inputted into your smart contract.
如您所见,要生成真正的随机输入并非易事。 不要依赖block.timestamp
, now
和block.blockhash
作为随机源。 一个好的解决方案包括几个伪随机数据输入的组合,以及使用Oracle或智能合约来使其更可靠。 您需要100%确保没有人可以篡改智能合约中输入的数据。
Be careful and think twice before implementing random number generation logic.
在实施随机数生成逻辑之前,请三思而后行。
翻译自: https://www.sitepoint.com/solidity-pitfalls-random-number-generation-for-ethereum/
以太坊solidity