從錢包到智能合約的交易給出錯誤“txn 收據狀態失敗”。如果您轉移到另一個錢包,它可以工作。如何解決?
我需要將錢從 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