Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error Calling contract method with nested array elements #583

Open
baptistapedro opened this issue Dec 4, 2024 · 9 comments
Open

Error Calling contract method with nested array elements #583

baptistapedro opened this issue Dec 4, 2024 · 9 comments

Comments

@baptistapedro
Copy link

Hi, I am trying to call myFunc which has this ABI:

{
      "inputs": [
        {
          "components": [
            {
              "internalType": "uint256[2]",
              "name": "a",
              "type": "uint256[2]"
            },
            {
              "internalType": "uint256[2][2]",
              "name": "b",
              "type": "uint256[2][2]"
            },
            {
              "internalType": "uint256[2]",
              "name": "c",
              "type": "uint256[2]"
            }
          ],
          "internalType": "struct Pwn5.Proof",
          "name": "proof",
          "type": "tuple"
        },
        {
          "internalType": "uint256[1]",
          "name": "publicSignals",
          "type": "uint256[1]"
        },
        {
          "internalType": "address",
          "name": "_myCoin",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "_myAmount",
          "type": "uint256"
        }
      ],
      "name": "myFunc",
      "outputs": [],
      "stateMutability": "payable",
      "type": "function"
    },
I have been trying to call it at such:
 const tx = await contract.myFunc([
 [calldata[0][0], calldata[0][1]], 
 [calldata[1][0], calldata[1][1]], 
 [calldata[2][0],calldata[2][1]]], 
 publicSignals, 
 jstHex, 
 _amount.toString() 
).send();

====error
Error: types/value length mismatch (argument="tuple", value=[["0x1a8ba9a57e8635b9293ebc48c559b8dff70c0c2e265e4aa04a525d6c7eeef345","0x13c356c3daaeb2dfcf45048e16eaf9583e899c6860fd1921691bf0a74abd310f"],[["0x27d554f65edba762c33dd033c0eda7af5194e0d7bc38c5b9e7689428569c3f78","0x1fb0f04c93debf46ae97991cdf0e275764a9b09f3f28b90391378421f222e759"],["0x166411e64431d452f6c443def2f43689814a65995a258b7ac6ebb6b7617e1be4","0x069e8ba613f95a5071c7f0ac047ec86ff062b9457a56f544b332b723ba0ef4b3"]],["0x2f3718e96e927fb600b08e45209853be4f29ff2b65af743558497a1326b1c4eb","0x1a39f79e888304437879c2d40315fc678178f5f4b4cbf80b35b0176c771748ac"]], code=INVALID_ARGUMENT, version=abi/5.7.0) at l.makeError (injected.js:1:316125) at l.throwError (injected.js:1:316245)

It seems to parse the calldata args alright but fails on publicSignals, etc?

Appreciate some feedback on this. Tks

@Satan-web3
Copy link
Contributor

Satan-web3 commented Dec 5, 2024

The second argument of the tuple argument should be a 2 dimension array but you only provided an 1 dimension array.

@baptistapedro
Copy link
Author

baptistapedro commented Dec 5, 2024

@Satan-web3 I changed it to:

a (2) ['0x286a51a8e54434234b2e59749fbb9b2b465034b88b9353e96181360062967fc3', 
'0x113f24a5e2e2485ab433eb50d147b7925b3f147aabab9b93932edbb608d6aa4e']

b (2) [Array(2), Array(2)]0: (2) ['0x083254bb42253499bb77fe4b6b23d3c29e15c4345735a8088b2f05b1f956c75d', 
'0x2fa58cbad762be8be337ec5392610ba2fd0db356cab444b3693fed3d603d52e6']

(2) ['0x068b3ef46ef5960fb8a51000fd72a159c23bdf307b42d41b3b5cb8f4ea23f4e5', 
'0x267b66d3034446d8a0b7e40580381ff33977ab47d2b616aa0ce6352d8ab570f1']

c (2) ['0x0abd667baa6fecc73043cec2037c35f1d551cd694313b7dee3b45aa5199367f4', 
'0x0afe313eea5ae4ddb2ea42dcf9ff3b40b3008a760756363cbd4666996b47ca7b']

 pubSignals ['18273616782692070165464484626328797446874384656626294920441909218184967909019']

