Web3.py: Transaction fail (Tx is Successful in Remix)

Created on 23 Jun 2018  ·  8Comments  ·  Source: ethereum/web3.py

Hey,

I get a transaction failed when trying to execute the following contract:

  pragma solidity ^0.4.23;
  pragma experimental ABIEncoderV2;
  contract state {    
      uint256 contract_version = 1;
      function set_version(uint256 cv_n) public {
                contract_version = cv_n;
      }
      function get_version() public view returns (uint256) {
                return contract_version;
      }
  }
  contract complicated {
     state st;
     constructor() public {
            address st_address = new state();
            st = state(st_address);
     }
     function set_version(uint256 cv_n) public {
            st.set_version(cv_n);
     }
     function get_version() public view returns (uint256) {
            return st.get_version();
     }
  }

And to execute the contract using solidity I use the following code derived from the example:

compiled_sol = compile_source(contract_source_code) # Compiled source code
contract_interface = compiled_sol['<stdin>:complicated']

# web3.py instance
w3 = Web3(Web3.TestRPCProvider())

# set pre-funded account as sender
w3.eth.defaultAccount = w3.eth.accounts[0]

# Instantiate and deploy contract
Greeter = w3.eth.contract(abi=contract_interface['abi'], bytecode=contract_interface['bin'])

# Submit the transaction that deploys the contract
tx_hash = Greeter.constructor().transact()

# Wait for the transaction to be mined, and get the transaction receipt
tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)

# Create the contract instance with the newly-deployed address
greeter = w3.eth.contract(
    address=tx_receipt.contractAddress,
    abi=contract_interface['abi']
)

# Display the default greeting from the contract
print('Setting the state version to 10...')
tx_hash = greeter.functions.set_version(10).transact()

# Wait for transaction to be mined...
w3.eth.waitForTransactionReceipt(tx_hash)

# Display the new greeting value
print('Updated contract greeting: {}'.format(
    greeter.functions.get_version().call()
))

Using Web3py I get the following error message:
ValueError: {'code': -32000, 'message': 'Server error', 'data': {'type': 'TransactionFailed', 'args': [], 'message': ''}}

When I import the cotnract to remix the contract works perfectly
Edit: I discovered someone else having the same issue ( Source

All 8 comments

compiled_sol = compile_source(contract_source_code) # Compiled source code

@davinci26 Can you try changing the code above to the following:

compiled_sol = compile_source(contract_source_code, evm_version='homestead')

I haven't tested the code! BUT if that works, then I'll tell you the cause of the problem.

@voith Amazing it works! thanks alot! Can you explain a bit more what is happening?

@davinci26 I realised that you were using solidity version greater than 0.4.22. Solidity versions post 0.4.22 have introduced two new opcodes, which aren't implemented in pyethereum which was causing the TransactionFailed error. To know more read: https://medium.com/@chris_77367/explaining-unexpected-reverts-starting-with-solidity-0-4-22-3ada6e82308c

Closing since this appears to be resolved. Thanks @voith !

@voith Do you know where we can track the introduction of these opcodes into pyethereum (or maybe py-evm)? https://github.com/ethereum/pyethereum/blob/develop/ethereum/opcodes.py#L41 suggests that the opcodes already exist. I'm looking at my requirements file and I can't tell whether I depend on pyethereum or py-evm.

Is it expected that the contract posted by @davinci26 works on mainnet because those opcodes do exist?

https://github.com/ethereum/pyethereum/blob/develop/ethereum/opcodes.py#L41

that's interesting. However the version of py-ethereum that I used did not have those opcodes implemented.

I'm looking at my requirements file and I can't tell whether I depend on pyethereum or py-evm.

If you're using TestRPCProvider() then you're definitely using py-ethereum.
what does pip freeze | grep ethereum say?

works on mainnet because those opcodes do exist?

Those should work on the mainnet, AFAIK. I haven't tested though.

If you looking for a node to run unit/integration tests than you can use eth-tester. But make sure that you're using the py-evm backend to avoid TransactionFailure errors that are raised due to missing opcodes.

Yeah, what's curious is that https://github.com/ethereum/pyethereum/blob/develop/ethereum/opcodes.py#L41 was last changed in September of 2017: https://github.com/ethereum/pyethereum/commits/develop/ethereum/opcodes.py

I'm using the EthereumTesterProvider.

Here's the output of pip freeze | grep eth:

 ❮❮❮ pip freeze | grep eth
eth-abi==1.1.1
eth-account==0.2.3
eth-hash==0.1.4
eth-keyfile==0.5.1
eth-keys==0.2.0b3
eth-rlp==0.1.2
eth-tester==0.1.0b27
eth-utils==1.0.3
ethereum==1.6.1
pyethash==0.1.27

Thanks for the tip on using py-evm with eth-tester. I'll give that a shot :)

ethereum==1.6.1 is a very old version and doesn't have the byzantium opcodes implemented.

I'm using the EthereumTesterProvider.

There are two different providers in web3.py with the name EthereumTesterProvider.

  • from web3.providers.tester import EthereumTesterProvider(uses eth-testrpc which uses pyethereum internally)
  • from web3.providers.eth_tester import EthereumTesterProvider (uses eth-teser which supports multiple backends).

if you're planing to use eth-tester than make sure that you use eth_tester.EthereumTesterProvider.
eth-tester expects input a slightly different manner and the provider internally takes care of the data conversion.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

venkatBGit picture venkatBGit  ·  4Comments

kaleb-keny picture kaleb-keny  ·  4Comments

locpv-ibl picture locpv-ibl  ·  4Comments

Lebski picture Lebski  ·  5Comments

carver picture carver  ·  4Comments