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.run
se llama, Foo.test2()
la prueba pasa, pero cuando Foo.test()
se llama, la prueba falla.
utils.create_contract
má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
Mire el problema de github que hice, que es similar. La respuesta allí funcionó para mí.
davinci26