Solidity

合約轉賬/存入乙太幣失敗

  • September 6, 2022

我正在嘗試將乙太幣存入智能合約。查看文件,我的方法首先看起來像這樣:

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

contract SendEther {

   function deposit(uint256 amount) public payable {
       require(msg.value == amount);
   }
}

但是,失敗並顯示以下錯誤消息:

$$ vm $$ 來自:0x5c6…21678

至:SendEther.deposit(uint256) 0xe63…4ddf5

值:0 wei

數據:0xb6b…03039

日誌:0

雜湊:0x50c…acc83

狀態 false 交易已開採但執行失敗

事務雜湊 0x50cb8aab1042aef79e8bf285346213a1edfa106b2a7421ee159da82b693acc83

從 0x5c6B0f7Bf3E7ce046039Bd8FABdfD3f9F5021678

to SendEther.deposit(uint256) 0xe63D12C600b87F5da3C32C7cB3C1b1A84944ddf5 gas 3000000 gas 交易成本 21614 gas 執行成本 21614 gas input 0xb6b…03039 解碼輸入 { “uint256 amount”: “12345” } 解碼輸出 {} logs

$$ $$val 0 衛 交易到 SendEther.deposit 錯誤:VM 錯誤:還原。

revert 事務已恢復到初始狀態。

注意:如果您發送值並且您發送的值應該小於您目前的餘額,則呼叫的函式應該是應付的。

調試事務以獲取更多資訊。

然後我嘗試使用 transfer 或 call 方法發送 Ether。

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

contract SendEther {

   receive() external payable {}

   function sendViaTransfer(address payable to, uint256 amount) public payable {
       to.transfer(amount);
   }
}

這導致了這個錯誤:

$$ vm $$ 來自:0x147…C160C

至:SendEther.sendViaTransfer(address,uint256) 0x70c…a304B

值:0 wei

數據:0xd27…004d2

日誌:0

雜湊:0xc29…0cf23

狀態 false 交易已開採但執行失敗

交易雜湊 0xc296ba642bca2e19c304a9e28381b3b523fdb86a94fcbc19e14ad5847a20cf23

從 0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C

to SendEther.sendViaTransfer(address,uint256) 0x70c001c84C723e3EfbF852D3e6AdaEb69A8a304B

氣體 3000000 氣體

交易成本 29070 gas

執行成本 29070 gas

輸入 0xd27…004d2

解碼輸入{

“地址”:“0x70c001c84C723e3EfbF852D3e6AdaEb69A8a304B”,

“uint256 數量”:“1234”

}

解碼輸出{}

日誌

$$ $$ val 0 衛

交易到 SendEther.sendViaTransfer 錯誤:VM 錯誤:還原。

revert 事務已恢復到初始狀態。

嘗試使用“呼叫”或“發送”會導致相同的錯誤。

我究竟做錯了什麼?

日誌顯示消息值為 0。請確保在點擊功能之前在 remix 中設置 VALUE,以便發送值

呼叫函式時設置要發送的值

首先,對於第一個範例,我認為您不需要require(msg.value == amount). msg.value是發送到該合約的 eth 值。該amount參數在那裡沒有做太多。如果msg.value發送的與amount. 但無論如何,這樣做是多餘的。但是要確保如果你發送一個amount參數5,那麼你也應該發送5weis,這樣這個函式就不會失敗。

function deposit(uint256 amount) public payable {
       require(msg.value == amount);
   }

第二個例子看起來不錯。但是你的合約至少需要有amountbalance 或者你應該發送一個與參數msg.value相同的 balance ( ) amount

function sendViaTransfer(address payable to, uint256 amount) public payable {
       to.transfer(amount);
   }

我用你可以接收和發送乙太的所有方式編寫了一些程式碼,並附上了一些評論,這可能對你有幫助。所有範例工作。請記住,在嘗試將乙太幣發送到另一個地址之前,乙太幣在您的合約中有足夠的餘額SendEther,或者向該合約發送足夠的乙太幣,以便它可以使用msg.value並發送該金額。

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

contract Receiver {
   receive() external payable {}

   fallback() external payable {}

   function receiveBalance() public payable {}

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

   //.. Other functionalities here (withdraw, etc).
}

contract SendEther {

   address public owner = msg.sender;

   // Maybe you want to control who can withdraw the balance from this contract.
   modifier onlyOnwer() {
       require(msg.sender == owner);
       _;
   }

   function deposit(uint256 amount) public payable {
       require(msg.value == amount); // No need to send or check an amount here.
   }

   function deposit_v2() public payable {
       // We have the option to do nothing here. As long as the function is `payable`, we receive the eth.
   }

   // If you want to only receive eth without doing any special logic, then you can use `receive` and/or `fallback`.
   receive() external payable {}

   fallback() external payable {}

   // This function is `payable`, so this contract is receving some amount and sending `amount` to another address
   function sendViaTransfer(address payable to, uint256 amount) public payable onlyOnwer {

       // Maybe you want to check that this contract has enough balance to send the requested amount.
       require(address(this).balance >= amount, "Not enough balance in the contract.");

       to.transfer(amount);
   }

   // This function is `payable`, so this contract is receving some amount and sending that same amount (msg.value) to another address
   function sendViaTransfer_v2(address payable to) public payable onlyOnwer {
       to.transfer(msg.value);
   }

   // This function is `payable`, so this contract is receving some amount and sending `amount` to another address
   function sendViaSend(address payable to, uint256 amount) public payable onlyOnwer {

       // Maybe you want to check that this contract has enough balance to send the requested amount.
       require(address(this).balance >= amount, "Not enough balance in the contract.");

       bool success = to.send(amount);
       require(success, "Error sending eth");

   }

   // This function is `payable`, so this contract is receving some amount and sending that same amount (msg.value) to another address
   function sendViaSend_v2(address payable to) public payable onlyOnwer {
       bool success = to.send(msg.value);
       require(success, "Error sending eth");
   }

   // This function is `payable`, so this contract is receving some amount and sending `amount` to another address
   function sendViaCall(address payable to, uint256 amount) public payable onlyOnwer {

       // Maybe you want to check that this contract has enough balance to send the requested amount.
       require(address(this).balance >= amount, "Not enough balance in the contract.");

       (bool success, ) = to.call{value: amount}("");
       require(success, "Error sending eth");

   }

   // This function is `payable`, so this contract is receving some amount and sending that same amount (msg.value) to another address
   function sendViaCall_v2(address payable to) public payable onlyOnwer {
       (bool success, ) = to.call{value: msg.value}("");
       require(success, "Error sending eth");
   }

   // This function is `payable`, so this contract is receving some amount and sending `amount` to another address
   function sendViaCustomFunction(address payable to, uint256 amount) public payable onlyOnwer {

       // Maybe you want to check that this contract has enough balance to send the requested amount.
       require(address(this).balance >= amount, "Not enough balance in the contract.");

       Receiver(to).receiveBalance{value: amount}();

   }

   // This function is `payable`, so this contract is receving some amount and sending that same amount (msg.value) to another address
   function sendViaCustomFunction_v2(address payable to) public payable onlyOnwer {
       Receiver(to).receiveBalance{value: msg.value}();
   }

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

}

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