I have a simple testing contract:

contract TestContract {
    address public owner;
    address public someAddress;

    function TestContract() public {
        owner = msg.sender;

    modifier onlyOwner {
        assert(msg.sender == owner);

    function setSomeAddress(address _newAddress) onlyOwner public {
        someAddress = _newAddress;

According to documentation I should be able to call a state changing function on a contract like this:

transact_params = {
    'from': addr_owner,
    'gas': 21000,
    'gas_price': 1,

However this throws an exception:

File "/usr/local/lib/python3.5/dist-packages/web3/contract.py", line 624, in _find_matching_fn_abi
    raise ValueError("No matching functions found")

I have tried removing parameters, checking ABI (definition is there),... no avail. What am I doing wrong? How can I call a state changing function with web3.py?

  • 1
    What version of web3.py are you on? Would you add the ABI definition that you're using, and the line creating the contract instance? In general, the approach looks correct. – carver Nov 22 '17 at 15:12
  • I'm on 3.16.2 - but I think I figured it out from source, will post the answer... I see you are one of the developers - thanks for helping out, and thanks for a great library! – johndodo Nov 22 '17 at 15:15
  • Happy to help! :) – carver Nov 22 '17 at 15:47

Through follow-up, it became clear that the custom contract factory ConciseContract was used. That can be specified this way:

my_contract_instance = w3.eth.contract(..., ContractFactoryClass=ConciseContract)

ConciseContract looks up the first function call as a contract method. So this:


... attempts to look up the method transact() which is not available on the contract. That produces the error:

raise ValueError("No matching functions found")

In general, if you get that error, it means you are trying to interact with a function that is not defined in the ABI. Note that the functions are argument-dependent, so if you try to call the function defined in the ABI as myfunc(int) with a string as an argument, the message will be "No matching functions found".

  • True - I guess I copied that from somewhere... The problem was that I understood documentation as saying that ConciseContract was the only (non-abstract) type of Contract. So if I understand correctly, my original example should work if I remove , ContractFactoryClass=ConciseContract? – johndodo Nov 23 '17 at 8:49
  • 1
    Yes, it looks correct for the default contract. Thanks for flagging the documentation. I see how it could be interpreted that way, so I'll attempt to clarify it. – carver Nov 23 '17 at 16:29
  • I'm not using the custom contract factory ConciseContract, and still getting the same error. Can you please extend your answer if you happen to know why? – goodvibration Dec 22 '17 at 16:57
  • @goodvibration I added a bit more general info to the answer. If that doesn't help, I'd recommend asking a new question with background, code, etc. – carver Dec 22 '17 at 17:03
  • I did, thank you. – goodvibration Dec 22 '17 at 17:26

EDIT: below answer is correct for ConciseContract.

The correct syntax (tested in version 13.6.2) is:

my_contract_instance.setSomeAddress(w3.eth.accounts[1], transact=transact_params)

Be careful though - if I understand correctly, the **kwargs must have zero or one element which is used to specify the type of call (key must be one of call, transact or estimateGas). If **kwargs is empty, call is used.

*args are then passed to contract function.

  • 1
    This is true, only if you are using the ConciseContract contract factory. The syntax in your question was correct for the classic/default contract factory. – carver Nov 22 '17 at 15:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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