以下两种通过智能契约创建智能契约的方法之间有什么区别吗?
function create_v1() external {
Contract c = new Contract();
}function create_v2() external {
bytes memory deploymentBytecode = type(Contract).creationCode;
address contractAddress;
assembly {
contractAddress := create(0, add(deploymentBytecode, 0x20), mload(deploymentBytecode))
}
}发布于 2022-08-17 14:32:39
唯一有意义的区别是,第一个版本检查部署是否成功。从create返回的地址确实可以是address(0),在这种情况下,它意味着部署失败(例如,Contract可能在构造函数期间恢复)。
因此,要使第二个版本等同于第一个版本,我们可以添加一个简单的检查:
function create_v2() external {
bytes memory deploymentBytecode = type(Contract).creationCode;
address contractAddress;
assembly {
contractAddress := create(0, add(deploymentBytecode, 0x20), mload(deploymentBytecode))
if iszero(contractAddress) {
// we can forward the error message
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
}
}提示:一种粗略的方法是使用以下方法编译一份合同,以检查是否可靠。
solc Foo.sol --ir对于create_v1,我们可以看到以下内容(适配的,注释是我的)
function fun_create_v1_16() {
let _1 := allocate_unbounded()
let _2 := add(_1, datasize("Contract_4")) // Contract_4 is the contract we want to deploy
if or(gt(_2, 0xffffffffffffffff), lt(_2, _1)) { panic_error_0x41() } // memory overflow check
datacopy(_1, dataoffset("Contract_4"), datasize("Contract_4"))
_2 := abi_encode_tuple__to__fromStack(_2) // does nothing :|
let expr_13_address := create(0, _1, sub(_2, _1))
if iszero(expr_13_address) { revert_forward_1() } // check create worked - forward returndata in case
let var_c_9_address := expr_13_address
}https://ethereum.stackexchange.com/questions/133782
复制相似问题