MetaMask – Troubleshooting Transfer() Method Errors in Web3 for Smart Contract Wallets

metamasksmart-contract-walletstransfer

I tried to make a button on we3 when click on it, the transfer method should start after 5 minutes.
when I click my button first of all metamask show me this

enter image description here
when I click on try it anywhay this error appear to me
enter image description here

my solidity code:

address payable public tenant = payable(0x6eC9Ce7Db83035a69e60d2407e5d5fcc1e6411A6);
address payable public landlord = payable(0x16125Aa47cc309988Cf774d8001b614527203A4E);

uint256 public lastRun;

function myFunction() payable public {
    require(block.timestamp - lastRun > 5 minutes, 'Need to wait 5 minutes');
    //require(msg.value == rent, "Please pay the proper rent.");
    landlord.transfer(1);

    lastRun = block.timestamp;
}

My App.js code:

import React, { Component }  from 'react';
import detectEthereumProvider from '@metamask/detect-provider';
import Web3 from 'web3';
import './App.css';
import { useEffect } from 'react';
import { useState } from 'react';


function App() {
  const [web3Api,setWeb3Api]= useState({
    provider:null,
    web3:null,
  })

  useEffect( ()=>{
      const loadProvider = async()=>{
      const provider = await detectEthereumProvider();

      if(provider){
        setWeb3Api({
          provider,
          web3:new Web3(provider)
        })
       console.log(provider);
      } else {
        window.alert("Please install Metamask");
      }
    }
  loadProvider()},[])

  const [account, setAccount] = useState(null)
  useEffect( ()=>{
    const loadAccounts = async ()=>{
    const accounts = await web3Api.web3.eth.getAccounts()
    console.log(accounts);
    setAccount(accounts[0])
    }
    web3Api.web3 && loadAccounts()
  },[web3Api.web3])

    //Load Contract
    const [contract, setContract] = useState()
    useEffect(()=>{
      const loadContract = async()=>{
      const contractFile = await fetch('/abis/Properties.json');
      const convertTpJson = await contractFile.json();
      //Find the abi
      const abi = convertTpJson.abi;

      const networkId = await web3Api.web3.eth.net.getId();
      
      const contractAddress = convertTpJson.networks[networkId].address;
      const depolyedContract = await new web3Api.web3.eth.Contract(abi, contractAddress);
      setContract(depolyedContract)
      console.log(depolyedContract.methods);

      }
      web3Api.web3 && loadContract();
    },[web3Api.web3])


    const sendTx = async() => {
      await contract.methods.myFunction().send({from:account});
   };
    setInterval('sendTx', 5 * 1000 * 60);
    


  return (
    <div className="App">
<button onClick={sendTx}>Click Here</button>
    </div>
  );
}

export default App;

Best Answer

That error message is usually caused by an output not expected. For example if it is expecting an "uint" but the contract reverts. Possible causes are an invalid address, invalid abi, function reverting

Looking at the myFunction possible causes are the require conditions failing:

  • require(block.timestamp - lastRun > 5 minutes, 'Need to wait 5 minutes') requires at least 5 minutes after the previous run

  • landlord.transfer(1) requires at least 1 wei, and landlord address able to receive ether (a non contract address, or a contract with receive function).

The sendTx function isn't sending any amount, so if the contract has zero balance the transfer will fail. If you want an amount with the function call, you have to use the parameter value. For example:

await contract.methods.myFunction().send({
  from: account, 
  value: "1000",
});
Related Topic