Gas
生成隨機數
uint private seed; // starts from 0 (including) to _length number (excluding) function random(uint _length) private returns(uint) { seed = seed.add(block.timestamp.add(uint(msg.sender))); return uint(sha256(toBytes(uint(blockhash(block.number - 1)) + seed))) % _length; } function toBytes(uint256 x) private pure returns(bytes b) { b = new bytes(32); assembly { mstore(add(b, 32), x) } }
用於生成隨機數的安全性如何?
我有一個
seed
基於先前生成的隨機數的數據,這將使其幾乎無法跟踪。就天然氣使用而言,這會很昂貴嗎?
用於生成隨機數的安全性如何?
接近於零。
正如米哈伊爾回答的那樣:礦工可以操縱它
如果不考慮礦工,它仍然是低安全性的。實現中沒有太多隨機性。
- 給定一個塊和一個長度,結果是確定的。
- 因此,如果返回結果用於抽獎等活動,並假設用途類似於
function try_my_luck() { r=random(some_len) if r < 0.01 { award(100Eth) } }
- 然後因為呼叫你的隨機函式不會花費太多的氣體,一個直接的攻擊是
function attack() { r = random(some_len) if r >= 0.01 { revert; // will be back and try another block } for i = 0; i < 100000; i++ { try_my_luck() } }
- 一個真實的例子是here。
$$ Edit $$有人可能會爭辯說,很難列舉
- 長度
- 發件人地址
- 阻塞時間
- 塊號
然而,
- 長度 - 它可能是契約中某個數組的長度
- 發件人地址 - 易於生成和重試
- 出塊時間——只有幾秒鐘的精度,很容易猜到
- 塊號 - 幾乎是確定性的
當激勵足夠大時,進行離線計算以生成這些值的最佳組合併不難。