I have a smart contract that I deployed to the Ropsten test network with truffle (using Javascript). I want to be able to send transactions to it from my server, which is written in Python. I've been trying to follow: http://web3py.readthedocs.io/en/stable/web3.eth.html#web3.eth.Eth.contract

from web3 import Web3, HTTPProvider
import json

provider = HTTPProvider('https://ropsten.infura.io/<Redacted Key>')
w3 = Web3(provider)
assert w3.isConnected()

abi = str(<Here I am pasting my abi in.  How should I do this, since I didn't build the contract in Python?>
escrow = w3.eth.contract(address='0x8850259566e9d03a1524e35687db2c78d4003409', abi=abi)

... When I get to this line, the program crashes:

File "/usr/local/lib/python3.6/dist-packages/web3/eth.py", line 351, in contract
    ContractFactory = ContractFactoryClass.factory(self.web3, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/web3/contract.py", line 225, in factory
  File "/usr/local/lib/python3.6/dist-packages/web3/utils/datatypes.py", line 36, in __new__
  File "cytoolz/functoolz.pyx", line 236, in cytoolz.functoolz.curry.__call__
  File "cytoolz/functoolz.pyx", line 232, in cytoolz.functoolz.curry.__call__
  File "/usr/local/lib/python3.6/dist-packages/eth_utils/functional.py", line 22, in inner
    return callback(fn(*args, **kwargs))
  File "/usr/local/lib/python3.6/dist-packages/web3/utils/formatters.py", line 69, in apply_formatters_to_dict
    raise type(exc)("Could not format value %r as field %r" % (item, key)) from exc
TypeError: __init__() missing 2 required positional arguments: 'doc' and 'pos'
  • It looks like there should be another part of the exception, with the message "Could not format value ... as field ...". Can you add that trace to the question, and the version of web3.py that you are using?
    – carver
    Commented Apr 30, 2018 at 17:24
  • I was able to get some help on the web3.py githubg page. Now I can compile the smart contract, but I can't get the abi: (let me know if I should close this issue or if you have any feedback: github.com/ethereum/py-solc/issues/49) Commented Apr 30, 2018 at 18:53

1 Answer 1


You need to provide the abi as a dictionary, not as a string. Since the ABI is json encoded, you need to parse it with json.loads or similar.

You should also read it directly from the contract json file that is generated by truffle. This makes sure you don't accidentally use an old ABI. Here is what I do:

from web3 import Web3, HTTPProvider
import json

with open("build/Contracts/YourContract.json") as f:
    info_json = json.load(f)
abi = info_json["abi"]

w3 = Web3(HTTPProvider("https://..."))
escrow = w3.eth.contract(address='0x8850259566e9d03a1524e35687db2c78d4003409', abi=abi)
  • I was able to get this working by downgrading solc from 0.4.19 to 0.4.17 Commented Apr 30, 2018 at 22:19
  • Huh, good to know. Do you know what the specific problem with the new version was?
    – mafrasi2
    Commented Apr 30, 2018 at 22:29
  • I wish I did :( Commented Apr 30, 2018 at 22:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.