Web3.js: handling tuples (structs)

Created on 20 Dec 2017  Â·  76Comments  Â·  Source: ChainSafe/web3.js

in solidity verion 0.4.19 tuples are supported, which allow structs as input-params. The current encoder in web3-eth-abi does not support them yet.
a definition of them can be found here: http://solidity.readthedocs.io/en/develop/abi-spec.html?highlight=tuple#handling-tuple-types

example:

[
  {
    "name": "f",
    "type": "function",
    "inputs": [
      {
        "name": "s",
        "type": "tuple",
        "components": [
          {
            "name": "a",
            "type": "uint256"
          },
          {
            "name": "b",
            "type": "uint256[]"
          },
          {
            "name": "c",
            "type": "tuple[]",
            "components": [
              {
                "name": "x",
                "type": "uint256"
              },
              {
                "name": "y",
                "type": "uint256"
              }
            ]
          }
        ]
      },
      {
        "name": "t",
        "type": "tuple",
        "components": [
          {
            "name": "x",
            "type": "uint256"
          },
          {
            "name": "y",
            "type": "uint256"
          }
        ]
      },
      {
        "name": "a",
        "type": "uint256"
      }
    ],
    "outputs": []
  }
]
enhancement help wanted

Most helpful comment

+1

All 76 comments

We should definitely support that. I started looking into this. Any help would be welcome.

Any updates on this? Thanks.

Will it be available for solidity view function too ?

This will be a great feature, it will let me focus more of the filtering on the frontend instead of within the contract. Also should reduce the number of calls to the contract. Any idea when a feature like this might be ready?

Any updates?

+1

@OlyRice ethers.js have this working now https://github.com/ethers-io/ethers.js/issues/84

+1

+1

++;

03.02.2018 7:10 PM "Phil" notifications@github.com napisał(a):

+1

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/ethereum/web3.js/issues/1241#issuecomment-362841404,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABiASdWz1fh5hJEBQ5RT0ImwOh_ted5Mks5tRKERgaJpZM4RIdkx
.

+= 1;

+1

I've encountered this issue now using Truffle. I looked at the link with the definition, but I don't understand it. Could ethers.js and web3 share the same code?

+1

+1

Im on this in the #newAbiLib branch, but wont be able to finish the next two weeks, as im on holidays.

Just ran into the same thing, wanting to pass a struct as a constructor argument with contract.new(constructorArg, {data:...});

I've joined to waiting

+1

@frozeman any news on this?

+1

+1

This is necessary as Truffle development environment still at 0.20.x.

bandwagon +1 :(

+1

+1

+1

+1

+1

Any news on this one?

Im
Traveling this week and waiting for https://github.com/ethers-io/ethers.js/issues/163
If you push there Rico might get it faster done :)

+1 :)

+1

+1

+1

Is there currently any workaround? For example would it be feasible to manually transform the struct parameter to bytecode via 3rd party utility and pass it to the web3js function?

+1

+1

We've worked on adding ether-js ABI decode to support tuples. Could you guys please test the https://github.com/ethereum/web3.js/tree/newAbiLib branch and see if it works for you guys?
It would be great if the community could provide test cases for tuples (ins and out puts of the EVM), so we can test that i en/decodes properly.
Current tests can be found here: https://github.com/ethereum/web3.js/blob/newAbiLib/test/abi.decodeParameter.js
And for components it would expect the outputs or inputs of the json interface, as follows:

web3.eth.abi.decodeParameters(jsonInterface.outputs, bytes) > Results {....}

web3.eth.abi.encodeParameters(jsonInterface.inputs, parameters) > 0x12345.....

simply posting the raw eth_call output, or inputs, and the jsonInterface would help.

+1

+1

+1

@frozeman I had a look at the newAbiLib branch, and run the test locally to make sure I was loading the right version of web3-eth-abi, yet I fail to see how to use it.

Making a call to a contract that outputs a struct fails (Error: invalid solidity type!: tuple) and I don't know how to get the raw output to decode it.

I also tried to encode a function call with structs in the parameters, but the encoding fails if one of the input has type: 'tuple' (Error: Invalid solidity type: tuple ) :/

@frozeman Would you be so kind and publish the newAbiLib branch to npm? It seems that lerna causes problems on some platforms thus adding git+http path as a dependency is not always possible. You also need to have additional packages installed globally. Puting this to npm (e.g. web3-newabilib) would really help!

+1

@frozeman I am not sure if I understand the progress made on this issue, but I npm installed ethereum/web3.js#newAbiLib and could some what get tuples to work. I deployed the following contract locally and tried to call foo:

pragma solidity ^0.4.24;
pragma experimental ABIEncoderV2;

contract Test {

    struct Bar {
        uint a;
        uint b;
    }

    Bar public z;
    string public y;

    function foo(string s, Bar b) public {
        y = s;
    }

}

When I did contract.methods.foo("hello", { a: 1, b: 2 }).send({ from: '0x...' }), it gave me the following error:

