0

I'm having some problem with the arguments of a function written in solidity and called in JavaScript. I'm using the Remix ballot default example, except I removed the first require in it. It looks like this:

function giveRightToVote(address voter) public {
require(
    !voters[voter].voted,
    "The voter already voted."
);
require(voters[voter].weight == 0);
voters[voter].weight = 1;}

As far as I'm understanding, I should give it an address so it can give permission to that address. This is the JavaScript code that calls that function:

const permission = async () => {
    const ethereumAddress = web3.utils.toChecksumAddress(account);
    const gasEstimate = await window.contract.methods.giveRightToVote([ethereumAddress]).estimateGas({ from: account });
    console.log("1");
    const result = await window.contract.methods.giveRightToVote(account).send({ gas: gasEstimate, from: account});
    document.getElementById("permissionArea").innerHTML = "Permiso para votar obtenido";
    /**
    await window.contract.methods.giveRightToVote(account).send({ from: account });
    document.getElementById("permissionArea").innerHTML = "Permiso para votar obtenido";
    */
}

The last commented part was the original code. I have changed it a lot trying to make it work. I kind of guess the problem is the argument account. I have tried using [account] which has worked in another function, but I seem to not be able to figure out how it wants the parameters. I know the account is right, I get it like this:

const accounts = await ethereum.request({method: "eth_requestAccounts"});
account = accounts[0];

And when I print it it's the right address. The full error reads:

Error: types/value length mismatch (argument="tuple", value=["0x40bCba26F1ED151Fa34232E3CFf55d9C2867bCf1"], code=INVALID_ARGUMENT, version=abi/5.7.0)

This is not the only function that shows this same problem, in fact, I can't send any argument to the solidity functions. I have this vote function that only requires a integer (uint) as an argument. If I just send 0 for example it gives me the error I just addressed. But if I make a javascript Uint8Array and send the complete array like this:

let numero = new Uint8Array(1);
numero[0]=selectedCandidate;
const gasEstimate = await window.contract.methods.vote(numero).estimateGas({ from: account });
await window.contract.methods.vote(numero).send({ gas: gasEstimate, from: account });

It shows a different error:

MetaMask - RPC Error: Internal JSON-RPC error. {code: -32603, message: 'Internal JSON-RPC error.', data: {…}}                inpage.js:1

And

Uncaught (in promise) Error: Internal JSON-RPC error.                             web3.min.js:2
{
  "message": "VM Exception while processing transaction: revert",
  "stack": "RuntimeError: VM Exception while processing transaction: revert\n    at exactimate (C:\\Users\\pc\\AppData\\Local\\Programs\\Ganache\\resources\\static\\node\\node_modules\\ganache\\dist\\node\\1.js:2:182136)",
  "code": -32000,
  "name": "RuntimeError",
  "data": {
    "hash": null,
    "programCounter": 130,
    "result": "0x",
    "reason": null,
    "message": "revert"
  }
}

I'm still confused that it wants a tuple when the smart contract only takes one argument; any idea what problem I just run into?

1 Answer 1

0

The issue seems to be related to passing the argument to the giveRightToVote function. The error message suggests that the value being passed as an argument is of the wrong type or length, and that it is expected to be a tuple.

Based on the Solidity code you provided, the giveRightToVote function takes a single address parameter, which is of the address type. Therefore, you should not be passing an array as an argument to the function, as you are currently doing.

Instead, you should be passing the Ethereum address of the voter as a string, without brackets, directly as the argument to the function.

Therefore, try changing this line of your JavaScript code:

const result = await window.contract.methods.giveRightToVote(account).send({ gas: gasEstimate, from: account});

to:

const result = await window.contract.methods.giveRightToVote(ethereumAddress).send({ gas: gasEstimate, from: account});

This should pass the Ethereum address as a string, which is what the Solidity function is expecting.

For the vote function, you are creating a Uint8Array of length 1 to pass as an argument. This is correct. However, the error message suggests that the transaction is failing because of a revert operation in the Solidity code. Without seeing the full Solidity code, it's hard to say exactly what the issue might be, but it's possible that there is a logic error in the contract code that is causing the function to revert when it is called.

check it, do some changes to these points and see if the issue solves

1
  • I'm sorry I upload the new version of my code. I first used 'ethereumAddress' as it is, and I have been changing it to try to send it. const result = await window.contract.methods.giveRightToVote(ethereumAddress).send({ gas: gasEstimate, from: account}); gives the same error as [etherumAddress]. This is the complete code if it helps, the smart contract is called smartcontract.sol; the rest are for me to save other things: github.com/Marcos-Molina-R/Blockchain-Voting-System
    – marcos
    Commented May 2, 2023 at 18:59

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.