Solidity陷阱:以太坊的随机数⽣成
title: Solidity陷阱:以太坊的随机数⽣成
Solidity是⼀种相当新的语⾔,因为没有代码是完美的,它包含与代码相关的问题以及你希望⽤它完成的任务。本⽂将指导你使⽤随机数作为以太坊智能合约的输⼊时的最佳实践和陷阱。
python生成1到100之间随机数 Solidity随机数⽣成
Solidity⽆法创建随机数。实际上,每个创建随机数的算法都是伪随机的——没有语⾔能够创建完全随机的数字。Solidity的问题在于复杂的算法成本太⾼,因此使⽤了更基本的解决⽅案。除此之外,Solidity代码应该是确定性的,因为它将在多个节点上运⾏。我们需要⼀种能够⽣成⼀次随机数的算法,并在多个节点上使⽤它。像时钟时间这样的东西不能⽤于⽣成随机数,因此我们必须查看其他选项。作为开发⼈员,你应该了解此问题,因为攻击者能够在某些特定情况下预测结果。
最常⽤的算法之⼀是“线性同余发⽣器”(LCG)。它是最古⽼的算法之⼀,快速且易于理解。LCG是嵌⼊式系统的⼀个很好的选择,因为它们的内存有限。但是,它不适合加密安全应⽤程序。虽然,这仍然在智能合约中使⽤,因为快速算法在⽓体成本⽅⾯实施起来便宜得多。
算法本⾝执⾏以下步骤:
接受输⼊。
在输⼊上执⾏算法。
取输出模数(除以你需要的范围内的最⼤数量)。
在你需要的范围内输出0到最⼤数字。
让我们探讨使⽤智能合约⽰例创建随机数的不同⽅法。⽤户可以通过向合约发送0.1以太以及0到250之间的整数来加⼊。
1.Block.timestamp&Block.difficulty
每当他确认交易时,矿⼯就会分配⼀个block.timestamp。我们的合约的任何玩家都⽆法控制它。让我们看看这段代码来创建⼀个随机数。
function random() private view returns (uint8) {
return uint8(uint256(keccak256(block.timestamp, block.difficulty))%251);
}
这段代码⾸先hash了⼀个块时间戳和难度。接下来,我们将hash转换为整数并将其除以251以获得0到250之间的整数。但是,这段代码的问题在于我们不应该信任矿⼯来挑选胜利者。
2.输⼊任意数据
我们需要更多任意数据来挑选我们的赢家。我们可以使⽤已经进⼊我们的智能合约的玩家的地址,但是我们必须将其隐藏在其他玩家之外,因为他们可以滥⽤它。隐藏此信息是不可能的,因为它全部记录在区块链上。
提交给我们的智能合约的号码可以使⽤。⽤户必须将他们选择的号码与他们的以太坊地址⼀起hash。这给了我们⼀个相当随机的数字。
3.其他机制
3.1以太坊闹钟
开发⼈员需要考虑何时选择胜利者。时间之类的东西在以太坊虚拟机中不可⽤,因为代码将在不同的时间在多个节点上运⾏。这使得挑选胜利者变得更加困难。实现这⼀⽬标的⼀种⽅法是在智能合约中实施⼀项功能,该功能将关闭并选择获胜者。这不像我们希望的那样去中⼼化。合约的所有者在确定他们的朋友将获胜时可以关闭。我们想避免这种作弊⾏为。
更好的选择是使⽤以太坊闹钟。它是⼀种允许稍后在以太坊区块链上执⾏调度事务的服务。这项服务完全没有信任,这意味着整个服务作为智能合约运作。基本上,以太坊闹钟使⽤块号来安排交易。注意,这并不意味着合约本⾝就会被唤醒。它依赖于有兴趣的⽤户(以太奖励)来调⽤“挑选获胜者”功能。当然,如果没有⼈打电话给你的功能,你的就会失败。
3.2随机数据输⼊
提供了⼀个API,通过JSON为你提供随机数据源。以太坊智能合约可以使⽤此数据源来提供选择随机数的算法。由于安全性很重要,因此可以使⽤数字签名。随机数据将由签署。你可以验证数据的完整性,以便证明它确实来⾃并且数据未被篡改。
RANDAO是区块链领域的⼀个新项⽬,专注于提供随机数。他们使⽤oracles和智能合约的组合为你提供随机数字。但是,RANDAO 服务⽬前相当缓慢。如果你拥有经常使⽤的应⽤程序,这并不理想。
3.3 Blocknumber Watcher
你还可以在代码中使⽤观察程序,它会检查程序段编号,直到它与你设置的⽬标编号相匹配。
function f( blocknumber, to_address, value_) {
var filter =www.h.filter(www.haom178'latest').watch(
function(err, blockHash) {
var target=www.mingcheng178/ blocknumber;
h.blockNumber==target) {
filter.stopWatching(www.mhylpt); // your function here
h.sendTransaction({to:to_address, h.coinbase, value: Wei(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智能合约创建
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语⾔⼯程师快速⼊门区块链开发的最佳选择。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论