以太坊合约的地址是根据创建者(sender)的地址以及创建者发送过的交易数量(nonce)来计算确定的。sender和nonce进行RLP编码,然后用keccak-256进行hash计算。
【1】使用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;
}
【2】使用go-ethereum的Golang代码(方式一)
// calculateAddress creates an ethereum address given the bytes and the nonce
func calculateAddress(b common.Address, nonce uint64) (address common.Address, err error) {
// RLP encoding of val
data, err := rlp.EncodeToBytes([]interface{}{b, nonce})
if err != nil {
return common.Address{}, fmt.Errorf("RLP encoding error:%s", err)
}
return common.BytesToAddress(crypto.Keccak256(data)[12:]), nil
}
【3】使用go-ethereum的Golang代码(方式二)
// CreateAddress2 creates an ethereum address given the address bytes, initial
// contract code and a salt.
func CreateAddress2(b common.Address, salt [32]byte, code []byte) common.Address {
return common.BytesToAddress(Keccak256([]byte{0xff}, b.Bytes(), salt[:], Keccak256(code))[12:])
}
【4】测试用例(一)
如果sender为0x6ac7ea33f8831ea9dcc53393aaa88b25a785dbf0,创造的合约地址如下:
nonce0= "0xcd234a471b72ba2f1ccf0a70fcaba648a5eecd8d"
nonce1= "0x343c43a37d37dff08ae8c4a11544c718abb4fcf8"
nonce2= "0xf778b86fa74e846c4f0a1fbd1335fe81c00a0c91"
nonce3= "0xfffd933a0bc612844eaf0c6fe3e5b8e9b6c1d19c"
【5】测试用例(二)
如果sender为0xa990077c3205cbDf861e17Fa532eeB069cE9fF96,创造的合约地址如下:
nonce0= "0x1820a4b7618bde71dce8cdc73aab6c95905fad24"
nonce1= "0x7faad426db1e8a79173400c5e0914b28f9ff4412"
nonce2= "0x74e474ba81c7d71f23ca9165113b84ed25b82bb0"
以太坊的合约地址创造过程完全是确定的,也就是说合约的地址是可以预先获知的。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)