0

How to encode an object with ABIEncoder V2?

For example, this one:

{
  items: [
    {  
      str: "str",
      num: 5,
      bol: true
    }
  ]
}

Solidity struct:

struct Item {
  string str;
  uint   num;
  bool   bol;
}

struct Arg {
  Item[] items;
}
3
  • Neither one of these (str, num and bol) is a valid type in Solidity. I sincerely doubt that this object can be encoded. Jan 15, 2020 at 16:53
  • @goodvibration these are keys, not types
    – warchantua
    Jan 15, 2020 at 17:16
  • Yes, but those keys should be representing Solidity types (i.e., the types of your variables rather than the names of your variables). Jan 15, 2020 at 17:25

1 Answer 1

2

See the example below

Warning from Remix: Experimental features are turned on. Do not use experimental features on live deployments.

pragma solidity ^0.5.12;
// Enable the ABI v2 Coder
pragma experimental ABIEncoderV2;

contract AbiTwoTest {

    struct Item {
        string str;
        uint   num;
        bool   bol;
    }

    struct Arg {
        Item[] items;
    }

    mapping (address => Arg) itemsByUser;

    // User struct in the event
    event ItemAdded(string indexed str, uint num, bool bol);

    // User struct in the method signature
    function addItem(Item memory _item) public {
        itemsByUser[msg.sender].items.push(_item);
        emit ItemAdded(_item.str, _item.num, _item.bol);
    }

    // User struct in the returns
    function item(address addr) public view returns (Arg memory items) {
        return itemsByUser[addr];
    }
}

Remix Testing

Add Item enter image description here

Read Item enter image description here

Contract ABI

[
    {
        "constant": false,
        "inputs": [
            {
                "components": [
                    {
                        "internalType": "string",
                        "name": "str",
                        "type": "string"
                    },
                    {
                        "internalType": "uint256",
                        "name": "num",
                        "type": "uint256"
                    },
                    {
                        "internalType": "bool",
                        "name": "bol",
                        "type": "bool"
                    }
                ],
                "internalType": "struct AbiTwoTest.Item",
                "name": "_item",
                "type": "tuple"
            }
        ],
        "name": "addItem",
        "outputs": [],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "anonymous": false,
        "inputs": [
            {
                "indexed": true,
                "internalType": "string",
                "name": "str",
                "type": "string"
            },
            {
                "indexed": false,
                "internalType": "uint256",
                "name": "num",
                "type": "uint256"
            },
            {
                "indexed": false,
                "internalType": "bool",
                "name": "bol",
                "type": "bool"
            }
        ],
        "name": "ItemAdded",
        "type": "event"
    },
    {
        "constant": true,
        "inputs": [
            {
                "internalType": "address",
                "name": "addr",
                "type": "address"
            }
        ],
        "name": "item",
        "outputs": [
            {
                "components": [
                    {
                        "components": [
                            {
                                "internalType": "string",
                                "name": "str",
                                "type": "string"
                            },
                            {
                                "internalType": "uint256",
                                "name": "num",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bool",
                                "name": "bol",
                                "type": "bool"
                            }
                        ],
                        "internalType": "struct AbiTwoTest.Item[]",
                        "name": "items",
                        "type": "tuple[]"
                    }
                ],
                "internalType": "struct AbiTwoTest.Arg",
                "name": "items",
                "type": "tuple"
            }
        ],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    }
]
3
  • Is there a way to automatically encode arbitrary object into a tuple?
    – warchantua
    Jan 15, 2020 at 22:17
  • I based my answer off of this link. ethers.js seems to automatically encode the provided json object when it creates and sends the transaction. blog.ricmoo.com/… would this do what you are looking for?
    – Steven V
    Jan 15, 2020 at 22:41
  • 2
    Wow. Solidity v0.8.0 has JUST BEEN RELEASED WITH ABI coder v2 activated by default!!!
    – Russo
    Dec 24, 2020 at 10:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.