合约内的合约创建

  • nilliol
  • 更新于 2024-05-26 10:16
  • 阅读 912

以太坊中外部账户EOA可以创建账户,同样智能合约也可以创建账户。只能合约创建账户的方法有两种:creatcreat21creat使用creat就是直接new一个合约即可,使用create创建的地址的计算方法是对:部署者地址和nonce(部署者发送交易的总数)进行哈希计算。使用方法如下:

以太坊中外部账户EOA可以创建账户,同样智能合约也可以创建账户。智能合约创建账户的方法有两种:

  • creat
  • creat2

1 creat

使用creat就是直接new一个合约即可,使用create创建的地址的计算方法是对:部署者地址和nonce(部署者发送交易的总数)进行哈希计算。使用方法如下:

Contract x = new Contract{value: _value}(params)
// Contract 是要创建的合约名(两个 Contract 都是)
// x 是返回的合约对象(地址)
// 如果构造函数是 payable,可以创建时转入 _value 数量的 ETH
// params 是新合约构造函数的参数

新地址 = hash(创建者地址, nonce)

使用creat同样也需要知道需要创建合约的代码

2 creat2

使用creat2的目的是为了让合约地址独立于未来的事件(不管未来区块链上发生了什么,你都可以把合约部署在事先计算好的地址上)。地址计算方法如下:

新地址 = hash("0xFF",创建者地址, salt, hash(bytecode))
// 0xFF 一个常数,避免和 CREATE 冲突
// 创建者地址
// salt 由创建者提供的数值
// bytecode 待部署合约的字节码

// 计算如下(貌似还是可以直接在合约中使用):
predictedAddress = address(
    uint160(    // 再转为 uint160(address 类型为 uint160 的长度)
        uint(   // 先转为 uint256
            keccak256(  // 对所有输入进行哈希
                abi.encodePacked(   // 进行编码打包
                    bytes1(0xff),   // 固定的字节
                    address(this),  // 部署者的地址
                    salt,   // 由部署者自己决定
                    keccak256(type(Pair).creationCode)  // 访问 Pair 的内存字节数组,creationCode 只能在内联汇编中使用。
                )
            )
        )
    )
);

关于 address 和 uint256 的关系参考:((20240522134445-kp8i23g "地址和 uint256"))

使用creat2的方法如下(只是多添加了一个salt参数):

Contract x = new Contract{salt: _salt, value: _value}(params)

// 在汇编中调用
assembly {
    // 1:0 表示发送的 wei 数
    // 2、3: 表示字节码在内存中的位置
    // 4:表示盐值
    addr := create2(0, add(bytecode, 0x20), mload(bytecode), salt)
}

3 总结

对于creatcreat2来说,两者间除了creat2可以提前计算出将要部署的合约的地址外,没有什么区别。

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
nilliol
nilliol
0xbe3e...29A9
web3 的学习者,寻找实习机会中。 博客地址:https://llwh2333.github.io