Solidity
使用工廠模式複製合約時使用 Create2 計算確定性地址
另一位作者有一個存在相同問題的未回答問題,我正在創建一個更詳細的問題,希望兩者都可以關閉。
我有一份基於這篇文章的想法的可靠契約。基本上它是允許部署貨運代理契約的工廠契約。為了最大限度地降低 gas 成本,在創建轉發器後,您可以創建它的複製。
我希望計算將使用 create2 生成的地址,該地址適用於該
createForwarder
函式:貨代工廠.sol
function createForwarder(address forwardAddress, uint256 salt) public onlyOwner returns (Forwarder forwarder) { bytes memory bytecode = abi.encodePacked( type(Forwarder).creationCode, uint256(uint160(address(forwardAddress))) ); assembly { forwarder := create2(0, add(bytecode, 0x20), mload(bytecode), salt) } emit Deployed(address(forwarder), salt); }
計算地址.js
let bytecode = `${forwarderBytecode}${encodeParam( "address", forwardAddress ).slice(2)}`; function buildCreate2Address(creatorAddress, saltHex, byteCode) { return `0x${web3.utils .sha3( `0x${["ff", creatorAddress, saltHex, web3.utils.sha3(byteCode)] .map((x) => x.replace(/0x/, "")) .join("")}` ) .slice(-40)}`.toLowerCase(); }
效果很好。但是在生成新的複製地址時,之前的
buildCreate2Address
函式不再起作用,因為 create2 函式中的第二個和第三個參數不同。貨代工廠.sol
function generateCloneAddress(address target, uint256 salt) private returns (address cloneAddress) { bytes20 targetBytes = bytes20(target); assembly { let clone := mload(0x40) mstore( clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000 ) mstore(add(clone, 0x14), targetBytes) mstore( add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000 ) cloneAddress := create2(0, clone, 0x37, salt) } }
我不太確定它的字節碼是否正在改變,或者它是否
buildCreate2Address
需要更新。
事實證明,複製是使用標準EIP 1167創建的,因此它具有與原始轉發器不同的創建字節碼。因此,要計算複製的確定性地址,您可以修改
buildCreate2Address
函式的字節碼參數,也可以在合約中實現以下函式:function predictCloneAddress(address forwarderAddress_, uint256 salt_) public view returns (address) { address predictedAddress = Clones.predictDeterministicAddress( forwarderAddress_, bytes32(salt_) ); return predictedAddress; }