[solved] Issues with web3.js calling a contract function with node

Hi everybody,
I’m trying to call a funcion by node, a mint function on my NFT smart contract
I want it mints a new NFT and assign it to the user address that makes the request
This is my contract function

function assign(string calldata tokenURI, bytes calldata bytesId) public {
        uint256 _tokenId = abi.decode(bytesId, (uint256));
        _mint(msg.sender, _tokenId);
        _setTokenURI(_tokenId, tokenURI);
        emit Assigned(_tokenId, msg.sender, bytesId);
    }

This is my node function

const web3 = new Web3(new Web3.providers.HttpProvider(
    "https://rpc.ankr.com/polygon_mumbai"
  ));

  Contract.setProvider("https://rpc.ankr.com/polygon_mumbai");
  const contract = new Contract(CONTRACT_NFT_ABI, CONTRACT_NFT_ADDRESS, {
    from: userAddress
  });
  
  const encoded = contract.methods.assign(tokenURI, plotID).encodeABI();
  const block = await web3.eth.getBlock("latest");
  const gasLimit = Math.round(block.gasLimit / block.transactions.length);
  
  const tx = {
    from: userAddress,
    gas: gasLimit,
    to: CONTRACT_NFT_ADDRESS,
    data: encoded
  }

  await web3.eth.accounts.signTransaction(tx, PRIVATE_KEY)
    .then(signed => {
      web3.eth.sendSignedTransaction(signed.rawTransaction, function(error, transactionHash){
      if (transactionHash){
        res.status(200).send({
          res: "OK",
          msg: transactionHash
        });              
      }
      if (error) {
        res.status(400).send({
          res: "KO",
          msg: error
        });             
      }
    })}).catch((err) => {
      res.status(400).send({
        res: "KO",
        msg: err
      });      
    });```
If I call this function I get a transaction and the NFT is sent to the PRIVATE_KEY’s address and not the userAddress, so not what I want

If I use contract.methods.assign(tokenURI, plotID).send({from: userAddress}) I get “unknown account” error

How can I do?

Thanks

this function mints the token id for the msg.sender that is the account that makes the transaction
you should add another parameter as the user address and mint the nft for that address:

=>

that could be a possible solution if you want to make the transaction in backend and not the user in front end

Hi Cryptokid, I wouldn’t change the contract, but if it’s the only way…

function assign(string calldata tokenURI, bytes calldata bytesId, address userAddress) public {
        uint256 _tokenId = abi.decode(bytesId, (uint256));
        _mint(userAddress, _tokenId);
        _setTokenURI(_tokenId, tokenURI);
        emit Assigned(_tokenId, userAddress, bytesId);
    }

I’ll change this function this way so I can pass the userAddress among the function parameters!

I’ll try and let you know!
Thanks for now

1 Like

Adding userAddress parameter gives me a couple of warnings on Remix Ide when compiling and Internal JSON-RPC error when deploying
I’m using openzeppeling contracts as base for mine
Any other suggestion??

the other suggestion would be to make the mint in front end, if you don’t have to necessarily make it in backend, or to make a transfer after you did the mint to a specific address, that will require another transaction to do that transfer

At the end I moved the mint function to frontend, used the contract.method function and this solved the issue
Thanks cryptokid for your suggestion and time

2 Likes