Search code examples
javascriptethereumweb3js

Calling solidity smart contract with javascript to mint token does not seem to work


I have a newby ethereum question--just getting started and trying to understand the Ethereum dev environment.

I have a very simple 721 test contract that I deployed to Ropsten and I can use REMIX to use it and it works to mint and to view balance of tokens (tokenCounter) etc.

Here is the 'contract' : https://ropsten.etherscan.io/address/0x97E0175415cB7D758cFB0ffc27Be727360664B90

// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;
 
import "@0xcert/ethereum-erc721/src/contracts/tokens/nf-token-metadata.sol";
import "@0xcert/ethereum-erc721/src/contracts/ownership/ownable.sol";

contract Icollect is NFTokenMetadata, Ownable {
 
 uint256 public tokenCounter;

  constructor() NFTokenMetadata () {
    nftName = "Icollect";
    nftSymbol = "ICOL";
    tokenCounter = 0;
  }
 
  function mint(string calldata _uri) external onlyOwner {
    super._mint(msg.sender, tokenCounter);
    super._setTokenUri(tokenCounter, _uri);
    tokenCounter = tokenCounter + 1;
  }
}

The contract seems to work for minting tokens when I test locally with this test javascript and hardhat

async function main() {

    const contract_address = "0x5FbDB2315678afecb367f032d93F642f64180aa3";      
    const Icollect = await ethers.getContractFactory("Icollect");
    const icollect = await Icollect.attach(contract_address);

    const mint_return = await icollect.mint("https://test.test");    
    console.log("mint returned: ", mint_return);
    
    console.log("owner:", await icollect.owner());
    console.log("owner:", await icollect.ownerOf(0)); 
    console.log("symbol:", await icollect.symbol());
    console.log("URI:", await icollect.tokenURI(0));
    console.log("token counter:", await icollect.tokenCounter());    
  }
  
  main()
    .then(() => process.exit(0))
    .catch(error => {
      console.error(error);
      process.exit(1);
    });
    

The PROBLEM: When I try to mint a token from a web page I can't seem to get the 'mint' transaction to work (when I need gas). However, viewing variables works (like name and owner of contract). Any idea what I'm doing wrong here.

const transaction = contract.methods.mint(NFT_URI);

I'm building the object, then signing it and then sending it. The transaction seems to work but I don't see the additional token.

Here is one of the example 'mint' transaction using code below: https://ropsten.etherscan.io/tx/0x6f3fc389355ffedfe135ac049837ac2d1a6eb6aad1dd10b055addfa70814e0fd But using REMIX to query 'tokenCounter' shows that I never increase the count.

document.getElementById('mintbutton').onclick = async function() {
        let NFT_URI = document.getElementById("nft_uri").value;                                            
        let contract_address = document.getElementById("contract_address").value;                                            
        const contract = await new web3.eth.Contract(abi, contract_address);  
        let account_address = document.getElementById("account_address").value;  
        const account = web3.eth.accounts.privateKeyToAccount(privateKey).address;        
        const transaction = contract.methods.mint(NFT_URI);
        let nonce_count = await web3.eth.getTransactionCount(account_address);        

        //build the transaction            
        const txObject = {
            nonce: nonce_count, 
            to: account_address,
            //value: web3.utils.toHex(21000),
            //gasLimit: web3.utils.toHex(1000000),
            gasPrice: web3.utils.toHex(web3.utils.toWei('10','gwei')),            
            gas: await transaction.estimateGas({from: account}),
            data: transaction.encodeABI()
        };

        const signed  = await web3.eth.accounts.signTransaction(txObject, privateKey);        
        const return_from_send = await web3.eth.sendSignedTransaction(signed.rawTransaction);
                        
        return_string = 
            "blockHash: " + return_from_send.blockHash + "<br>" +
            "blockNumber: <a href='https://ropsten.etherscan.io/block/"  + return_from_send.blockNumber + "'>" + return_from_send.blockNumber + "</a><br>" +
            "contractAddress: " + return_from_send.contractAddress + "<br>" +
            "cumulativeGasUsed: " + return_from_send.cumulativeGasUsed + "<br>" +            
            "from: <a href='https://ropsten.etherscan.io/address/" + return_from_send.from  + "'>" + return_from_send.from + "</a><br>" +
            "gasUsed: " + return_from_send.gasUsed + "<br>" +
            "status: " + return_from_send.status + "<br>" +
            "to:  <a href='https://ropsten.etherscan.io/address/" + return_from_send.to + "'>" + return_from_send.to + "</a><br>" +
            "transactionHash: <a href='https://ropsten.etherscan.io/tx/" + return_from_send.transactionHash + "'>" + return_from_send.transactionHash + "</a><br>" +
            "transactionIndex: " + return_from_send.transactionIndex + "<br>" +
            "type: " + return_from_send.type + "<br>"; 

        $('#mint_return').html(return_string);            
        
        var x = document.getElementById("showDIV3");        
        x.style.display = "block";

    }

Here is a link to the console.log https://i.sstatic.net/k7hcv.jpg


Solution

  • I had the wrong address in the transaction object. I had the account address and not the contract address. Correction below.

    //build the transaction            
        const txObject = {
            nonce: nonce_count, 
            to: contract_address, //NOT account_address,
            //value: web3.utils.toHex(21000),
            //gasLimit: web3.utils.toHex(1000000),
            gasPrice: web3.utils.toHex(web3.utils.toWei('10','gwei')),            
            gas: await transaction.estimateGas({from: account}),
            data: transaction.encodeABI()
        };