Error creating bet: Error: types/value length mismatch (argument="tuple", value=[["0x286a51a8e54434234b2e59749fbb9b2b465034b88b9353e96181360062967fc3","0x113f24a5e2e2485ab433eb50d147b7925b3f147aabab9b93932edbb608d6aa4e"],[["0x083254bb42253499bb77fe4b6b23d3c29e15c4345735a8088b2f05b1f956c75d","0x2fa58cbad762be8be337ec5392610ba2fd0db356cab444b3693fed3d603d52e6"],["0x068b3ef46ef5960fb8a51000fd72a159c23bdf307b42d41b3b5cb8f4ea23f4e5","0x267b66d3034446d8a0b7e40580381ff33977ab47d2b616aa0ce6352d8ab570f1"]],["0x0abd667baa6fecc73043cec2037c35f1d551cd694313b7dee3b45aa5199367f4","0x0afe313eea5ae4ddb2ea42dcf9ff3b40b3008a760756363cbd4666996b47ca7b"]], code=INVALID_ARGUMENT, version=abi/5.7.0)
    at l.makeError (injected.js:1:316125)
    at l.throwError (injected.js:1:316245)
    at l.throwArgumentError (injected.js:1:316300)
    at u (injected.js:1:212306)
    at T.encode (injected.js:1:216848)
    at injected.js:1:212553
    at Array.forEach (<anonymous>)
    at u (injected.js:1:212423)
    at T.encode (injected.js:1:216848)

My current code is:

console.log('a', a)
console.log('b', b)
console.log('c', c)
console.log('pubSignals', publicSignals)

const tx = await contract.myFunc([
calldata[0],
[calldata[1][0], calldata[1][1]], 
calldata[2]],
calldata[3],
jstHex,
_amount.toString()
).send();

I was able to call the same func signature on eth evm with:

const _tu = {
        a: calldata[0],
        b: [calldata[1][0], calldata[1][1]],
        c: calldata[2],
      };
      const publicSignals = calldata[3];

myFunc(_tu, publicSignals);

Now it seems to parse a,b,c properly but not publicSignals.
@Satan-web3 -- mind giving it a try?

@Satan-web3
Copy link
Contributor

I tried to use utils.abi.encodeParamsV2ByABI to encode your data and it worked. Please recheck your code.

@baptistapedro
Copy link
Author

this is the actual code triggering the error, can you show what you did instead? Because I've rechecked it many times.

@Stan202310
Copy link

Your code pasted on this page is totally messed up. Can you upload your original code?

@baptistapedro
Copy link
Author

baptistapedro commented Dec 12, 2024 via email

@Stan202310
Copy link

I mean your code can't run directly, you must have edited for illustrate the problem. Here's my test code:

import { TronWeb, utils } from "tronweb";

const tronWeb = new TronWeb({
    fullHost: 'https://api.nileex.io',
});

console.log(utils.abi.encodeParamsV2ByABI(
    {
        "inputs": [
          {
            "components": [
              {
                "internalType": "uint256[2]",
                "name": "a",
                "type": "uint256[2]"
              },
              {
                "internalType": "uint256[2][2]",
                "name": "b",
                "type": "uint256[2][2]"
              },
              {
                "internalType": "uint256[2]",
                "name": "c",
                "type": "uint256[2]"
              }
            ],
            "internalType": "struct Pwn5.Proof",
            "name": "proof",
            "type": "tuple"
          },
          {
            "internalType": "uint256[1]",
            "name": "publicSignals",
            "type": "uint256[1]"
          },
          {
            "internalType": "address",
            "name": "_myCoin",
            "type": "address"
          },
          {
            "internalType": "uint256",
            "name": "_myAmount",
            "type": "uint256"
          }
        ],
        "name": "myFunc",
        "outputs": [],
        "stateMutability": "payable",
        "type": "function"
      },
      [
        [["0x286a51a8e54434234b2e59749fbb9b2b465034b88b9353e96181360062967fc3","0x113f24a5e2e2485ab433eb50d147b7925b3f147aabab9b93932edbb608d6aa4e"],[["0x083254bb42253499bb77fe4b6b23d3c29e15c4345735a8088b2f05b1f956c75d","0x2fa58cbad762be8be337ec5392610ba2fd0db356cab444b3693fed3d603d52e6"],["0x068b3ef46ef5960fb8a51000fd72a159c23bdf307b42d41b3b5cb8f4ea23f4e5","0x267b66d3034446d8a0b7e40580381ff33977ab47d2b616aa0ce6352d8ab570f1"]],["0x0abd667baa6fecc73043cec2037c35f1d551cd694313b7dee3b45aa5199367f4","0x0afe313eea5ae4ddb2ea42dcf9ff3b40b3008a760756363cbd4666996b47ca7b"]],
        ['18273616782692070165464484626328797446874384656626294920441909218184967909019'],
        'TS7pha3r3WzzBo95nY1Y9oL5ahVDFeB2Yh',
        1,
      ]
));

And it works. So please upload all your code so I can find out where the problem is.

@cfengliu
Copy link

cfengliu commented Dec 13, 2024

@Stan202310 hi ser, I am encountering a similar issue and cannot encode my parameters. Could you please review the following code?

Error

