以太坊生成合约地址以及存在的账户碰撞

以太坊生成合约地址以及存在的账户碰撞,第1张

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的需求,主要是因为某些状况下可能还没有要和合约做互动,但需要先知道合约地址。因此只要是需要先知道地址,但没有要立即使用的合约就十分适合通过这个指令来建立。

例如对于交易所来说,替所有要入金的人建立私钥有管理上的问题,若透过智能合约则相对有d性,但却不是所有申请地址的人都真的会入金,此时就适合利用这个指令先行取得地址,当真的有入金时再布署合约。


4 账户碰撞
3607
私钥账户和合约账户之间存在碰撞性
Any transaction where tx.sender has a CODEHASH != EMPTYCODEHASH MUST be rejected as invalid, where EMPTYCODEHASH = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470. The invalid transaction MUST be rejected by the client and not be included in a block. A block containing such a transaction MUST be considered invalid.

1.存在私钥账户和CREATE2合约账户碰撞的背景:不同私钥生成不同的公钥,从而生成不同的私钥账户;通过CREATE2不同salt值下同一个合约代码能够生成不同的合约账户。
假设存在一个160bit的冲突账户,考虑最小计算花销和存储花销,前80bit由遍历不同私钥生成,后80位通过遍历不同salt值生成。一共花费 2 ** 80 + 2 ** 80 =281的哈希值计算时间和存储空间,在当前的硬件条件以及电力下,需花费1年时间以及100亿美元可以计算得出。
2.CREATE合约账户和私钥账户的碰撞花销为2160,计算时间和存储成本都不可接受

计算281的成本为:281=2.4*10**25,在当前的硬件条件以及电力下,需花费1年时间以及100亿美元可以计算得出。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/925652.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存