Solidity

工廠契約的高gas成本!

  • August 13, 2020

我注意到,當合約工廠使用“new”關鍵字創建新合約時,交易會花費大量的 gas,就好像它是第一次部署合約一樣。我不明白為什麼這麼高的 gas 成本,如果之前已經部署了合約並且程式碼已經在“區塊鏈中”,那麼為什麼需要再次部署整個程式碼。

這是一個例子:

   pragma solidity >=0.4.22 <0.6.0;
   
   contract OwnedToken {
       // `TokenCreator` is a contract type that is defined below.
       // It is fine to reference it as long as it is not used
       // to create a new contract.
       TokenCreator creator;
       address owner;
       bytes32 name;
   
       // This is the constructor which registers the
       // creator and the assigned name.
       constructor(bytes32 _name) public {
           // State variables are accessed via their name
           // and not via e.g. `this.owner`. Functions can
           // be accessed directly or through `this.f`,
           // but the latter provides an external view
           // to the function. Especially in the constructor,
           // you should not access functions externally,
           // because the function does not exist yet.
           // See the next section for details.
           owner = msg.sender;
   
           // We do an explicit type conversion from `address`
           // to `TokenCreator` and assume that the type of
           // the calling contract is `TokenCreator`, there is
           // no real way to check that.
           creator = TokenCreator(msg.sender);
           name = _name;
       }
   
       function changeName(bytes32 newName) public {
           // Only the creator can alter the name --
           // the comparison is possible since contracts
           // are explicitly convertible to addresses.
           if (msg.sender == address(creator))
               name = newName;
       }
   
       function transfer(address newOwner) public {
           // Only the current owner can transfer the token.
           if (msg.sender != owner) return;
   
           // We ask the creator contract if the transfer
           // should proceed by using a function of the
           // `TokenCreator` contract defined below. If
           // the call fails (e.g. due to out-of-gas),
           // the execution also fails here.
           if (creator.isTokenTransferOK(owner, newOwner))
               owner = newOwner;
       }
   }
   
   contract TokenCreator {
       function createToken(bytes32 name)
          public
          returns (OwnedToken tokenAddress)
       {
           // Create a new `Token` contract and return its address.
           // From the JavaScript side, the return type is
           // `address`, as this is the closest type available in
           // the ABI.
           return new OwnedToken(name);
       }
   
       function changeName(OwnedToken tokenAddress, bytes32 name) public {
           // Again, the external type of `tokenAddress` is
           // simply `address`.
           tokenAddress.changeName(name);
       }
   
       // Perform checks to determine if transferring a token to the
       // `OwnedToken` contract should proceed
       function isTokenTransferOK(address currentOwner, address newOwner)
           public
           pure
           returns (bool ok)
       {
           // Check an arbitrary condition to see if transfer should proceed
           return keccak256(abi.encodePacked(currentOwner, newOwner))[0] == 0x7f;
       }
   }

TokenCreator 合約的’createToken’ 函式創建一個 OwnedToken 合約的對象。但是,如果程式碼始終相同,為什麼呼叫該函式的成本與部署 OwnedToken 合約的成本一樣高呢?

謝謝你。

正如@goodvibration 所說,您總是創建不同的實例。因此 byteCode 是重複的,因此總是消耗相同數量的 gas。

為避免這種情況,您可以使用複製工廠:https ://github.com/optionality/clone-factory 。它創建了一個新合約,將所有呼叫委託給給定的庫合約。該庫僅部署一次,因此複製工廠部署要便宜得多。

更新:如果有人感興趣,寫一篇關於複製工廠的部落格文章:https ://soliditydeveloper.com/clonefactory 。

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