承接上篇,不多做介绍,直接上代码:
func Create2ContractAddr(sendAddr string, salt string, byteCode []byte) (string,error) {
//keccak256( 0xff ++ sendAddr ++ salt ++ keccak256(byteCode))[12:]
var (
data []byte
err error
buf []byte
)
data = append(data, byte(0xff))
if buf, err = hex.DecodeString(sendAddr); err != nil {
return "",err
}
data = append(data, buf...)
if buf, err = hex.DecodeString(salt); err != nil {
return "",err
}
data = append(data, buf...)
buf = Keccak256Hash(byteCode)
data = append(data, buf...)
buf = Keccak256Hash(data)
return hex.EncodeToString(buf[12:]),nil
}
下面是丰富的测试用例:
//测试用例来自https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1014.md
func TestCreate2ContractAddr(t *testing.T) {
var testcases = []struct {
sender string
salt string
byteCode []byte
want string
} {
{
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000000000000000000000000000",
[]byte{0x00},
"4d1a2e2bb4f88f0250f26ffff098b0b30b26bf38",
},
{
"deadbeef00000000000000000000000000000000",
"0000000000000000000000000000000000000000000000000000000000000000",
[]byte{0x00},
"b928f69bb1d91cd65274e3c79d8986362984fda3",
},
{
"deadbeef00000000000000000000000000000000",
"000000000000000000000000feed000000000000000000000000000000000000",
[]byte{0x00},
"d04116cdd17bebe565eb2422f2497e06cc1c9833",
},
{
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000000000000000000000000000",
[]byte{0xde,0xad,0xbe,0xef},//deadbeef
"70f2b2914a2a4b783faefb75f459a580616fcb5e",
},
{
"00000000000000000000000000000000deadbeef",
"00000000000000000000000000000000000000000000000000000000cafebabe",
[]byte{0xde,0xad,0xbe,0xef},//deadbeef
"60f3f640a8508fc6a86d45df051962668e1e8ac7",
},
{
"00000000000000000000000000000000deadbeef",
"00000000000000000000000000000000000000000000000000000000cafebabe",
[]byte{0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef},
"1d8bfdc5d46dc4f61d6b6115972536ebe6a8854c",
},
{
"0000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000000000000000000000000000",
[]byte{},
"e33c0c7f7df4809055c3eba6c09cfe4baf1bd9e0",
},
}
for _, oneCase := range testcases {
var got string
var err error
if got, err = Create2ContractAddr(oneCase.sender, oneCase.salt, oneCase.byteCode); err != nil {
t.Error(err)
return
}
if got != oneCase.want {
t.Error("generate contract address error")
t.Error("want:", oneCase.want)
t.Error("got: ", got)
return
}
}
}
(全文完)
参考资料:
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1014.md