I have this simple set of contracts.

pragma solidity ^0.4.21;

contract FirstContract {

  bool public isTrue = true;

  function sayHello() public pure returns(bool) {
      return true;


contract ServiceContract {

  FirstContract firstContract;

  function ServiceContract (address _firstContract) public {
    firstContract = FirstContract(_firstContract);

  function confirmFirstContract() public view returns(bool) {
      bool x = firstContract.isTrue();
      return x;

  function sayHi() public view returns(bool) {
      bool y = firstContract.sayHello();
      return y;


When this is compiled and deployed in the correct sequence using 0.4.21, confirmFirstContract() and sayHi() return true as expected.

When the compiler is changed to 0.4.22 the same function returns an "invalid opcode".

Why would that be?

I found this blog that suggests some hints. https://medium.com/@chris_77367/explaining-unexpected-reverts-starting-with-solidity-0-4-22-3ada6e82308c


  • This code works fine for me on Remix with 0.4.22+commit.4cb486ee.Emscripten.clang. The hint in the article you link to would suggest that perhaps firstContract doesn't hold the right address. If you could provide more details about how to reproduce the error, I'd be happy to try further.
    – user19510
    Commented Jun 23, 2018 at 6:51
  • 1
    Are you testing against ganache, geth or some other client? Does it have byzantinum fork enabled?
    – Ismael
    Commented Jun 23, 2018 at 7:23
  • function ServiceContract is a "regular" function, not a constructor. Either change it to constructor, or call it explicitly from your off-chain code before you call function confirmFirstContract. This function returns "invalid opcode" because the firstContract variable has not been initialized to point to a deployed FirstContract instance (i.e., it still points to address 0). Commented Jun 23, 2018 at 8:13
  • If I'm not mistaken, solc 0.4.21 warns about deprecated constructor syntax but still treats it as a constructor function, whereas newer versions of solc treat it is a normal function. This should explain the problem that you're experiencing. Commented Jun 23, 2018 at 8:23
  • 1
    The cause might be that the new version of solidity compiler uses returndatasize opcode and you are running against an implementation that doesn't have byzantinum fork enabled. github.com/ethereum/solidity/issues/4116.
    – Ismael
    Commented Jun 23, 2018 at 13:58


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.