1

The following solidity code works as expected

pragma solidity 0.4.25;

contract Another {
    uint public balance;
    function sendToAnother() public {
        balance += 10;
    }
}

contract Test {
    function send(address another) public {
        Another(another).sendToAnother();
    }
}

I want to move the Another contract to a separate file. So now I have the following two files:

//Test.sol
pragma solidity 0.4.25;

contract Another {
    function sendToAnother() public pure returns (uint);
}

contract Test {
    function send(address another) public pure {
        Another(another).sendToAnother();
    }
}

And

//Another.sol
pragma solidity 0.4.25;

contract Another {
    uint public balance;
    function sendToAnother() public {
        balance += 10;
    }
}

In remix, I am then doing the following:

  1. Deploying Another Contract from Another.sol, and copying its address.
  2. Deploying Test Contract from Test.sol
  3. Invoking send() from Test Contract with the address of the Another contract deployed in step 1

At this stage, I am getting the following error. What am I doing wrong here?

call to Test.send errored: VM error: revert.
revert  The transaction has been reverted to the initial state.
Note: The constructor should be payable if you send value.  Debug the transaction to get more information.
0

For this to work, you need to add an import for the contract you are accessing.

//Test.sol
pragma solidity ^0.4.25;

import "./Another.sol";

contract Test {
    function send(address another) public  {
        Another(another).sendToAnother();
    }
}

and

//Another.sol
pragma solidity 0.4.25;

contract Another {
    uint public balance;
    function sendToAnother() public {
        balance += 10;
    }
}
0

This is because your ABIs don't match. You can do what Felix suggested in another answer, or you can fix the ABI. The actual function in Another.sol doesn't define a return value, but version defined in Test.sol says it returns a uint256, when it doesn't. Newer versions of Solidity validate the return data size, so remove the return value from the Another in Test.sol and it should work.

0

The first issue is that the function signatures diverge, as mentioned by user flygoing. There is no pure keyword in the first code snippet (the one mentioned as working) either, even though it is apparently acceptable when declaring in Test.sol. In Test.sol, sendToAnother signature is: function sendToAnother() public pure returns (uint), while in Another.sol it is defined as function sendToAnother() public.

The main issue, however, is that sendToAnother function, and consequently the send function, cannot be declared as pure as they modify state [1].

The equivalent working code would then be:

//Test.sol
pragma solidity 0.4.25;

contract Another {
    function sendToAnother() public;
}

contract Test {
    function send(address another) public {
        Another(another).sendToAnother();
    }
}

and the other contract, unchanged:

//Another.sol
pragma solidity 0.4.25;

contract Another {
    uint public balance;
    function sendToAnother() public {
        balance += 10;
    }
}

Using the import statement, as mentioned by user Felix Dolderer, instead of declaring contract Another in Test.sol file, also works, but it is not a requirement.

[1] Pure Functions. https://solidity.readthedocs.io/en/v0.4.25/contracts.html#pure-functions

Stay super!

/Javi

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.