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
  • Were you able to resolve this? Is there a finalized solution posted somewhere? – LampShade Jun 16 at 3:15
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);
}
| improve this answer | |
  • Can you clarify what the copy(_addr, btsptr, _len); line does? copy isn't a real command in solidity. What does that function do exactly? – LampShade Jun 16 at 3:15
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; } }

| improve this answer | |

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.