Gas

硬編碼值的最便宜方法

  • May 2, 2022

我有一個智能合約來檢查 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 的部署成本略高。

那是因為aconstant和硬編碼的值差不多,兩者都不佔用儲存空間。但是您需要關鍵字constant才能將其視為這樣(選項 3 中缺少)。

所以總是constant在可能的情況下使用,比 s 更好

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