Go-ethereum: Always fail when the contract call external contract

Created on 8 Jun 2018  路  15Comments  路  Source: ethereum/go-ethereum

System information

Geth version: 1.8.7
OS & Version: Linux

Expected behaviour

Always fail when the contract call external contract

Actual behaviour

image

I don't know why , but it always cost all gas!

it work fine on geth 1.6.x

documentation triage

Most helpful comment

Thanks @chriseth the EVM change solved the problem for me.

@dksuper to get my example up and running, I was able it to do it one of two ways.
1) Specify byzantiumBlock in your genesis.json to enable Byzantium support on your private chain. For my current application, I was able to reinit the entire chain since my private fork is only for testing.

{
    "config": {
        "chainId": 1,
        "homesteadBlock": 0,
        "eip155Block": 0,
        "eip158Block": 0,
        "eip160Block": 0,
        "byzantiumBlock": 0
    },
    "nonce": "0x0000000000000042",
    "timestamp": "0x00",
    "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "extraData": "0x00",
    "gasLimit": "0x8000000",
    "difficulty": "0x100",
    "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "coinbase": "0x3333333333333333333333333333333333333333"
}

I substituted an arbitrary choinbase address and arbitrary chainId above. The key is the addition of byzantiumBlock.

2) If you cannot change the private net and don't want to fork it, you can also use the older compiler version 0.4.21. In my post above, I posted a complete example with the pragma field. I'd recommend solution 1 if you are able. Using older compilers as a workaround may potentially contain undesired bugs, exploits, and missing features that are fixed in newer versions. (That being said newer versions can also contain bugs, exploits, or missing features so when the time comes, test the heck out of your system , lock in the version, and watch forums for exploits and bugs)

All 15 comments

I'm seeing the same thing. I tested the following code on Ropsten and it works as expected.

pragma solidity ^0.4.23;

contract Producer {
  uint8 public SOME_VALUE=12;
}

contract Consumer {
    Producer currentProducer;

    function setProducer(address addr) public { 
        Producer newProducer = Producer(addr);
        require(newProducer.SOME_VALUE() > 0);
        currentProducer = newProducer; 
    }

    function getSome() public view returns (uint8) {
        return currentProducer.SOME_VALUE(); 

    }
}

Code reproduced from https://ethereum.stackexchange.com/questions/48833/calling-external-contract-leads-to-infinite-gas-need

Version: 1.8.10-stable
Git Commit: eae63c511ceafab14b92e274c1b18bf1700e2d3d
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.10
Operating System: linux
GOPATH=
GOROOT=/usr/lib/go-1.10

a bit more follow-up...

looks like the issue might be related to the compiler version as well as go-ehtereum version.

The following code runs for Tester: Tester.create(), Tester.test(), Tester.getCreatorCreator() with remix and solidity 0.4.21

pragma solidity 0.4.21;

contract Creator {
  address creator;

  function Creator() public {
    creator = msg.sender;
  }

  function getCreator() public constant returns(address) {
    return creator;
  }
}

contract Tester {
  Creator creator;
  address creatorCreator;

  function create() public {
    creator = new Creator();
  }

  function test() public {
    creatorCreator = creator.getCreator();
  }

  function getCreatorCreator() public constant returns(address) {
    return creatorCreator;
  }
}

Metadata

