CREATE2(v, n, p, s) 1.CREATE2方法的第一个参数是在创建合约后向合约传输v wei以太币,最后一个参数是salt,那n,p这两个参数有什么用呢?
2.在uniswap v2版本呢中是这样使用的:
pair := create2(0, add(bytecode, 32), mload(bytecode), salt)
为什么第二个和第三个参数要用 opcode “add”和“mload”?
3.如何查看或者在哪里查看CREATE2 opcode的实现逻辑?
这里有一个使用 create2 示例, 里面有注释帮助理解, 我摘录了一下代码:
function deploy(bytes memory bytecode, uint _salt) public payable {
address addr;
/*
NOTE: How to call create2
create2(v, p, n, s)
create new contract with code at memory p to p + n
and send v wei
and return the new address
where new address = first 20 bytes of keccak256(0xff + address(this) + s + keccak256(mem[p…(p+n)))
s = big-endian 256-bit value
*/
assembly {
addr := create2(
callvalue(), // wei sent with current call
// Actual code starts after skipping the first 32 bytes
add(bytecode, 0x20),
mload(bytecode), // Load the size of code contained in the first 32 bytes
_salt // Salt from function arguments
)
if iszero(extcodesize(addr)) {
revert(0, 0)
}
}
emit Deployed(addr, _salt);
}
可以看出来分别表示代码起始位置和长度。
至于为什么加 0x20(32个字节),这个是跟 evm 内存布局 有关系, 变长数组的前面第一个槽位(32个字节)是用来存放长度的,接下来才是内容。
查看 create2 的实现, 在 geth 的源码里肯定是有, 不过,其实看 EIP 说明: EIP-1014: Skinny CREATE2 就足够了。 例如第一句就说明了 参数的含义: Adds a new opcode (
CREATE2) at
0xf5, which takes 4 stack arguments: endowment, memory_start, memory_length, salt.