Open
Description
- Version: 4.3.0
- Python: 3.6
- OS: linux
What was wrong?
I have a contract with a mapping and a struct with public accessors:
pragma solidity ^0.4.24;
contract A {
struct MyStruct {
uint a;
uint b;
}
MyStruct public myStruct;
mapping (address => MyStruct) public myMapping;
}
However, in web3py, it returns lists instead of structs:
from web3 import Web3, EthereumTesterProvider
w3 = Web3(EthereumTesterProvider())
contract_data = {
'bytecode' : '0x608060405234801561001057600080fd5b50610143806100206000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637c07d4f1146100515780638bc9fe6c146100af575b600080fd5b34801561005d57600080fd5b50610092600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506100e1565b604051808381526020018281526020019250505060405180910390f35b3480156100bb57600080fd5b506100c4610105565b604051808381526020018281526020019250505060405180910390f35b60026020528060005260406000206000915090508060000154908060010154905082565b600080600001549080600101549050825600a165627a7a72305820c9c5dcef2ed03794dc04e36476afbb4cfb28b05e167806d4fdfb32e0e66a44540029',
'bytecode_runtime' : '0x60806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637c07d4f1146100515780638bc9fe6c146100af575b600080fd5b34801561005d57600080fd5b50610092600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506100e1565b604051808381526020018281526020019250505060405180910390f35b3480156100bb57600080fd5b506100c4610105565b604051808381526020018281526020019250505060405180910390f35b60026020528060005260406000206000915090508060000154908060010154905082565b600080600001549080600101549050825600a165627a7a72305820c9c5dcef2ed03794dc04e36476afbb4cfb28b05e167806d4fdfb32e0e66a44540029',
'abi' : [{"constant":True,"inputs":[{"name":"","type":"address"}],"name":"myMapping","outputs":[{"name":"a","type":"uint256"},{"name":"b","type":"uint256"}],"payable":False,"stateMutability":"view","type":"function"},{"constant":True,"inputs":[],"name":"myStruct","outputs":[{"name":"a","type":"uint256"},{"name":"b","type":"uint256"}],"payable":False,"stateMutability":"view","type":"function"}]
}
tx_hash = w3.eth.contract(**contract_data).constructor().transact()
tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)
contract = w3.eth.contract(address=tx_receipt.contractAddress, abi=contract_data['abi'])
contract.functions.myMapping("0x0").call()
[0, 0]
contract.functions.myStruct().call()
[0, 0]
It would be nicer if this returned a MyStruct
struct object, or some dict with those keys, or something more explicit than a list.
How can it be fixed?
There is no direct way to access MyStruct
's layout from the ABI, but typically it apppears similar to a tuple and always has the members annotated in the output args of the getter. There should be some way to cast that to a struct object or dict so it's a little more intuitive for developers.