Error: invalid number value (arg=undefined, type="undefined", value=undefined)
    at Object.throwError (/Users/mananmehta/Desktop/bar/node_modules/web3/packages/web3-eth-abi/node_modules/ethers/utils/errors.js:74:17)
    at Object.encode (/Users/mananmehta/Desktop/bar/node_modules/web3/packages/web3-eth-abi/node_modules/ethers/utils/abi-coder.js:68:24)
    at /Users/mananmehta/Desktop/bar/node_modules/web3/packages/web3-eth-abi/node_modules/ethers/utils/abi-coder.js:340:59
    at Array.forEach (<anonymous>)
    at pack (/Users/mananmehta/Desktop/bar/node_modules/web3/packages/web3-eth-abi/node_modules/ethers/utils/abi-coder.js:339:12)
    at Object.encode (/Users/mananmehta/Desktop/bar/node_modules/web3/packages/web3-eth-abi/node_modules/ethers/utils/abi-coder.js:521:20)
    at /Users/mananmehta/Desktop/bar/node_modules/web3/packages/web3-eth-abi/node_modules/ethers/utils/abi-coder.js:340:59
    at Array.forEach (<anonymous>)
    at pack (/Users/mananmehta/Desktop/bar/node_modules/web3/packages/web3-eth-abi/node_modules/ethers/utils/abi-coder.js:339:12)
    at Object.encode (/Users/mananmehta/Desktop/bar/node_modules/web3/packages/web3-eth-abi/node_modules/ethers/utils/abi-coder.js:521:20)
    at Coder.encode (/Users/mananmehta/Desktop/bar/node_modules/web3/packages/web3-eth-abi/node_modules/ethers/utils/abi-coder.js:661:62)
    at ABICoder.encodeParameters (/Users/mananmehta/Desktop/bar/node_modules/web3/packages/web3-eth-abi/src/index.js:103:27)
    at /Users/mananmehta/Desktop/bar/node_modules/web3/packages/web3-eth-contract/src/index.js:421:24
    at Array.map (<anonymous>)
    at Object._encodeMethodABI (/Users/mananmehta/Desktop/bar/node_modules/web3/packages/web3-eth-contract/src/index.js:420:12)
    at Object._processExecuteArguments (/Users/mananmehta/Desktop/bar/node_modules/web3/packages/web3-eth-contract/src/index.js:736:39)
    at Object._executeMethod (/Users/mananmehta/Desktop/bar/node_modules/web3/packages/web3-eth-contract/src/index.js:761:54)

but contract.methods.foo("hello", [ 1, 2 ]).send({ from: '0x...' }) goes through just fine. I am assuming this is the correct way of passing in tuples instead of using objects like { a: 1, b: 2 }.

@mehtamanan That is what my testing showed as well. This web3 supports tuples but you still have to flatten objects to array yourself.

@MoMannn So the order of the arguments in the tuple should match the order in which the struct parameters are declared?

@mehtamanan this method should help you transform objects to tuples. You can check tests here to se how you should use it.

@xpepermint Right on!

@mehtamanan I might sound stupid but how do you npm install ethereum/web3.js#newAbiLib ?
Also, my contract (obtained by artifacts.require(path);) does not contain any .methods.xxx objects ...

@Amxx In nodejs you include a GIT dependency as

"web3": "git+https://github.com/ethereum/web3.js.git#newAbiLib"

Based on artifacts.require I assume you are using truffle. You'll have to fork the truffle project to achieve that.

@Amxx Truffle is shipped with a web3 v0.20.1. You cannot use ethereum/web3.js#newAbiLib with truffle unless you fork truffle and update the dependencies. Regardless, it shouldn't be a major hurdle to work around it; you just won't be able to use truffle console and truffle tests till truffle updates their dependencies. If you're using truffle-contract on the client side or backend, just setProvider to be Web3.providers.HttpProvider and make sure you're using web3.js#newAbiLib version.

Hey guys, any ideas when this will be resolved and released? :)

+1

+1

+1

+1

+1

+1

+1

+1

Friendly reminder: since 2 years, we can use GitHub Reactions to express how we feel about something 🙂

https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/

The new ABICoder implementation is merged and this issue will be solved in the next release.

Any updates?

Hi, anything new ? When I'm here, it looks like the problem should be solved, but I still have the same message when I call a method that return a tuple array.

Any updates on this?
Can you suggest a workaround?

Faced the same isuue while trying to call a solidity function which returns dynamic array of structures , used the latest version of web3 which supports "pragma experimental ABIEncoderV2" of solidity

Could you please open an issue in the ethers.js repository? We use the ABICoder from there currently and just pass the data in. :-) @adityachap @gked

I'll update the ethers.js lib to the latest version on the next release. Maybe this will already solve it.

Ethers.js indeed already has a coder for tuples.

@nivida I'm confused. is this fixed in web3 or ethers.js? Is ethers.js a dependency of web3? I'm a little confused at how these projects interact

@nivida

The new ABICoder implementation is merged and this issue will be solved in the next release.

Which release was this? I'm using 0.18.4 but still having a problem

I am still running into issues while trying to generate java contract wrappers. I get the following error Unsupported type encountered: tuple , any update on progress of this? Or is there any branch i can switch to that has this working?

@araa47 did you happen to find a solution to this issue?

@chimpyTheDev can't remember correctly, but If I am not wrong I ended up using https://github.com/esaulpaugh/headlong

@araa47 I'll check it out, Thanks.

I see in many comments that web3 1.0 supports the solution to:
Uncaught (in promise) Error: invalid solidity type!: tuple[]
However I can't seem to find any documentation or implementation of the same, any lead anyone?

Was this page helpful?
0 / 5 - 0 ratings