Search code examples
javascriptethereumsoliditymetamaskethers.js

Retrieving Solidity Event Data with Ethers.js


I'm new to Solidity and Ethers.js, so if there are any amateurish mistakes, that would be why.

I'm trying to build a dApp that runs a function on my smart contract, retrieves the data that is emitted from the event, and then displays it on my front-end. I've gotten it to run on Localhost so far. Currently, MetaMask connects to my front-end, but it throws an error when I try to confirm a transaction with the contract.

Create Function (JS):

    async function create() {
        ///Acquiring values
        postBody = document.getElementById("in-1-pbd").value;
        postSubcat = document.getElementById("in-2-sc").value;
        console.log(postBody + ", " + postSubcat);
        ///Connecting with Ethereum
        await requestAccount()
        if (typeof window.ethereum != 'undefined') {
          const provider = new ethers.providers.Web3Provider(window.ethereum);
          const signer = provider.getSigner();
          const contract = new ethers.Contract(blokracyAddress, Blokracy.abi, signer)
          const transaction = await contract.createBallot(postSubcat, postBody)
          await transaction.wait()
        ///Building and presenting the ballot
        contract.on("Creation", (message, idnum ) => {
          console.log("Creation Event Data: ", message, idnum);
          buildBallot(Wallet.publicKey, idnum, postBody);
          });
        } else {
          window.alert("Non-Ethereum browser detected. You should consider installing MetaMask.")
        }
      }

Request Account Function:

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

Create Function (Solidity):

///Event Declaration
    event Creation(string message, uint idnum);
///Functionality
///Creating a Ballot:
    function createBallot(
        string memory _subcategory, string memory _post
    ) public {

        ///Set Operator
        operator = msg.sender;

        ///Increment ballotNum
        ballotNum ++;

        ///Apply specifics to ballot
        ballot[ballotNum] = Ballot(
            ballotNum, _subcategory, operator,
            _post, 0, 0, 0, 0
        );

        ///return string and ballotNum
        emit Creation("Ballot was successfully posted!", ballotNum);
        
    }

Any insight would be amazing. Like I said, I'm new and trying to learn as much as I can about dApps by building this project.


Solution

  • You can try this approach for calling function of smart contract in front-end with the help of web3.

    const web3 = new Web3(sNetworkRPCURL);
    const oDefaultWeb3 = new Web3(window.ethereum);
    let oContractObject;
    let sWalletAddress;
    
    async function metamaskConnection(){
        const aReqAccount = await window.ethereum.request({
            method: "eth_requestAccounts",
        });
        sWalletAddress=aReqAccount[0];
    
    }
    async function create() {
            ///Acquiring values
            postBody = document.getElementById("in-1-pbd").value;
            postSubcat = document.getElementById("in-2-sc").value;
            console.log(postBody + ", " + postSubcat);
            ///Connecting with Ethereum
    
            if(typeof window.ethereum=="undefined"){
                console.log("METAMASK IS NOT FOUND");
                return;
            }
    
            oContractObject = new web3.eth.Contract(aContractABI,sContractAddress);
            let oNewContractObject = new oDefaultWeb3.eth.Contract(aContractABI,sContractAddress);
    
           
            let estimatedGas;      
        
            try {
                estimatedGas = await oNewContractObject.methods
                    .createBallot(postSubcat, postBody)
                    .estimateGas({
                        from: sWalletAddress                    
                    });
        
                console.log("Estimated Gas: ", estimatedGas);
            } catch (error){          
        
                console.log(error);   
        
                return;
            }
            try {
                await oNewContractObject.methods
                    .createBallot(postSubcat, postBody)
                    .send({
                        from: sWalletAddress,                   
                        gas: estimatedGas,
                    })
                    .on("transactionHash", (txHash) => {
                        console.log("Transaction Hash: ", txHash);                    
                    })
                    .on("receipt", async (txReceipt) => {
                        console.log("Receipt: ", txReceipt);   
                       
                    })
                    .catch("error", (err) => {
                        console.error(err);
                        
                    });
            } catch (err) {
                console.error(err);
               
            }
        }
    

    And I want just clarification on web3 object and oDefaultWeb3 objects which I have taken in my code. fist web3 object I will use it for view or call() methods. And other one is useful for send() methods.

    So, Now I hope this approach will helpful for you to developing dApps and many more.