1.1 create
keccak256(rlp.encode(address, nonce))[12:]
// Create creates a new contract using code as deployment code.
func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address()))
return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr, CREATE)
}
// CreateAddress creates an ethereum address given the bytes and the nonce
func CreateAddress(b common.Address, nonce uint64) common.Address {
data, _ := rlp.EncodeToBytes([]interface{}{b, nonce})
return common.BytesToAddress(Keccak256(data)[12:])
}
1.2 create2
keccak256(0xff ++ address ++ salt ++ keccak256(init_code))[12:]
// Create2 creates a new contract using code as deployment code.
//
// The different between Create2 with Create is Create2 uses keccak256(0xff ++ msg.sender ++ salt ++ keccak256(init_code))[12:]
// instead of the usual sender-and-nonce-hash as the address where the contract is initialized at.
func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *big.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
codeAndHash := &codeAndHash{code: code}
contractAddr = crypto.CreateAddress2(caller.Address(), salt.Bytes32(), codeAndHash.Hash().Bytes())
return evm.create(caller, codeAndHash, gas, endowment, contractAddr, CREATE2)
}
// CreateAddress2 creates an ethereum address given the address bytes, initial
// contract code hash and a salt.
func CreateAddress2(b common.Address, salt [32]byte, inithash []byte) common.Address {
return common.BytesToAddress(Keccak256([]byte{0xff}, b.Bytes(), salt[:], inithash)[12:])
}
bytecodes = type(Test).creationCode;
contractAddr = crypto.CreateAddress2(caller.Address(), salt.Bytes32(), codeAndHash.Hash().Bytes())
func CreateAddress2(b common.Address, salt [32]byte, inithash []byte) common.Address {
return common.BytesToAddress(Keccak256([]byte{0xff}, b.Bytes(), salt[:], inithash)[12:])
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Deployer {
bytes public initCode;
function getInitCode() public {
initCode = type(Test).creationCode;
}
function deploy(uint _salt) public returns(address){
address addr;
bytes memory bytecode = type(Test).creationCode;
assembly {
addr := create2(0, add(bytecode, 0x20), mload(bytecode), _salt)
}
return addr;
}
}
devContractAddress
:= common.BytesToAddress(common.FromHex("0x26b989b9525Bb775C8DEDf70FeE40C36B397CE67"))
initByteCode := common.FromHex("0x33ff")
initCodeHash := crypto.Keccak256(initByteCode)
i := rand.Uint64()
salt := uint256.NewInt(i).Bytes32()
address := crypto.CreateAddress2(devContractAddress, salt, initCodeHash).String()
fmt.Println(address)
func getAddress(devContractAddress common.Address, initCodeHash []byte, p string, s string) {
for {
i := rand.Uint64()
salt := uint256.NewInt(i).Bytes32()
address := crypto.CreateAddress2(devContractAddress, salt, initCodeHash).String()
if strings.HasPrefix(address, p) && strings.HasSuffix(address, s) {
fmt.Println(i)
fmt.Println(address)
fmt.Println()
}
}
}
contract Test {
address public owner;
event Ev();
function met() public {
owner = msg.sender;
}
function get() public {
require(owner == msg.sender);
emit Ev();
}
}
原文始发于微信公众号(山石网科安全技术研究院):如何使用create2来进行合约钓鱼