web3 icon indicating copy to clipboard operation
web3 copied to clipboard

web3 can't work with abitype Tuple

Open devedse opened this issue 2 years ago • 5 comments

I'm currently working on a SmartContract that has the following method:

struct Color {
    uint8 R;
    uint8 G;
    uint8 B;
}

function create(uint index, Color calldata backgroundColor, Color calldata textColor, uint number) {
    ....
}

I tried calling this function however web3 shows the following error:

> web3 contract call --address xxxxxx --abi Test.abi --function create 1 "[100, 12, 200]" "[50, 100, 10]" 1
ERROR: Error calling contract: unsupported input type (uint8,uint8,uint8)

devedse avatar Apr 17 '22 01:04 devedse

I haven't used structs, but maybe try setting the experimental flag and passing in the struct name with the parameters like here: https://ethereum.stackexchange.com/questions/65980/passing-struct-as-an-argument-in-call

treeder avatar Apr 17 '22 22:04 treeder

Could you maybe provide an example of what you mean? I had already included the pragma abiencoderv2 in my smart contact

devedse avatar Apr 18 '22 00:04 devedse

I was thinking something like it has in that stackoverflow: "SetStruct((int256,int256))" instead of an array like you're using "[100, 12, 200]". I have no idea if that will work, but worth a test.

treeder avatar Apr 18 '22 21:04 treeder

Ok I'm still not sure what you mean exactly. Here's what I have now:

pragma solidity >=0.4.22 <0.9.0;

contract Test {

    struct Color {
        uint8 R;
        uint8 G;
        uint8 B;
    }

    function create(uint lockIndex, Color calldata backgroundColor) public {

    }
}

With abi:

[
	{
		"inputs": [
			{
				"internalType": "uint256",
				"name": "lockIndex",
				"type": "uint256"
			},
			{
				"components": [
					{
						"internalType": "uint8",
						"name": "R",
						"type": "uint8"
					},
					{
						"internalType": "uint8",
						"name": "G",
						"type": "uint8"
					},
					{
						"internalType": "uint8",
						"name": "B",
						"type": "uint8"
					}
				],
				"internalType": "struct Test.Color",
				"name": "backgroundColor",
				"type": "tuple"
			}
		],
		"name": "create",
		"outputs": [],
		"stateMutability": "nonpayable",
		"type": "function"
	}
]

I deployed this to here: https://ropsten.etherscan.io/address/0x45cd215365cdf384ea65a65927501e6a40571266#code

And I'm calling this by doing:

web3 contract call --address 0xa9637b51e5b413e4C9D35E2663eB748396Df79a9 --abi Test.abi --function create 3 "SetStruct((int256,int256,int256))"

Which results in the following error:

ERROR: Error calling contract: unsupported input type (uint8,uint8,uint8)

From Etherscan I can do the following which works: image Working transaction: https://ropsten.etherscan.io/tx/0x900c1805dac74134dba0284b96656131eeeb13a97b08ff1ddb69d182e8ac9d48

devedse avatar Apr 18 '22 23:04 devedse

I have since written my own Web3Cli to basically be able to pass structs to a constructor of a smart contract or a function. So if anyone is looking for this feel free to check out my tool: https://github.com/devedse/DeveWeb3Cli

For this library it could be useful as a first idea too.

devedse avatar Apr 24 '22 16:04 devedse