Skip to content

Structs return as lists #931

Open
Open
@fubuloubu

Description

@fubuloubu
  • 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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions