Gas

生成隨機數

  • December 11, 2019
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基於先前生成的隨機數的數據,這將使其幾乎無法跟踪。

就天然氣使用而言,這會很昂貴嗎?

用於生成隨機數的安全性如何?

接近於零。

  • 正如米哈伊爾回答的那樣:礦工可以操縱它

  • 如果不考慮礦工,它仍然是低安全性的。實現中沒有太多隨機性。

    1. 給定一個塊和一個長度,結果是確定的。
    2. 因此,如果返回結果用於抽獎等活動,並假設用途類似於
function try_my_luck() {
   r=random(some_len)
   if r < 0.01 {
      award(100Eth)
   }
}
  1. 然後因為呼叫你的隨機函式不會花費太多的氣體,一個直接的攻擊是
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()
   }
}
  1. 一個真實的例子是here

$$ Edit $$有人可能會爭辯說,很難列舉

  • 長度
  • 發件人地址
  • 阻塞時間
  • 塊號

然而,

  • 長度 - 它可能是契約中某個數組的長度
  • 發件人地址 - 易於生成和重試
  • 出塊時間——只有幾秒鐘的精度,很容易猜到
  • 塊號 - 幾乎是確定性的

當激勵足夠大時,進行離線計算以生成這些值的最佳組合併不難。

引用自:https://ethereum.stackexchange.com/questions/77380