我通过程序集遇到了不同版本的delegatecall,并尝试了所有这些版本--到目前为止没有不同的结果。它们有何不同,哪一种是最好的版本?
OpenZeppelin版本:
assembly {
let ptr := mload(0x40)
calldatacopy(ptr, 0, calldatasize)
let result := delegatecall(gas, _impl, ptr, calldatasize, 0, 0)
let size := returndatasize
returndatacopy(ptr, 0, size)
switch result
case 0 { revert(ptr, size) }
default { return(ptr, size) }
}MakerDAO版本:
assembly {
let succeeded := delegatecall(sub(gas, 5000), _target, add(_calldata, 0x20), mload(_calldata), 0, 0)
let size := returndatasize
response := mload(0x40)
mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f))))
mstore(response, size)
returndatacopy(add(response, 0x20), 0, size)
switch iszero(succeeded)
case 1 {
revert(add(response, 0x20), size)
}
}简单版本:
assembly {
let succeeded := delegatecall(sub(gas, 5000), _target, add(_calldata, 0x20), mload(_calldata), 0, 32)
response := mload(0)
switch iszero(succeeded)
case 1 {
revert(0, 0)
}
}发布于 2019-03-25 14:59:53
OpenZeppelin的一个是最通用的,并且解决了合同升级方案。它将msg.data转发给被调用的契约,并返回所谓的合同返回。
MakerDAO也是通用的,但它允许将任意bytes作为参数传递,并将返回的值打包到bytes中。
简单版本允许任意bytes作为参数,但只返回返回值的前32字节。它还忽略由失败的委托调用返回的任何数据。
https://ethereum.stackexchange.com/questions/68810
复制相似问题