Solidity是一种至关新的语言,由于没有代码是完美的,它包含与代码相关的问题以及你但愿用它完成的任务。本文将指导你使用随机数做为以太坊智能合约的输入时的最佳实践和陷阱。php
Solidity没法建立随机数。实际上,每一个建立随机数的算法都是伪随机的——没有语言可以建立彻底随机的数字。Solidity的问题在于复杂的算法成本过高,所以使用了更基本的解决方案。除此以外,Solidity代码应该是肯定性的,由于它将在多个节点上运行。咱们须要一种可以生成一次随机数的算法,并在多个节点上使用它。像时钟时间这样的东西不能用于生成随机数,所以咱们必须查看其余选项。做为开发人员,你应该了解此问题,由于攻击者可以在某些特定状况下预测结果。java
最经常使用的算法之一是“线性同余发生器”(LCG)。它是最古老的算法之一,快速且易于理解。LCG是嵌入式系统的一个很好的选择,由于它们的内存有限。可是,它不适合加密安全应用程序。虽然,这仍然在智能合约中使用,由于快速算法在气体成本方面实施起来便宜得多。node
算法自己执行如下步骤:python
让咱们探讨使用彩票智能合约示例建立随机数的不一样方法。用户能够经过向合约发送0.1以太以及0到250之间的整数来加入彩票。android
每当他确认交易时,矿工就会分配一个block.timestamp
。咱们的彩票合约的任何玩家都没法控制它。让咱们看看这段代码来建立一个随机数。程序员
function random() private view returns (uint8) { return uint8(uint256(keccak256(block.timestamp, block.difficulty))%251); }
这段代码首先hash了一个块时间戳和难度。接下来,咱们将hash转换为整数并将其除以251以得到0到250之间的整数。可是,这段代码的问题在于咱们不该该信任矿工来挑选胜利者。web
咱们须要更多任意数据来挑选咱们的赢家。咱们可使用已经进入咱们的彩票智能合约的玩家的地址,可是咱们必须将其隐藏在其余玩家以外,由于他们能够滥用它。隐藏此信息是不可能的,由于它所有记录在区块链上。算法
提交给咱们的彩票智能合约的号码可使用。用户必须将他们选择的号码与他们的以太坊地址一块儿hash。这给了咱们一个至关随机的数字。mongodb
开发人员须要考虑什么时候选择胜利者。时间之类的东西在以太坊虚拟机中不可用,由于代码将在不一样的时间在多个节点上运行。这使得挑选胜利者变得更加困难。实现这一目标的一种方法是在智能合约中实施一项功能,该功能将关闭彩票并选择获胜者。这不像咱们但愿的那样去中心化。合约的全部者在肯定他们的朋友将获胜时能够关闭彩票。咱们想避免这种做弊行为。编程
更好的选择是使用以太坊闹钟。它是一种容许稍后在以太坊区块链上执行调度事务的服务。这项服务彻底没有信任,这意味着整个服务做为智能合约运做。基本上,以太坊闹钟使用块号来安排交易。注意,这并不意味着合约自己就会被唤醒。它依赖于有兴趣的用户(以太奖励)来调用“挑选获胜者”功能。固然,若是没有人打电话给你的功能,你的彩票就会失败。
Random.org提供了一个API,经过JSON为你提供随机数据源。以太坊智能合约可使用此数据源来提供选择随机数的算法。因为安全性很重要,所以可使用数字签名。随机数据将由Random.org签署。你能够验证数据的完整性,以便证实它确实来自Random.org而且数据未被篡改。
RANDAO是区块链领域的一个新项目,专一于提供随机数。他们使用oracles和智能合约的组合为你提供随机数字。可是,RANDAO服务目前至关缓慢。若是你拥有常用的应用程序,这并不理想。
你还能够在代码中使用观察程序,它会检查程序段编号,直到它与你设置的目标编号相匹配。
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'); } }); };
iOlite正在建立一种接受天然语言来建立智能合约的产品。它使用称为快速自适应引擎(FAE)的斯坦福天然语言处理(NLP)引擎。iOlite依靠Solidity专家的社区培训。Solidity专家(贡献者)能够定义包含一个或多个句子的结构,并将其附加到相应的智能合约代码。
斯坦福NLP引擎的建立是为了理解复杂的语言。语言复杂程度取决于机器培训的数量。通过适当的培训,引擎将可以建立复杂的智能合约。FAE可以建立此类合约,由于复杂的合约实际上并不复杂。专家能够将请求拆分为多个较小的代码并将其附加到一个句子中。
当有人输入多个句子时,它会寻找相应的结构/句子来创建“复杂”的合约。贡献者将经过新结构的挖掘过程得到iOlite代币奖励。
使用iOlite的好处是智能合约专家能够像生成随机数同样为你解决难题。你能够在iOlite.io上找到更多信息。
如你所见,生成真正的随机输入并不是易事。不要依赖block.timestamp
,如今和block.blockhash
做为随机源。一个好的解决方案包括几个伪随机数据输入的组合以及使用oracles或智能合约来使其更可靠。你须要100%肯定没有人能够篡改输入智能合约的数据。
在实现随机数生成逻辑以前要当心并三思然后行。
======================================================================
分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:
- java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
- python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
- php以太坊,主要是介绍使用php进行智能合约开发交互,进行帐号建立、交易、转帐、代币开发以及过滤器和交易等内容。
- 以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。
- 以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
- C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括帐户管理、状态与交易、智能合约开发与交互、过滤器和交易等。
- EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、帐户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。
- java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如建立地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。
- php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如建立地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。
- tendermint区块链开发详解,本课程适合但愿使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。
汇智网原创翻译,转载请标明出处。这里是原文Solidity陷阱:以太坊的随机数生成