Gas
硬編碼值的最便宜方法
我有一個智能合約來檢查 msg.sender 是否是所有者。例如,如果我知道所有者地址是 0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8,那麼硬編碼我用於檢查 msg.sender 的這個值的最便宜的方法是這個地址
選項1
function foo() { require(msg.sender == 0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8) }
選項 2
function call() { return 0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8 } function foo() { require(msg.sender == call()) }
選項 3
address owner = 0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8 function foo() { require(msg.sender == owner) }
哪種方式更便宜,為什麼?
我們來做一個具體的實驗——
選項1
contract Greeter { uint public x = 0; constructor() { } function foo() public { require(msg.sender == address(0x7D70653a55BcAc5B96c02FADcaC7f4272C1642B9)); x = 1; } }
部署:115,183 gas
呼叫 foo(): 41,256 gas
選項 2
contract Greeter { uint public x = 0; constructor() { } function call() internal pure returns (address) { return address(0x7D70653a55BcAc5B96c02FADcaC7f4272C1642B9); } function foo() public { require(msg.sender == call()); x = 1; } }
部署:117,973 gas
呼叫 foo():41,291 gas
選項 3
contract Greeter { uint public x = 0; address owner = address(0x7D70653a55BcAc5B96c02FADcaC7f4272C1642B9); function foo() public { require(msg.sender == owner); x = 1; } }
部署:140,392 gas
呼叫 foo():42,092 gas
選項 4
contract Greeter { uint public x = 0; address constant owner = address(0x7D70653a55BcAc5B96c02FADcaC7f4272C1642B9); function foo() public { require(msg.sender == owner); x = 1; } }
部署:115,171 gas
呼叫 foo(): 41,256 gas
概括
選項 4 和選項 1 大致相同,並且部署和呼叫都最便宜。選項 1 的部署成本略高。
那是因為a
constant
和硬編碼的值差不多,兩者都不佔用儲存空間。但是您需要關鍵字constant
才能將其視為這樣(選項 3 中缺少)。所以總是
constant
在可能的情況下使用,比 s 更好