调用具有返回值的合同函数时,事务失败

时间:2018-05-13 02:15:17

标签: python solidity web3

当我的一份合同叫另一份合同时,我正在坚定地打出一些不直观的行为。我正在使用web3py测试合同。这是我能想到的最小的例子。请注意,它实际上可能不是一个最小的例子,因为失败的原因并没有从以太坊传播到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]})

Bar.run调用Foo.test2()时,测试通过,但调用Foo.test()时,测试失败。

utils.create_contract或多或少会对quickstart for web3py中显示的内容进行一些修改,以处理编译多个文件。

我得到以下错误的堆栈跟踪:

/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

0 个答案:

没有答案