ethers.js icon indicating copy to clipboard operation
ethers.js copied to clipboard

Add "struct" type to the Human-Readable ABI

Open ricmoo opened this issue 7 years ago • 11 comments

With ABIv2, there are more contracts using structs as input and output parameters, so it would be useful to allow the Human-Readable ABI to support structs as a alias to its respective tuple.

For example:

abi = [
    "event registered(tuple(address user, string email) user)",
    "function getId(tuple(address user, string email) user) view returns (uint id)",
    "function getUser(uint id) view returns (tuple(address user, string email) user)",
    "function addUser(tuple(address user, string email) user)"
]

Should also be able to be written as:

abi = [
    "struct User { address user, string email }",

    "event registered(User user)",
    "function getId(User user) view returns (uint id)",
    "function getUser(uint id) view returns (User user)",
    "function addUser(User user)",

    // Also support composite structs
    "struct Relationship { User a, User b, string relationship }",
]

ricmoo avatar Oct 16 '18 19:10 ricmoo

Hello @ricmoo

Is it currently possible to pass a struct (as a tuple) to a public function using ethers?

For example: function get(Info memory info) public returns(bool)

Is it yet safe to use it in production?

kraikov avatar Dec 07 '18 14:12 kraikov

It certainly is available, here is an example: https://blog.ricmoo.com/solidity-abiv2-a-foray-into-the-experimental-a6afd3d47185

I believe it is discouraged for production use though, as it is still experimental.

This ticket is more about adding aliases for structs in the human-readable ABI.

ricmoo avatar Dec 07 '18 17:12 ricmoo

YEAAH ! Go struct type in Human Readable ABI !

gitpusha avatar Jun 10 '20 09:06 gitpusha

What is the status of this?

mudgen avatar Mar 08 '21 22:03 mudgen

Should also be able to be written as

While struct syntax is not supported, this works for me

const User = "(address user, string email)";
const abi = [
  `event registered(${User} user)`,
  `function getId(${User} user) view returns (uint id)`,
  `function getUser(uint id) view returns (${User} user)`,
  `function addUser(${User} user)`,
];
const Relationship = `(${User} a, ${User} b, string relationship)`;

borgbob avatar Feb 11 '22 00:02 borgbob

Should also be able to be written as

While struct syntax is not supported, this works for me

const User = "(address user, string email)";
const abi = [
  `event registered(${User} user)`,
  `function getId(${User} user) view returns (uint id)`,
  `function getUser(uint id) view returns (${User} user)`,
  `function addUser(${User} user)`,
];
const Relationship = `(${User} a, ${User} b, string relationship)`;

OMG, you are my life saver

cryptothink629 avatar Sep 05 '22 16:09 cryptothink629

@borgbob that works when the returns are a single element, but when you want to return an array of structs it doesn't do the trick.

We could use

const User = "(address user, string email)";
const abi = [
  `function getUsers() view returns (tuple(tuple${User}))`,
];

but then you need to know beforehand the number of elements the function is going to return, and normally you don`t

I'm finding that being able to indicate the struct type on the ABI and then indicating the function return type, would be very good.

abi = [
    "struct User { address user, string email }",
    "function getUsers() view returns (User[] memory)",
]

sraver avatar Sep 20 '22 19:09 sraver

Try this it works for me 100% --

const TaskStruct = "(uint256 id , string content , bool completed)"

const Simple_ABI = [ function getTodos() public view returns(${TaskStruct}[] tasks), function getTodo(uint256 _id) public view returns(${TaskStruct} task) ]

01JAMIL avatar Jan 20 '23 18:01 01JAMIL

@01JAMIL Thanks for pointing it out! I probably missed trying it that way, will check next time I face the issue! :pray:

sraver avatar Mar 09 '23 10:03 sraver

Hi from time machine. Is this feature by any chance supported? @ricmoo

xinbenlv avatar Jun 28 '23 20:06 xinbenlv

Should also be able to be written as

While struct syntax is not supported, this works for me

const User = "(address user, string email)";
const abi = [
  `event registered(${User} user)`,
  `function getId(${User} user) view returns (uint id)`,
  `function getUser(uint id) view returns (${User} user)`,
  `function addUser(${User} user)`,
];
const Relationship = `(${User} a, ${User} b, string relationship)`;

A clever solution. It works, a million thanks

JanessaTech avatar Dec 06 '23 02:12 JanessaTech