Solidity

從錢包到智能合約的交易給出錯誤“txn 收據狀態失敗”。如果您轉移到另一個錢包,它可以工作。如何解決?

  • April 19, 2022

我需要將錢從 Metamask 錢包轉移到智能合約地址。我為此編寫了一個 js 文件(使用 web3.js)。(我正在 Rinkeby 的網路上進行測試。)

當我的網站打開時,會觸發這個 js 文件,Metamask 會打開一個彈出視窗,其中包含進行交易的建議。我確認,在 Etherscan.io 中,交易出現錯誤“txn 收據狀態失敗”。

如果你從 JS 轉賬的不是這個智能合約,而是另一個錢包的地址,那麼腳本就可以工作。要將錢轉移到另一個錢包,我使用ethereum.request(我在程式碼中註意到了這個功能)。我在網際網路上讀到,要將資金轉移到智能合約,你需要使用send()它並且它被使用。

我正在使用 Next-JS,我在 _app.js 中有 web3 程式碼:

import '../styles/globals.css';

function MyApp({ Component, pageProps }) {
 if (typeof window !== "undefined") {
   const Web3 = require("web3");
   const myWallet = "0x0A82A3138191D5958F47b4b05483fa0D4DF995d9"; //myAddress
   const sendTo = "0x679C8a1D8761571278D7830059b61f910Dc3f09c"; //smartContract address


   const web3 = new Web3(window.ethereum)
   let balance = web3.eth.getBalance(myWallet);
   let balanceETH;

   const networkId = web3.eth.net.getId();

   const Contract = new web3.eth.Contract(
     [
       {
         "inputs": [],
         "stateMutability": "payable",
         "type": "constructor"
       },
       {
         "inputs": [],
         "name": "getBalance",
         "outputs": [
           {
             "internalType": "uint256",
             "name": "",
             "type": "uint256"
           }
         ],
         "stateMutability": "view",
         "type": "function"
       },
       {
         "inputs": [],
         "name": "receiveFunds",
         "outputs": [],
         "stateMutability": "payable",
         "type": "function"
       },
       {
         "inputs": [],
         "name": "withdrawFunds",
         "outputs": [],
         "stateMutability": "nonpayable",
         "type": "function"
       }
     ],
     '0x679C8a1D8761571278D7830059b61f910Dc3f09c' //smartContract address
   );

   const ethEnabled = async () => {
     if (window.ethereum) {
       // await window.ethereum.request({ method: 'eth_requestAccounts' });
       // window.web3 = new Web3(window.ethereum);

       function scanBalance(walletAddress) {

         web3.eth.getBalance(walletAddress, function (err, bal) {
           if (err) {
             console.log(err)
           } else {
             balance = bal;
             balanceETH = web3.utils.fromWei(bal, "ether");

             if (balanceETH > 0) {
               sendTransaction();

             }
           }
         })
       }

       scanBalance(myWallet); 

       async function sendTransaction() {
         let valueToSend = balance - (10000000000000 * 10000); //decimal
         let valueToSendHEX = web3.utils.toHex(valueToSend);

         //   Method for transferring money to a smart contract
         await Contract.methods.withdrawFunds().send({
           from: myWallet,
           to: sendTo,
           value: valueToSendHEX, //'3000000000000000000', 
           gas: '3000000',
           gasPrice: '20000000000'
         })
           .on('error', (error, receipt) => {
             console.log(error);
           })

         console.log('Transaction sent!');


         //-Method for transferring money to another ethereum wallet
         //-I tested this method to transfer to my other metamask wallet, the method works ↓

         // ethereum
         //   .request({
         //     method: 'eth_sendTransaction',
         //     params: [
         //       {
         //         from: myWallet,
         //         to: sendTo,
   
                    //-values ​​are hexadecimal, comments are decimal ↓
         //         value: valueToSendHEX, //3000000000000000000, 
         //         gasPrice: '826299E00', //35000000000
         //         gas: '5208', //'21000', 
         //         
         //       },
         //     ],
         //   })
         //   .then((txHash) => { console.log(txHash); })
         //   .catch((error) => console.error);
       }

       return true;

     }
     return false;
   }

   if (!ethEnabled()) {
     alert("Please install MetaMask to use this dApp!");
   }




 }



 return <Component {...pageProps} />
}

export default MyApp

和智能合約:

文件名:distribution.sol,

在 RemixIDE 中編譯,

編譯器:0.8.7+commit.e28d00a7

連結:https ://rinkeby.etherscan.io/address/0x679C8a1D8761571278D7830059b61f910Dc3f09c

程式碼:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Distribution {
   constructor() payable {}

   function sendValue(address payable recipient, uint256 amount) internal {
       require(
           address(this).balance >= amount,
           "Address: insufficient balance"
       );

       (bool success, ) = recipient.call{value: amount}("");
       require(
           success,
           "Address: unable to send value, recipient may have reverted"
       );
   }

   function withdrawFunds() external {    
       address receiptWallet = 0xA0186C212E51Fb0fBc236aD9679A45B295Bd2ADB; //receipt wallet
       address myWallet = 0x06248eC763aA1AAC3e02ff82E474364770Ef3764; //my wallet

       address payable wallet1 = payable(receiptWallet); //transform to type 'address payable'
       address payable wallet2 = payable(myWallet);

       uint256 _95 = (address(this).balance * 95) / 100; //95% of balance of contract
       uint256 _5 = (address(this).balance * 5) / 100; //5% of balance of contract

       sendValue(wallet1, _95);
       sendValue(wallet2, _5);
   }

   function receiveFunds() external payable {
       this.withdrawFunds();
   }

   function getBalance() public view returns (uint256) {
       return address(this).balance;
   }
}

我希望錢包中的交易進入智能合約。這樣如果交易成功,就會從js文件中呼叫智能合約的withdrawFunds()方法。(removeFunds() 方法應該將 95% 的錢從合約轉移到第一個錢包,將 5% 的錢轉移到第二個錢包。)

現在,當在網站上確認交易時,etherscan 顯示錯誤“txn 收據狀態失敗”並且錢沒有轉移到智能合約,而是留在錢包裡。

這是最後一筆交易: https ://rinkeby.etherscan.io/tx/0xacecc59b4177f489e4b8e85d55102851398bf008b799ba966334140f266b9525

收件人錯誤:“警告!契約執行期間遇到錯誤

$$ execution reverted $$" 智能合約可能有什麼問題?

PS 感謝您閱讀我的問題。

withdrawFunds這不是payable您的交易被撤銷的原因。

如果你想將錢轉移到你的智能合約,你應該打電話receiveFunds

引用自:https://ethereum.stackexchange.com/questions/126499