$ node scripts/swap.js
Error: Error: too many arguments: types/values length mismatch (count=2, expectedCount=0, code=UNEXPECTED_ARGUMENT, version=6.13.4)
    at makeError (/Users/me/Documents/workspaces/tron-deploy/node_modules/tronweb/node_modules/ethers/lib.commonjs/utils/errors.js:129:21)
    at assert (/Users/me/Documents/workspaces/tron-deploy/node_modules/tronweb/node_modules/ethers/lib.commonjs/utils/errors.js:149:15)
    at assertArgumentCount (/Users/me/Documents/workspaces/tron-deploy/node_modules/tronweb/node_modules/ethers/lib.commonjs/utils/errors.js:175:5)
    at AbiCoder.encode (/Users/me/Documents/workspaces/tron-deploy/node_modules/tronweb/node_modules/ethers/lib.commonjs/abi/abi-coder.js:166:44)
    at Object.encodeParamsV2ByABI (/Users/me/Documents/workspaces/tron-deploy/node_modules/tronweb/lib/commonjs/utils/abi.js:137:21)
    at main (/Users/me/Documents/workspaces/tron-deploy/scripts/swap.js:148:41)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  code: 'UNEXPECTED_ARGUMENT',
  count: 2,
  expectedCount: 0,
  shortMessage: 'too many arguments: types/values length mismatch'
}

Code

const { TronWeb, utils: TronWebUtils, Trx, TransactionBuilder, Contract, Event, Plugin } = require('tronweb');

const privateKey = 'PRIVATE_KEY';

const tronWeb = new TronWeb({
  fullHost: 'https://api.trongrid.io',
  privateKey: privateKey
})

const fromAddress = tronWeb.address.fromPrivateKey(privateKey);
console.log('fromAddress:', fromAddress);

const abi = [{
  "inputs": [
    {
      "internalType": "struct IRouter.SwapExactInParams",
      "name": "params",
      "type": "tuple",
      "components": [
        {
          "internalType": "address[]",
          "name": "path",
          "type": "address[]"
        },
        {
          "internalType": "uint256",
          "name": "amountIn",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "v2AmountRatio",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "v3AmountRatio",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "v2AmountOutMin",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "v3AmountOutMin",
          "type": "uint256"
        },
        {
          "internalType": "uint24[]",
          "name": "v3Fees",
          "type": "uint24[]"
        },
        {
          "internalType": "address",
          "name": "to",
          "type": "address"
        },
        {
          "internalType": "uint256",
          "name": "deadline",
          "type": "uint256"
        }
      ]
    },
    {
      "internalType": "uint256",
      "name": "routerFeeRate",
      "type": "uint256"
    }
  ],
  "stateMutability": "payable",
  "type": "function",
  "name": "swapExactIn",
  "outputs": [
    {
      "internalType": "uint256",
      "name": "v2AmountOut",
      "type": "uint256"
    },
    {
      "internalType": "uint256",
      "name": "v3AmountOut",
      "type": "uint256"
    }
  ]
},    {
  "inputs": [],
  "name": "v3Router",
  "outputs": [
    {
      "internalType": "address",
      "name": "",
      "type": "address"
    }
  ],
  "stateMutability": "view",
  "type": "function"
}]

const contractAddress = 'CONTRACT_ADDRESS';

const main = async () => {
  try {
    const contract = await tronWeb.contract(abi, contractAddress);

    const params = {
      path: [
        "TNUC9Qb1rRpS5CbWLmNMxXBjyFoydXjWFR",
        "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"
      ],
      amountIn: "10000",
      v2AmountRatio: "0",
      v3AmountRatio: "100000",
      v2AmountOutMin: "0",
      v3AmountOutMin: "0",
      v3Fees: ["3000"],
      to: "TO_ADDRESS",
      deadline: (Math.floor(Date.now() / 1000) + 60 * 20).toString()
    };

    const routerFeeRate = "100";

    const args = [
      [
        [
          "TNUC9Qb1rRpS5CbWLmNMxXBjyFoydXjWFR",
          "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"
        ],
        params.amountIn,
        params.v2AmountRatio,
        params.v3AmountRatio,
        params.v2AmountOutMin,
        params.v3AmountOutMin,
        [
          3000
        ],
        params.to,
        params.deadline
      ], 
      routerFeeRate
    ];

    const parameter = tronWeb.utils.abi.encodeParamsV2ByABI(abi, args);
    console.log('parameter:', parameter);

    const tx = await tronWeb.transactionBuilder.triggerSmartContract(
      contractAddress,
      functionSelector,
      {},
      parameter
    );

    const signedTx = await tronWeb.trx.sign(tx.transaction);

    const result = await tronWeb.trx.sendRawTransaction(signedTx);

    console.log('Transaction result:', result);

  } catch (error) {
    console.error('Error:', error);
    if (error.error) {
      console.error('Details:', JSON.stringify(error.error, null, 2));
    }
  }
}

main().catch(console.error);

@Stan202310
Copy link

const parameter = tronWeb.utils.abi.encodeParamsV2ByABI(abi, args);

This line should be like below:

const parameter = tronWeb.utils.abi.encodeParamsV2ByABI(abi[0], args);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants