合约地址碰撞疑问:同一交易创建两合约为何地址不同?
为什么同一交易中创建的两个合约地址不同?
嘿,这个问题戳中了很多人对合约地址生成规则的误解点,我来给你拆解清楚~
首先,先明确合约地址的标准生成规则:
合约地址是通过对创建者地址和创建者的nonce值进行Keccak-256哈希计算,取结果的最后20字节得到的,公式可以简单表示为:
contractAddress = bytes20(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), senderAddress, bytes1(nonce))))
本质上是对[sender, nonce]进行RLP编码后做哈希运算,再截取后20字节,两种表述逻辑一致。
接下来重点来了:你混淆了外部账户(EOA)和合约账户的nonce规则!
- 对于外部账户(EOA):
nonce代表该账户发起的交易次数,每提交一笔交易,nonce就递增1。如果是外部账户直接在同一笔交易里多次创建合约,所有合约的创建者nonce都是该交易对应的EOAnonce,这种情况下才会生成相同地址(后创建的合约会覆盖前一个)。 - 但你的情况是通过合约账户创建新合约(也就是代码是在某个合约的函数里执行了两次创建合约的逻辑):此时创建者是这个合约账户,而合约账户的
nonce规则完全不同——它的nonce是自身创建的合约数量,每成功创建一个合约,合约账户的nonce就会立即递增1,不管这些创建操作是不是在同一笔交易中执行的。
所以在你的交易里,第一个合约创建时,合约账户的nonce是N;第二个合约创建时,nonce已经变成了N+1,两个不同的nonce值代入哈希计算,自然就生成了两个不同的合约地址,不会出现覆盖的情况。
举个直观的例子:假设你的合约账户地址是0xContract,初始nonce为0。第一次调用create操作时,用nonce=0生成地址A;第二次调用create时,nonce已经自动增长到1,生成地址B,两者必然不同。
总结一下:核心区别在于创建者是EOA还是合约账户,它们的nonce递增逻辑不一样——EOA按交易次数递增,合约账户按创建的合约数量递增,同一交易里多次创建合约会让合约账户的nonce连续增长,最终生成不同的合约地址。
内容的提问来源于stack exchange,提问作者user9785654
相关产品推荐
相关产品推荐

