1

I know that if I use call from a contract, that I cannot get the return value. I get a true or a false.

Is it possible for me to inspect the blockchain afterwords to get the return value?

For example, if the function that I CALL creates an new contract and returns the address, can I endow the the mined block and find the address of the created contract?

What if it returned a uint?

How would I do this? Web3?

I've created a blog post that shows a bit of what I'm trying to accomplish here: http://catallax.info/news/2017/6/8/calling-future-contracts-from-contracts-in-ethereum-dev-log-6

  • They current way to do this in solidity is to use events, your contract generates an event with the address generated. See ethereum.stackexchange.com/q/12950. Another way is to inspect the execution of your contract with debug_traceTransaction but it is way more involved. – Ismael Jun 7 '17 at 2:18
  • That would require the other contract to have implemented an event. Obviously this would be a best practice, but not a surety. – Austin Fatheree Jun 7 '17 at 11:35
2

Low-level calls are just a tiny bit above inline assembly, so you can use inline assembly to emulate this feature.

Something like this:

function get(address _addr, string _func) public view returns (bytes data) {
    uint len = 32;
    uint ptr;

    bytes4 sig = bytes4(keccak256(_func));
    assembly {
        ptr := mload(0x40)       
        mstore(ptr, sig)

        let result := call(5000, _addr, 0, ptr, 0x4, ptr, add(len, 0x40))

        if eq(result, 0) {
            revert(0, 0)
        }

        ptr := add(ptr, 0x40)
        mstore(0x40, add(ptr, add(len, 0x40)))
    }

    data = toBytes(ptr, len); 
}

function toBytes(uint _addr, uint _len) internal pure returns (bytes memory bts) {
    bts = new bytes(_len);
    uint btsptr;
    assembly {
        btsptr := add(bts, 0x20)
    }
    copy(_addr, btsptr, _len);
}
0

There is an inline assembly function delegatecall(g, a, in, insize, out, outsize) identical to callcode, which output the return value to mem[out..(out+outsize)), For more details , you can see https://solidity.readthedocs.io/en/v0.4.24/assembly.html#

If you just want to call but not the delegatecall, you can define an interface of your target contract and get the result directly. pragma solidity ^0.4.24; contract Remote{ function A() public returns (uint){ return uint(12345); } } /-------------------local-----------------------/ interface remote{ function A() external returns(uint); } contract local{ remote r; uint b; constructor(address _remote) public { r = remote(_remote); } function cal() public view returns(uint){ return r.A()+1; } }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.