La transacción falla al llamar a la función de contrato con valor de retorno

Estoy golpeando un comportamiento poco intuitivo en la solidez cuando uno de mis contratos llama a otro. Estoy probando los contratos con web3py. Este es el ejemplo más mínimo que se me ocurrió. Tenga en cuenta que en realidad puede no ser un ejemplo mínimo porque las razones de las fallas no se propagan desde ethereum a web3py.

Foo.sol:

solidez de pragma ^0.4.0;

importar "./Bar.sol";

contrato Foo {
    Bar bar público;

    funcion Foo(){
        barra = barra nueva ();
    }

    prueba de función () devuelve (uint) { devuelve 1; }

    función prueba2() {}

    función ejecutar () {
        barra.ejecutar();
    }
}

bar.sol

solidez de pragma ^0.4.0;

importar "./Foo.sol";

barra de contrato {
    dirección barra_dirección;
    barra de funciones(){
        bar_address = mensaje.remitente;
    }

    función ejecutar () {
        Foo foo = Foo(bar_address);
        // foo.prueba(); # falla
        foo.prueba2(); # tiene éxito
    }
}

prueba.py

desde web3 importar Web3, EthereumTesterProvider
prueba unitaria de importación
importar sistema operativo
de eth_tester.exceptions import TransactionFailed
importar tests.utils.utils como utils
de web3.utils.filters filtro de importación


clase TestMycroToken(unittest.TestCase):
    PROJECT_ROOT = os.ruta.dirname(os.ruta.dirname(__archivo__))
    CONTRACT_ROOT = os.path.join(PROJECT_ROOT, "contratos")
    TEST_CONTRACT_ROOT = os.path.join(CONTRACT_ROOT, "test_contracts")

    def test_foo(uno mismo):
        w3 = Web3(EthereumTesterProvider())
        contrato_propuesta, dirección_contrato_propuesta, instancia_contrato_propuesta = utils.create_contract(
            self.CONTRACT_ROOT, os.path.join(self.TEST_CONTRACT_ROOT, "Foo.sol"), "Foo", w3 )

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

Cuando Bar.runse llama, Foo.test2()la prueba pasa, pero cuando Foo.test()se llama, la prueba falla.

utils.create_contractmás o menos hace lo que se muestra en el inicio rápido para web3py con algunas modificaciones para manejar la compilación de varios archivos.

Obtengo el siguiente seguimiento de pila para el error:

/Users/paymahn/mycro/venv/bin/python /Applications/PyCharm.app/Contents/helpers/pycharm/_jb_unittest_runner.py --target test_mycro_token.TestMycroToken.test_foo
Lanzamiento de unittests con argumentos python -m unittest test_mycro_token.TestMycroToken.test_foo en /Users/paymahn/mycro/tests


Ejecutó 1 prueba en 0,692 s

FALLIDO (errores=1)

Error
Rastreo (llamadas recientes más última):
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/eth_tester/utils/formatting.py", línea 85, en contenedor
    return to_wrap(*argumentos, **kwargs)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/eth_tester/backends/pyethereum/v16/main.py", línea 439, en estimación_gas
    transacción=transacción,
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/eth_tester/backends/pyethereum/v16/main.py", línea 157, en _estimate_evm_transaction
    volver _send_evm_transaction(tester_module, evm, transaction_for_estimate)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/eth_tester/backends/pyethereum/v16/main.py", línea 145, en _send_evm_transaction
    evmdata=transacción.get('datos', b''),
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/ethereum/tester.py", línea 338, en envío
    volver self._send(*args, **kwargs)["salida"]
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/ethereum/tester.py", línea 296, en _send
    aumentar transacción fallida ()
ethereum.tester.TransactionFailed

La excepción anterior fue la causa directa de la siguiente excepción:

Rastreo (llamadas recientes más última):
  Archivo "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/case.py", línea 59, en testPartExecutor
    producir
  Archivo "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/case.py", línea 605, en ejecución
    método de prueba()
  Archivo "/Users/paymahn/mycro/tests/test_mycro_token.py", línea 125, en test_foo
    propuesta_contract_instance.execute(transact={'from': self.w3.eth.accounts[1]})
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/contract.py", línea 777, en __call__
    return self.__prepared_function(*args, **kwargs)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/contract.py", línea 790, en __prepared_function
    devuelve getattr(self._function(*args), modificador)(modifier_dict)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/contract.py", línea 1028, en transacción
    **auto.kwargs)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/contract.py", línea 1305, en transact_with_contract_function
    txn_hash = web3.eth.sendTransaction(transact_transaction)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/eth.py", línea 247, en sendTransaction
    get_buffered_gas_estimate(self.web3, transacción),
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/utils/transactions.py", línea 72, en get_buffered_gas_estimate
    gas_estimate = web3.eth.estimateGas(gas_estimate_transaction)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/eth.py", línea 288, en la estimación de Gas
    [transacción],
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/manager.py", línea 103, en request_blocking
    respuesta = self._make_request(método, parámetros)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/manager.py", línea 86, en _make_request
    devuelve request_func (método, parámetros)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/gas_price_strategy.py", línea 18, en middleware
    volver make_request(método, parámetros)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/formatting.py", línea 21, en middleware
    respuesta = make_request(método, formatted_params)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/attrdict.py", línea 18, en middleware
    respuesta = make_request(método, parámetros)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/formatting.py", línea 21, en middleware
    respuesta = make_request(método, formatted_params)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/normalize_errors.py", línea 9, en middleware
    resultado = make_request(método, parámetros)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/validation.py", línea 44, en middleware
    volver make_request(método, post_validated_params)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/formatting.py", línea 21, en middleware
    respuesta = make_request(método, formatted_params)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/providers/eth_tester/middleware.py", línea 315, en middleware
    return make_request(método, [llenado_transacción] + params[1:])
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/fixture.py", línea 12, en middleware
    volver make_request(método, parámetros)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/middleware/formatting.py", línea 21, en middleware
    respuesta = make_request(método, formatted_params)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/providers/eth_tester/main.py", línea 46, en make_request
    respuesta = delegador(self.ethereum_tester, params)
  Archivo "cytoolz/functoolz.pyx", línea 232, en cytoolz.functoolz.curry.__call__
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/web3/providers/eth_tester/defaults.py", línea 36, ​​en call_eth_tester
    devuelve getattr(eth_tester, fn_name)(*fn_args, **fn_kwargs)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/eth_tester/main.py", línea 466, en estimación_gas
    raw_gas_estimate = self.backend.estimate_gas(raw_transaction)
  Archivo "/Users/paymahn/mycro/venv/lib/python3.6/site-packages/eth_tester/utils/formatting.py", línea 88, en contenedor
    elevar old_to_new_Exceptions[tipo(e)] de e
eth_tester.excepciones.Transacción fallida
Tengo el mismo problema con web3py y abrí un problema en su enlace de github

Respuestas (1)

Mire el problema de github que hice, que es similar. La respuesta allí funcionó para mí.