Solidity

從合約中提取 ETH 失敗

  • December 3, 2021

試圖編寫一個快速函式來退出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 這樣的工具可能會在某種程度上掩蓋非同步過程,因為它們會“按需”立即探勘塊。小心不要被即時挖礦所迷惑。使用公共測試網確認您正在正確處理該過程。

希望能幫助到你。

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