[Ethereum] way to return data from a fallback function

contract-developmentdesign-patternssolidity

I'm trying to write a contract that contains a fallback function which would pass-through the call to another destination contract. This would allow for future upgrades/bug-fixes to the destination contract by updating the destination contract address in the contract which contains the pass-through fallback function.

Caller calling Do() -> Pass-Through function () -> Destination implements Do()

The problem is the fallback function can't return anything. Worse, if the caller to a contract with a fallback function is expecting a return value, they will receive what I believe is msg.data instead of the expected value.

  1. Is there a way to return data from a fallback function (assembly okay) ?
  2. Is the current behavior dangerous (e.g. corrupting the caller's stack)?

Here's the example code:

pragma solidity ^0.4.10;

contract Real
{
    function Do() public constant returns (uint256) { return 12345; }
}

contract Blank
{
    function () public { }
}

// Client contract address: 0x7C2F875a9D5Ba712A6cdF35E537651ea89779802
contract Client
{
    function Run() public constant returns (uint256 result1, uint256 result2)
    {
        Real real = Real(0xd64dE830995C7407b09CF96EC59f76701D4DBcF9); // This is the address of Real
        result1 = real.Do();

        Real blank = Real(0x068c8D804Fab87B3d2cF3f02914eF2bE6b199436); // This is the address of Blank
        result2 = blank.Do();
    }
}

// result1 = 12345
// result2 = 0xDDFAE52900000000000000000000000000000000000000000000000000000000
// bytes4(sha3("Do()")) = 0xDDFAE529. This is why I think result2 is msg.data

Best Answer

As outlined here by chriseth (who created Solidity):

Fallback functions cannot have return values.

It does look like your result2 value is the msg.data value. That said, you have not outlined how you are calling the client function - it is possible that returning msg.data is a fallback of the library/tooling that you are using.