Eip1014 1、create 通过CREATE关键字创建合约 // 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)
}
合约的地址被定义为Keccak256(call.address,nonce)
// 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:])
}
2、create2 通过CREATE2关键字创建合约
// 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)
}
根据call.address,32字节256位的salt:μs[3] denotes the third item on the machine’s stack,inithash :the runtime bytecode(合约的运行时代码) keccak256( 0xff ++ address ++ salt ++ keccak256(init_code))[12:]
// 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:])
}
3、EIP-1014提出新的合约地址创建公式
以太坊CREATE通过Address和递增的Nonce值(避免双花)创建合约地址,一个地址无法在不同的时间得到相同的合约地址。
在EIP-1014中,提出了另外一个指令create2,接受的参数是一个salt和initcode(建立合约的运行时 ByteCodes)。这个指令会透过keccak256哈希,混和参数和主合约的地址来算出子合约地址。
EIP-1014在起初是基于State Channel的需求,主要是因为某些状况下可能还没有要和合约做互动,但需要先知道合约地址。因此只要是需要先知道地址,但没有要立即使用的合约就十分适合通过这个指令来建立。
例如对于交易所来说,替所有要入金的人建立私钥有管理上的问题,若透过智能合约则相对有弹性,但却不是所有申请地址的人都真的会入金,此时就适合利用这个指令先行取得地址,当真的有入金时再布署合约。
|