2

I am calling smart contract function in Solidity from React, which should count the votes for the specific choices. The function works perfectly when I call it from my truffle console. However, when I call it from React application, the function is executed but votes are not counted.

function:

 function doVote(uint _choice)
        public
        inState(State.Voting)
        returns(bool voted)
    {
        bool found = false;        
        
        if(!voterRegister[msg.sender].voted ){
            voterRegister[msg.sender].voted = true;
            vote memory v;
            v.voterAddress = msg.sender;
            v.choice = _choice;

            
            candidatesRegister[_choice].votes++  ;
            
            votes[totalVote] = v;
            totalVote++;
            found = true;
        }
        return found;        
    }

in truffle console, this works:

> ballot = await Ballot.deployed()
> ballot.doVote(1)

In React I have this function where the address represents the public key of a user being logged in to the application:

export const doVote = async (choice, address)=> {
 

    web3.eth.defaultAccount = address;
    console.log("network: " + Contract.networks[networkID].address)
    const BallotContract = new web3.eth.Contract(Contract.abi, Contract.networks[networkID].address);       

    return await BallotContract.methods
    .doVote(choice)

};

if I add .call() to .doVote(choice) function will return "true"

2 Answers 2

1

This solution is with ethers assuming that you have metamask in your browser:

I also used react, I stored the contract abi in a json as well as the address

import smartContract from './smart-contract-abi.json';
import contractAddress from './contract-address.json';
import { ethers } from 'ethers';

// step 1 - Connect wallet

await window.ethereum.request({method: 'eth_requestAccounts'});

// step 2 - Initialize your contract

    this.provider = new ethers.providers.Web3Provider(window.ethereum);
    this.yourSignedContractObject = new ethers.Contract(
      contractAddress.Address, 
      smartContract.Abi,
      this.provider.getSigner(0)
    );

// step 3 - Submit transaction to metamask

    const tx = await this.yourSignedContractObject.doVote(yourChoice)

Source: (check the typescript PR) https://github.com/NomicFoundation/hardhat-boilerplate

1

When you are doing .call(), the blockchain's state is not altered. According to the web3 docs:

methods.myMethod.call

Will call a “constant” method and execute its smart contract method in the EVM without sending any transaction. Note calling cannot alter the smart contract state.

Call is useful for simulating a transaction and getting its return value, which you got as "true", but because the blockchain's state isn't changed, your votes aren't counted.

What you really want to do is use .send()

methods.myMethod.send
Will send a transaction to the smart contract and execute its method. Note this can alter the smart contract state.

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.