以太坊合约地址是怎么计算出来的?

以太坊合同的地址是根据创建者(sender)的地址以及创建者发送过的交易数量(nonce)来计算确定的。 sender
nonce
进行RLP编码,然后用 Keccak-256
进行hash计算。

参考 pyethereum
代码(Python):

def mk_contract_address(sender, nonce):
    return sha3(rlp.encode([normalize_address(sender), nonce]))[12:]

使用 Solidity 代码:

//  nonce 为 零时生成的地址
nonce0 = address(keccak256(0xd6, 0x94, address, 0x80))
nonce1 = address(keccak256(0xd6, 0x94, address, 0x01))

这里有一些 讨论

如果 sender 为 0x6ac7ea33f8831ea9dcc53393aaa88b25a785dbf0 , 创造的合约地址如下,这个过程完全是确定的:

nonce0= "0xcd234a471b72ba2f1ccf0a70fcaba648a5eecd8d"  
nonce1= "0x343c43a37d37dff08ae8c4a11544c718abb4fcf8"
nonce2= "0xf778b86fa74e846c4f0a1fbd1335fe81c00a0c91"
nonce3= "0xfffd933a0bc612844eaf0c6fe3e5b8e9b6c1d19c"

使用 Web3j 的 Java 代码:

private String calculateContractAddress(String address, long nonce){
    byte[] addressAsBytes = Numeric.hexStringToByteArray(address);

    byte[] calculatedAddressAsBytes =
            Hash.sha3(RlpEncoder.encode(
                    new RlpList(
                            RlpString.create(addressAsBytes),
                            RlpString.create((nonce)))));

    calculatedAddressAsBytes = Arrays.copyOfRange(calculatedAddressAsBytes,
            12, calculatedAddressAsBytes.length);
    String calculatedAddressAsHex = Numeric.toHexString(calculatedAddressAsBytes);
    return calculatedAddressAsHex;
}

注:根据 EIP 161 规范
合约帐户使用 nonce=1
初始(在主网络上)。 因此,由一个合同创建的第一个合同地址将使用非零nonce进行计算。

CREATE2

EIP-1014
中添加了一个新的操作码 CREATE2
(在19年1月的君士坦丁堡硬分叉中引入的操作码),它是可以创建合约的另一种方式。

对于由 CREATE2
创建的合约,其地址将是:

keccak256(0xff ++ senderAddress ++ salt ++ keccak256(init_code))[12:]

更多信息请参阅 EIP-1014

原问答 链接

深入浅出区块链知识星球提供专业的区块链问答服务,如果你需要问题一直没有思路,也许可以考虑咨询下老师。

深入浅出区块链 – 打造高质量区块链技术博客,学区块链都来这里,关注 知乎
、微博。