Web3.py: AttributeError when running contract method

Created on 2 Sep 2018  路  5Comments  路  Source: ethereum/web3.py

  • Version: 4.6.0
  • Python: 3.6
  • OS: osx

What was wrong?

Please include any of the following that are applicable:

  • The code which produced the error
# a.py
from ethtoken.abi import EIP20_ABI

from web3 import Web3
from web3.auto import w3
from web3.middleware import geth_poa_middleware

NODE_HTTP_ADDRESS = "http://127.0.0.1:8545"
MTN_CONTRACT_ADDRESS = "0x6160c9d6943f7c1040bb6e247cb100c19566185d"

MTN1_PUB_KEY = "0xf9a5c72412c0200b0801f581c6008e852c963bfe"


w3 = Web3(Web3.HTTPProvider(NODE_HTTP_ADDRESS, request_kwargs={'timeout': 60}), middlewares=[geth_poa_middleware])
print("connected")

w3.eth.enable_unaudited_features()
mtn = w3.eth.contract(address=Web3.toChecksumAddress(MTN_CONTRACT_ADDRESS), abi=EIP20_ABI)
balance = int(mtn.functions.balanceOf(Web3.toChecksumAddress(MTN1_PUB_KEY)).call())
  • The full output of the error
[amirbaer@beth] tmp > python3 a.py
connected
Traceback (most recent call last):
  File "a.py", line 20, in <module>
    balance = int(mtn.functions.balanceOf(Web3.toChecksumAddress(MTN1_PUB_KEY)).call())
  File "/usr/local/lib/python3.6/site-packages/web3/contract.py", line 1108, in call
    block_id = parse_block_identifier(self.web3, block_identifier)
  File "/usr/local/lib/python3.6/site-packages/web3/contract.py", line 1414, in parse_block_identifier
    last_block = web3.eth.getBlock('latest').number
AttributeError: 'dict' object has no attribute 'number'
  • What type of node you were connecting to.
    geth @ rinkeby

How can it be fixed?

As far as I can tell, by simply replacing:
web3.eth.getBlock('latest').number
with:
web3.eth.getBlock('latest')['number']

Most helpful comment

Interested in writing up a proposed alternative API @voith in a new issue?

Sure will do, but not today. focused on my populus work for now.

All 5 comments

@amirbaer I highly recommend you add the poa middleware as described in the docs:

# inject the poa compatibility middleware to the innermost layer
>>> w3.middleware_stack.inject(geth_poa_middleware, layer=0)

Many of the docs assume that the default middlewares are in place. For example, the default middlewares enable you to pass in native python types, and get them as results from contract calls, rather than convert everything to and from hex strings.

@carver This makes me think that configuring middlewares shouldn't be so flexible. The default middlewares like attrdict, pythonic, abi, formating, etc should be plugged in, no matter what the user configures the middlewares to.

Else we need to add a note in the docs telling users to "Beware! Overriding the default middlewares can lead to an undesired behaviour. Most likely what you're are looking for is w3.middleware_stack.inject API".

Yeah, I'm inclined to agree. We can start experimenting with alternative APIs and probably deprecate the current one in v5. cc @dylanjw

(especially since there's already a warning. Though perhaps the warning could be moved to a better place or worded more clearly: https://web3py.readthedocs.io/en/stable/middleware.html#optional-middleware :))

Interested in writing up a proposed alternative API @voith in a new issue?

Interested in writing up a proposed alternative API @voith in a new issue?

Sure will do, but not today. focused on my populus work for now.

Was this page helpful?
0 / 5 - 0 ratings