以太坊中外部账户EOA可以创建账户,同样智能合约也可以创建账户。只能合约创建账户的方法有两种:creatcreat21creat使用creat就是直接new一个合约即可,使用create创建的地址的计算方法是对:部署者地址和nonce(部署者发送交易的总数)进行哈希计算。使用方法如下:
以太坊中外部账户EOA
可以创建账户,同样智能合约也可以创建账户。智能合约创建账户的方法有两种:
creat
creat2
使用creat
就是直接new
一个合约即可,使用create
创建的地址的计算方法是对:部署者地址和nonce
(部署者发送交易的总数)进行哈希计算。使用方法如下:
Contract x = new Contract{value: _value}(params)
// Contract 是要创建的合约名(两个 Contract 都是)
// x 是返回的合约对象(地址)
// 如果构造函数是 payable,可以创建时转入 _value 数量的 ETH
// params 是新合约构造函数的参数
新地址 = hash(创建者地址, nonce)
使用
creat
同样也需要知道需要创建合约的代码
使用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)
}
对于creat
和creat2
来说,两者间除了creat2
可以提前计算出将要部署的合约的地址外,没有什么区别。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!