{"compiler":{"version":"0.4.21+commit.dfe3193c"},"language":"Solidity","output":{"abi":[{"constant":true,"inputs":[],"name":"getCreator","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}],"devdoc":{"methods":{}},"userdoc":{"methods":{}}},"settings":{"compilationTarget":{"browser/test_a.sol":"Creator"},"evmVersion":"byzantium","libraries":{},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"browser/test_a.sol":{"keccak256":"0x9a4f9f1fc840102efaa24819261ba23d8de8cff9c01377b18d7da47b3d7495aa","urls":["bzzr://4b92b0a80048bc85030318ee5588725839b9e73d83c0cff74392ce358c6b2c59"]}},"version":1}

Geth

Version: 1.8.10-stable
Git Commit: eae63c511ceafab14b92e274c1b18bf1700e2d3d
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.10
Operating System: linux
GOPATH=
GOROOT=/usr/lib/go-1.10

However, it fails with new versions the solidity, ^0.4.22.

That being said, on Robsten, the following contract ran successfully, but failed when running on the same version of Geth above.

pragma solidity 0.4.24;

contract Creator {
  address creator;

  constructor() public {
    creator = msg.sender;
  }

  function getCreator() public constant returns(address) {
    return creator;
  }
}

contract Tester {
  Creator creator;
  address creatorCreator;

  function create() public {
    creator = new Creator();
  }

  function test() public {
    creatorCreator = creator.getCreator();
  }

  function getCreatorCreator() public constant returns(address) {
    return creatorCreator;
  }
}

new Tester(): https://ropsten.etherscan.io/tx/0x731e6abb14cf5fd0d1d5a2f73196d4cab696406b1b1652214aed15a682077fd6
tester.create:
https://ropsten.etherscan.io/tx/0x61b35228b25f69eddc5e5ee1912f616ac066ecf14175126e2a1b021fe0509ce1
tester.test:
https://ropsten.etherscan.io/tx/0x30b21c8bfe94a0e5638033c0e00a7be56a532ba6a6b00b98f2804e422eac7b8c

Metadata

{"compiler":{"version":"0.4.24+commit.e67f0147"},"language":"Solidity","output":{"abi":[{"constant":true,"inputs":[],"name":"getCreator","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}],"devdoc":{"methods":{}},"userdoc":{"methods":{}}},"settings":{"compilationTarget":{"browser/test_a.sol":"Creator"},"evmVersion":"byzantium","libraries":{},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"browser/test_a.sol":{"keccak256":"0x92900de3747c5d0c79824561230c75bac633b60dbd391520a9f11d7ff7306d67","urls":["bzzr://a552e394c562850513398aea3328dcd0b6d209bcbbd922d07a4a40aea0287f56"]}},"version":1}

My guess would be that this is due to the EVM version not being set to Byzantium on the private chain.

@chriseth So, you mean when I change my EVM version , then problem will be solve?
if that is you mean, then how to change it??

@jeichel-miovision So, what can i do to solve this problem , in geth 1.8.7?

How did you initialize your private chain? The genesis file contains a config field in which you can set the block numbers that forks your occur at. You need to have byzantium enabled for the new EVM features to work on it.

@karalabe would it be possible to default more easily to byzantium somehow?

Thanks @chriseth the EVM change solved the problem for me.

@dksuper to get my example up and running, I was able it to do it one of two ways.
1) Specify byzantiumBlock in your genesis.json to enable Byzantium support on your private chain. For my current application, I was able to reinit the entire chain since my private fork is only for testing.

{
    "config": {
        "chainId": 1,
        "homesteadBlock": 0,
        "eip155Block": 0,
        "eip158Block": 0,
        "eip160Block": 0,
        "byzantiumBlock": 0
    },
    "nonce": "0x0000000000000042",
    "timestamp": "0x00",
    "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "extraData": "0x00",
    "gasLimit": "0x8000000",
    "difficulty": "0x100",
    "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "coinbase": "0x3333333333333333333333333333333333333333"
}

I substituted an arbitrary choinbase address and arbitrary chainId above. The key is the addition of byzantiumBlock.

2) If you cannot change the private net and don't want to fork it, you can also use the older compiler version 0.4.21. In my post above, I posted a complete example with the pragma field. I'd recommend solution 1 if you are able. Using older compilers as a workaround may potentially contain undesired bugs, exploits, and missing features that are fixed in newer versions. (That being said newer versions can also contain bugs, exploits, or missing features so when the time comes, test the heck out of your system , lock in the version, and watch forums for exploits and bugs)

@karalabe
Thank you for your reply , i didn't enabled the byzantium in my private chain initialize , because i can't see any information for enabled byzantium , in the go-ethereum README.md , i have two question in follow:

1.If i enabled byzantium in my private chain , then i can use the new versoin compiler to compile my solidity?

2.How to fork in my current private chain? if my current block numbers is 666666 , should i just put 666666 in the byzantiumBlockin field , which is in config field that contains in genesis file, then init it or just run geth?

@jeichel-miovision
Thanks for your reply, do you know how to fork in my current private chain? because i need used old data in current chain

Appreciate if someone could point out link to wiki page which describes forking private network.

I've solve this issue in my own private chain by including eip150Block: <desired block number> in my genesis config. EIP150 being related to the gas cost adjustment of certain opcodes following a spam attack and which it seems Byzantium EVM is dependant in some way.

{
    "config": {
        "homesteadBlock": 0,
        "eip150Block": 1,
    "byzantiumBlock": 1
    },
    "nonce": "0",
    "difficulty": "0x400",
    "mixhash": "0x00000000000000000000000000000000000000647572616c65787365646c6578",
    "coinbase": "0x0000000000000000000000000000000000000000",
    "timestamp": "0x00",
    "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "extraData": "0x",
    "gasLimit": "0x6ACFC0",
    "alloc": {}
}

Once we are done with the dump config that supports all forks enabled, this is not an issue anymore.

I have configured the byzantiumBlock in my private chain then also it is not working. I am using solidity v5.0.0.

Was this page helpful?
0 / 5 - 0 ratings