Miller42
Miller42

Reputation: 55

How to extract results of a Solidity payable transaction in React front-end using ethers.js?

I have a Solidity smart contract function that returns 3 variables upon transaction completion, matchednumbers, roll, winnings.

    function createTicket() external payable returns (uint _matchednumbers, uint[10] memory _generatednumbers, uint _winnings) {
        generateNumbers();
        uint[10] memory roll = getGenerateNumbers();
        uint matchednumbers;
        uint winnings;
    
             for(uint i = 0; i < 10; i++) {
                 for (uint j = 0; j < 10; j++) {
            if (arrays[msg.sender][i] == roll[j]) {
                matchednumbers +=1;
            }
                 }
        if (matchednumbers == 5) {
            winnings = msg.value * 5;    // msg.value is amount of wei (ether / 1e18), winnings is returning wei, winnings is being saved to next roll after win, need to fix!
        }
         if (matchednumbers == 6) {
            winnings = msg.value * 24;
        }
         if (matchednumbers == 7) {
            winnings  = msg.value * 142;
        }
         if (matchednumbers == 8) {
            winnings  = msg.value * 1000;
        }
          if (matchednumbers == 9) {
            winnings  = msg.value * 4500;
        }
          if (matchednumbers == 10) {
            winnings  = msg.value * 10000;
       }            
      }
      return  (matchednumbers, roll, winnings);
    }

I'm trying to render the results of the transaction, the matchednumbers (just an int), the roll (an array of numbers) and winnings (another int) in my front-end in React after the transaction has been completed. Just need sure how to do this? Or if it's possible with a external, payable Solidity function. In my App.js I have this:

  async function roll() {
    if (typeof window.ethereum !== "undefined") {
      await requestAccount();
      const provider = new ethers.providers.Web3Provider(window.ethereum);
      const signer = provider.getSigner();
      const contract = new ethers.Contract(keno3Address, Keno3.abi, signer);
      // const transaction = await contract.deposit({ value: ethers.utils.parseEther("6") })
      try {
        const data = await contract.createTicket(); // createTicket()
        await data.wait();
        console.log("data: ", data);
        const result = ethers.iface.decodeFunctionData("transferFrom", data);
        return data
      } catch (err) {
        console.log("Error: ", err);
      }
    }
  }

It's returning data of the transaction in the console.log but I cannot see the outcome of those variables, which I do see in Remix if I run it there. Or do I need to decode the transaction? I also tried that but it didn't work as you see.

Upvotes: 1

Views: 1944

Answers (1)

Ahmad Gorji
Ahmad Gorji

Reputation: 424

Uints returned from contract are in BigNumber type (read more about BigNumber here)

so data should log in console something like this:

(3) [BigNumber, Array(6), BigNumber]

Also data[0] = BigNumber{_hex: "0xfe", _isBigNumber: true} and maybe data[1] = [1,2,3,...,9,10] and data[3] = BigNumber{_hex: "0xfe", _isBigNumber: true}. Note that your result is completely different from results I wrote and they are just examples.

to change BigNumber to Number you can use function toNumber() simply adding to BigNumber.

let matchedNumbers = data[0].toNumber();
let generatedNumbers = data[1]; //this is array type, not BigNumber!
let winnings = data[2]

Upvotes: 2

Related Questions