I was trying to call a function from my python server to a contract deployed in Ropsten.
This is my method in the contract:
function send(address receiver, uint amount) public {
require(msg.sender == owner);
balances[receiver] += amount;
emit Sent(msg.sender, receiver, amount);
}
Here I try to call the method:
def default_reward():
name = request.json["ckan_user_id"]
user = db["userinfos"].find_one({"ckan_user_id":name})
address = user["bc_user_address"]
contract = wb3.eth.contract(
address=config.audacoin_contract_address,
abi=get_abi_audacoin(),
)
tx_hash = contract.functions.send(address, 5).call().transact({"from": config.ADMIN_ADDRESS})
tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)
return "Sended"
But I can't call the function. ¿Anybody know how can I call this method?
Thanks very much.
UPDATE
I have changed the method, but I have a new error:
def default_reward():
name = request.json["ckan_user_id"]
user = db["userinfos"].find_one({"ckan_user_id":name})
address = user["bc_user_address"]
contract = wb3.eth.contract(
address=config.audacoin_contract_address,
abi=get_abi_audacoin(),
)
tx_hash = contract.functions.send(address, 5).transact({"from": config.ADMIN_ADDRESS})
tx_receipt = wb3.eth.waitForTransactionReceipt(tx_hash)
return "Sended"
But I am having this error:
127.0.0.1 - - [31/Oct/2019 12:44:18] "POST /dataset/audacoin/default_reward HTTP/1.1" 500 -
Traceback (most recent call last):
File "/home/ibai/Documentos/proyecto/AudablokAPI/venv/lib/python3.6/site-packages/flask/app.py", line 2328, in __call__
return self.wsgi_app(environ, start_response)
File "/home/ibai/Documentos/proyecto/AudablokAPI/venv/lib/python3.6/site-packages/flask/app.py", line 2314, in wsgi_app
response = self.handle_exception(e)
File "/home/ibai/Documentos/proyecto/AudablokAPI/venv/lib/python3.6/site-packages/flask/app.py", line 1760, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/ibai/Documentos/proyecto/AudablokAPI/venv/lib/python3.6/site-packages/flask/_compat.py", line 36, in reraise
raise value
File "/home/ibai/Documentos/proyecto/AudablokAPI/venv/lib/python3.6/site-packages/flask/app.py", line 2311, in wsgi_app
response = self.full_dispatch_request()
File "/home/ibai/Documentos/proyecto/AudablokAPI/venv/lib/python3.6/site-packages/flask/app.py", line 1834, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/ibai/Documentos/proyecto/AudablokAPI/venv/lib/python3.6/site-packages/flask/app.py", line 1737, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/ibai/Documentos/proyecto/AudablokAPI/venv/lib/python3.6/site-packages/flask/_compat.py", line 36, in reraise
raise value
File "/home/ibai/Documentos/proyecto/AudablokAPI/venv/lib/python3.6/site-packages/flask/app.py", line 1832, in full_dispatch_request
rv = self.dispatch_request()
File "/home/ibai/Documentos/proyecto/AudablokAPI/venv/lib/python3.6/site-packages/flask/app.py", line 1818, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/ibai/Documentos/proyecto/AudablokAPI/api/dataset.py", line 665, in default_reward
tx_hash = contract.functions.send(address, 5).transact({"from": config.ADMIN_ADDRESS})
File "/home/ibai/Documentos/proyecto/AudablokAPI/venv/lib/python3.6/site-packages/web3/contract.py", line 1151, in transact
**self.kwargs
File "/home/ibai/Documentos/proyecto/AudablokAPI/venv/lib/python3.6/site-packages/web3/contract.py", line 1454, in transact_with_contract_function
txn_hash = web3.eth.sendTransaction(transact_transaction)
File "/home/ibai/Documentos/proyecto/AudablokAPI/venv/lib/python3.6/site-packages/web3/eth.py", line 269, in sendTransaction
[transaction],
File "/home/ibai/Documentos/proyecto/AudablokAPI/venv/lib/python3.6/site-packages/web3/manager.py", line 112, in request_blocking
raise ValueError(response["error"])
ValueError: {'code': -32601, 'message': 'The method eth_sendTransaction does not exist/is not available'}
Best Answer
Short answer
The issue is in the line where you try to transact with the function. You should not be invoking
call()
beforetransact()
. The following modification should fix it:Explanation
Given the wording of your question I think you maybe be unclear on the difference between calling a contract and sending a transaction to a contract:
The
web3.py
contract API allows you to call or transact with any contract function.call
returns whatever value(s) the contract function returns,transact
returns a transaction hash.In your example you are first using
call()
to call thesend
function, which returnsNone
becausesend
has no return value. You are then attempting to calltransact
upon the returnedNoneType
, which raises anAttributeError
.