可靠性 - 使用程序集获取delegatecall的返回值

时间:2017-08-29 04:07:19

标签: ethereum solidity

我有合同A和合同B.

合同A声明此功能:

function getIntValue() constant returns (uint);

来自B的delegatecall合同A getIntValue功能的适当汇编代码是什么?我还没有很好的装配经验所以我到目前为止只有这个没有工作:

function getContractAIntValue() constant returns (uint c) {
    address addr = address(contractA); // contract A is stored in B.
    bytes4 sig = bytes4(sha3("getIntValue()")); // function signature

    assembly {
        let x := mload(0x40) // find empty storage location using "free memory pointer"
        mstore(x,sig) // attach function signature
        let status := delegatecall(sub(gas, 10000), addr, add(x, 0x04), 0, x, 0x20)
        jumpi(invalidJumpLabel, iszero(status)) // error out if unsuccessful delegatecall
        c := mload(x)
    }
}

1 个答案:

答案 0 :(得分:1)

也许您已经解决了这个问题,原因是一年多以前有人提出来,但是如果有人仍在寻找它...

address addr = address(contractA); // contract A is stored in B.
bytes memory sig = abi.encodeWithSignature("getIntValue()"); // function signature

// solium-disable-next-line security/no-inline-assembly
assembly {
  let result := delegatecall(sub(gas, 10000), addr, add(sig, 0x20), mload(sig), 0, 0)

  let size := returndatasize

  let ptr := mload(0x40)
  returndatacopy(ptr, 0, size)

  // revert instead of invalid() bc if the underlying call failed with invalid() it already wasted gas.
  // if the call returned error data, forward it
  switch result case 0 { revert(ptr, size) }
  default { return(ptr, size) }
}