Evm

為什麼要使用專用的 ADDMOD 操作碼?

  • May 7, 2022

常用的 ADDMOD 是不是我們需要為其創建特定的操作碼?為什麼我們不能簡單地同時使用 ADD 操作碼 + MOD 操作碼?

同樣的問題也適用於 MULMOD 操作碼。

ADDMOD 和 MULMOD 操作碼在黃皮書中有一個特殊性

此操作的所有中間計算都不受 2^256 模數的限制。

這意味著您可以在 2^256 位限制之上進行算術運算,因為它們的實現(opAddmodopMulmod)實際上在內部對 Big Integers 進行操作,並且只返回結果。由於模值不能高於 2^256,因此結果不會溢出。

舉個例子:

function classicAddMod() public view returns (uint256 rvalue) {

   uint256 MAX_INT = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;

   assembly {
       rvalue := mod(add(MAX_INT, 1), 10)
   }
}

Whereadd(MAX_INT, 1)導致溢出,將值包裝回 0。模 10 仍為 0。現在,MAX_INT 實際上是 11579208923731619542357098500868790785326998466564056403945758400791312963993 5,該值 + 1 模 1 的結果應該是 1

以下帶有 ADDMOD 的版本實際上計算正確,因為它通過從不將加法的中間結果放入 256 位變數(2^256 模)來避免溢出:

function opAddMod() public view returns (uint256 rvalue) {

   uint256 MAX_INT = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;

   assembly {
       rvalue := addmod(MAX_INT, 1, 10)
   }
}

6由於上述原因,這確實返回了正確的結果。Mulmod 也有類似的行為。

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