從合約中提取 ETH 失敗
試圖編寫一個快速函式來退出
ETH
我的契約 - 它不起作用。這是程式碼:
function withdrawEntireBalance() payable external { require(msg.sender == contractOwner, "ERROR! Only Contract's owner may call!"); msg.sender.transfer(address(this).balance); }
當我說它不起作用時,我並不是說它在拋出錯誤。相反:它完美地編譯,它執行 - 它只是沒有做它應該做的事情。它什麼也不做。
我還創建了一個
getContractBalance()
函式,以便我可以查詢合約並確保它實際上有一些ETH
餘額:function getContractBalance() external returns(uint256 theBalance) { return address(this).balance; }
此功能執行良好,我能夠 100% 肯定地驗證當我嘗試提取該餘額時,該合約的餘額中確實有 ETH。這是一個範例輸出:
'getContractBalance' result is: 14700000000000000
我還嘗試了該功能的一些替代程式碼
withdrawEntireBalance()
- 在閱讀了各種關於安全問題和最低 gas 成本增加的文章(可能導致通常用於此類操作的傳統方法transfer()
和send()
方法失敗)之後 - 它也不起作用。無論如何,我將它包括在這裡,所以你可以看到我經歷了什麼:// Alternative code: (bool success, ) = msg.sender.call.value(address(this).balance)(""); require(success, "ERROR!!!! 'withdrawEntireBalance()' - Transfer failed.");
有什麼想法嗎?
=================
更新:
根據要求,這是我在程式碼中呼叫
withdrawEntireBalance()
方法的方式javascript
:cashOut: function() { console.log("\n\n=================\n==> in 'cashOut()'!"); var cashoutYo = jsApp.appContractInstance.methods.withdrawEntireBalance().call({from: jsApp.defaultAccount}, function(error, result) { if (!error) { console.log("Back in 'withdrawEntireBalance'!!! No ERRORS!!!"); // jsApp.contractOwner = result; console.log("CashOut result is: " + result); console.log("CashOut result KEYS = " + Object.keys(result)); console.log("CashOut result VALUES = " + Object.values(result)); } else { console.log("ERROR!!! from 'withdrawEntireBalance()' -->\n" + error); console.log("Error KEYS = " + Object.keys(error)); console.log("Error VALUES = " + Object.values(error)); } }); console.log("\n\n=================\n==>EXITING 'withdrawEntireBalance()'!"); }
var cashoutYo = jsApp....
是非同步的,所以試試await
.即便如此,它也不會返回您所期望的。您將獲得發送到網路的交易的交易雜湊 - 而不是網路探勘後的結果,因為您必須等待。
查看您可能感興趣的階段以及等待它們的便捷方式:
web3.eth.sendTransaction({from: '0x123...', data: '0x432...'}) .once('sending', function(payload){ ... }) .once('sent', function(payload){ ... }) .once('transactionHash', function(hash){ ... }) .once('receipt', function(receipt){ ... }) .on('confirmation', function(confNumber, receipt, latestBlockHash){ ... }) .on('error', function(error){ ... }) .then(function(receipt){ // will be fired once the receipt is mined });
https://web3js.readthedocs.io/en/v1.3.0/callbacks-promises-events.html
有幾個不同的 JavaScript 庫和合約抽像都有自己的實現,但底層的 EVM 總是相同的。
交易被發送並從有效負載生成雜湊(txn 的 UID)。甚至不需要來自網路的響應,因此無法保證網路甚至會知道(例如連接問題)。第一個回調為您提供節點嘗試發送的雜湊值。
稍後,當交易被包含在一個塊中時,它們就會被探勘出來。給定一個交易雜湊,你可以等待它出現在一個區塊中。只有這樣才能說它是失敗還是成功並檢查效果。
像 ganache-cli 這樣的工具可能會在某種程度上掩蓋非同步過程,因為它們會“按需”立即探勘塊。小心不要被即時挖礦所迷惑。使用公共測試網確認您正在正確處理該過程。
希望能幫助到你。