2

I'm hitting some unintuitive behavior in solidity when one of my contracts calls another. I'm testing the contracts with web3py. Here's is the most minimal example I could come up with. Note that it may not actually be a minimal example because failures reasons aren't propagated from ethereum to web3py.

Foo.sol:

pragma solidity ^0.4.0;

import "./Bar.sol";

contract Foo {
    Bar public bar;

    function Foo(){
        bar = new Bar();
    }

    function test() returns (uint) { return 1; }

    function test2() {}

    function execute() {
        bar.run();
    }
}

Bar.sol

pragma solidity ^0.4.0;

import "./Foo.sol";

contract Bar {
    address bar_address;
    function Bar(){
        bar_address = msg.sender;
    }

    function run() {
        Foo foo = Foo(bar_address);
        // foo.test(); # fails
        foo.test2(); # succeeds
    }
}

test.py

from web3 import Web3, EthereumTesterProvider
import unittest
import os
from eth_tester.exceptions import TransactionFailed
import tests.utils.utils as utils
from web3.utils.filters import Filter


class TestMycroToken(unittest.TestCase):
    PROJECT_ROOT = os.path.dirname(os.path.dirname(__file__))
    CONTRACT_ROOT = os.path.join(PROJECT_ROOT, "contracts")
    TEST_CONTRACT_ROOT = os.path.join(CONTRACT_ROOT, "test_contracts")

    def test_foo(self):
        w3 = Web3(EthereumTesterProvider())
        proposal_contract, proposal_contract_address, proposal_contract_instance = utils.create_contract(
            self.CONTRACT_ROOT, os.path.join(self.TEST_CONTRACT_ROOT,  "Foo.sol"), "Foo", w3 )

        proposal_contract_instance.execute(transact={'from': self.w3.eth.accounts[1]})

When Bar.run calls Foo.test2() the test passes, but when Foo.test() is called, the test fails.

utils.create_contract more or less does what's shown in the quickstart for web3py with some modifications to handle compiling multiple files.

I'm getting the following stack trace for the error:

/Users/paymahn/mycro/venv/bin/python /Applications/PyCharm.app/Contents/helpers/pycharm/_jb_unittest_runner.py --target test_mycro_token.TestMycroToken.test_foo
Launching unittests with arguments python -m unittest test_mycro_token.TestMycroToken.test_foo in /Users/paymahn/mycro/tests


Ran 1 test in 0.692s

FAILED (errors=1)

Error
Traceback (most recent call last):
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/eth_tester/utils/formatting.py", line 85, in wrapper
    return to_wrap(*args, **kwargs)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/eth_tester/backends/pyethereum/v16/main.py", line 439, in estimate_gas
    transaction=transaction,
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/eth_tester/backends/pyethereum/v16/main.py", line 157, in _estimate_evm_transaction
    return _send_evm_transaction(tester_module, evm, transaction_for_estimate)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/eth_tester/backends/pyethereum/v16/main.py", line 145, in _send_evm_transaction
    evmdata=transaction.get('data', b''),
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/ethereum/tester.py", line 338, in send
    return self._send(*args, **kwargs)["output"]
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/ethereum/tester.py", line 296, in _send
    raise TransactionFailed()
ethereum.tester.TransactionFailed

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/case.py", line 59, in testPartExecutor
    yield
  File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/case.py", line 605, in run
    testMethod()
  File "/Users/paymahn/mycro/tests/test_mycro_token.py", line 125, in test_foo
    proposal_contract_instance.execute(transact={'from': self.w3.eth.accounts[1]})
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/contract.py", line 777, in __call__
    return self.__prepared_function(*args, **kwargs)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/contract.py", line 790, in __prepared_function
    return getattr(self._function(*args), modifier)(modifier_dict)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/contract.py", line 1028, in transact
    **self.kwargs)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/contract.py", line 1305, in transact_with_contract_function
    txn_hash = web3.eth.sendTransaction(transact_transaction)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/eth.py", line 247, in sendTransaction
    get_buffered_gas_estimate(self.web3, transaction),
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/utils/transactions.py", line 72, in get_buffered_gas_estimate
    gas_estimate = web3.eth.estimateGas(gas_estimate_transaction)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/eth.py", line 288, in estimateGas
    [transaction],
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/manager.py", line 103, in request_blocking
    response = self._make_request(method, params)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/manager.py", line 86, in _make_request
    return request_func(method, params)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/gas_price_strategy.py", line 18, in middleware
    return make_request(method, params)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/formatting.py", line 21, in middleware
    response = make_request(method, formatted_params)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/attrdict.py", line 18, in middleware
    response = make_request(method, params)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/formatting.py", line 21, in middleware
    response = make_request(method, formatted_params)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/normalize_errors.py", line 9, in middleware
    result = make_request(method, params)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/validation.py", line 44, in middleware
    return make_request(method, post_validated_params)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/formatting.py", line 21, in middleware
    response = make_request(method, formatted_params)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/providers/eth_tester/middleware.py", line 315, in middleware
    return make_request(method, [filled_transaction] + params[1:])
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/fixture.py", line 12, in middleware
    return make_request(method, params)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/formatting.py", line 21, in middleware
    response = make_request(method, formatted_params)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/providers/eth_tester/main.py", line 46, in make_request
    response = delegator(self.ethereum_tester, params)
  File "cytoolz/functoolz.pyx", line 232, in cytoolz.functoolz.curry.__call__
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/providers/eth_tester/defaults.py", line 36, in call_eth_tester
    return getattr(eth_tester, fn_name)(*fn_args, **fn_kwargs)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/eth_tester/main.py", line 466, in estimate_gas
    raw_gas_estimate = self.backend.estimate_gas(raw_transaction)
  File "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/eth_tester/utils/formatting.py", line 88, in wrapper
    raise old_to_new_exceptions[type(e)] from e
eth_tester.exceptions.TransactionFailed
1
  • 1
    I have the same issue with web3py and I opened an issue in their github link
    – davinci26
    Jun 23, 2018 at 16:00

1 Answer 1

1

Look at the github issue I made, which is similar. The answer there worked for me.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.