I'm using web3.py to interact with an Ethereum Smart Contract which is:
pragma solidity ^0.4.0;
contract Coin {
address public minter;
string public name;
mapping (address => uint) public balances;
event Sent(address from, address to, uint amount);
function Coin() public {
minter = msg.sender;
name = 'MyCoin';
}
// Create new Tokens
function mint(address _reciever, uint _amount) public {
if (msg.sender != minter) return;
balances[_reciever] += _amount;
}
// Send tokens
function send(address _reciever, uint _amount) public {
if (balances[msg.sender] < _amount) return;
balances[msg.sender] -= _amount;
balances[_reciever] += _amount;
Sent(msg.sender, _reciever, _amount);
}
function getBalance(address _user) public view returns (uint){
return balances[_user];
}
function balances(address _account) public view returns (uint, string) {
return (balances[_account], name);
}
}
Compiling, deploying and generating ABI and contract address were successful. Hower, when i try to access to the deployed smart contract using web3.py i got a strange exception when i call the function balances()
in the smart contract.
eth_abi.exceptions.InsufficientDataBytes: Tried to read 32 bytes. Only got 0 bytes
I used geth
with a custom genesis block and parity
chain dev node, but without any success.
Here is my Python code:
import json
from web3 import Web3, RPCProvider
from web3.contract import ConciseContract
import time
RPC_IP = '127.0.0.1'
RPC_PORT = '8545'
# read the contract informations then convert them into a Python dict
with open('contract_informations.json', 'r') as f:
data = json.loads(f.read())
ABI = data.get('abi')
CONTARCT_ADDRESS = data.get('contract_address')
w3 = Web3(RPCProvider(RPC_IP, RPC_PORT))
contract_instance = w3.eth.contract(ABI, CONTARCT_ADDRESS, ContractFactoryClass=ConciseContract)
contract_instance.mint('0x00a329c0648769A73afAc7F9381E08FB43dBEA72', 1000, transact={'from': w3.eth.accounts[0]})
print(contract_instance.getBalance('0x00a329c0648769A73afAc7F9381E08FB43dBEA72'))
When i run the Python code there is two exceptions:
web3.exceptions.BadFunctionCallOutput: Could not transact with/call contract function, is contract deployed correctly and chain synced?
and
eth_abi.exceptions.InsufficientDataBytes: Tried to read 32 bytes. Only got 0 bytes
However, when i deploy the contract using Parity
web interface, everything works fine.
Did, web3.py
has some limitations or did i miss something ?
Thanks for your answers.
Best Answer
How do you know deployment was successful? Can you add the code where you wait for the transaction to complete and then you retrieve the contract address?
For what it's worth, a typical compiler would turn your public mapping into a function in the ABI that is exactly equivalent to the
getBalance
that you wrote. So you could also callcontract_instance.balances('0x00a329c0648769A73afAc7F9381E08FB43dBEA72')
.This strongly indicates that something is going wrong during your deployment that you haven't identified. Right now, there is not enough information in the question to debug the deployment.