Solidity

Escrow.sol:如果您發送價值並且您發送的價值應該小於您目前的餘額,則應該支付呼叫的函式

  • June 20, 2022

我正在嘗試Escrow.sol使用 ERC20 令牌。當我在 Remix 上部署 Escrow.sol 並想存入 10 個代幣時,似乎The called function should be payable if you send value and the value you send should be less than your current balance.提款功能也是如此。

我該如何解決?

以下是我的erc20.sol

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
   constructor() ERC20("GINWEI", "GW") public payable {
       _mint(msg.sender, 1000);
   }
}

以下是escrow.sol

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

import "./erc20.sol";

contract MyEscrow {

   mapping(address => mapping(address => uint256)) public _deposits;
   address payable payee = payable(msg.sender);
   MyToken token;

   function deposit(uint256 amount) public payable {
       token.approve(address(this), amount);
       token.transfer(address(this), amount);
       _deposits[payee][address(token)] += amount;
   }

   function depositsOf() public view returns (uint256) {
       return _deposits[payee][address(token)];
   }

   function withdraw(uint256 payment) public payable {
       _deposits[payee][address(token)] -= payment;
       payee.transfer(payment);
   }
}

你的MyEscrow智能合約有任何問題,讓我解釋一下:

  • 當您聲明此語句MyToken token;為儲存變數時,您必須使用 ERC20 的智能聯繫人地址對其進行實例化,以使用 ERC20 方法。如何解決此問題的範例:

MyToken token = MyToken([addressERC20SmartContract]);

  • token.approve(address(this), amount);此聲明是錯誤的,因為您正在批准您的 MyEscrow 智能合約來轉移它沒有的代幣數量。為了解決這個問題,在這種情況下,使用者必須approve()從您的 ERC20 智能合約呼叫MyToken智能合約。當 call 時approve,他必須在這些參數中傳遞這些值:

    • 支出者:MyEscrow智能合約地址;
    • MyEscrow金額:可以從您的錢包中轉移多少代幣。
  • 最後,在withdraw將 ERC20 從智能合約轉移到使用者錢包的功能中,您可以使用transfer()ERC20 方法並在其中傳遞msg.sender要提取的值和值。

MyEscrow以這種方式更正了您的智能合約:

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

import "./erc20.sol";

contract MyEscrow {

   mapping(address => mapping(address => uint256)) public _deposits;
   address payable payee = payable(msg.sender);
   MyToken token;

   constructor(address _myToken) {
       token = MyToken(_myToken); 
   }

   function deposit(uint256 amount) public payable {
       token.transferFrom(msg.sender, address(this), amount);
       _deposits[payee][address(token)] += amount;
   }

   function depositsOf() public view returns (uint256) {
       return _deposits[payee][address(token)];
   }

   function withdraw(uint256 payment) public payable {
       _deposits[payee][address(token)] -= payment;
       token.transfer(msg.sender, payment);
   }
}

經過幾次嘗試,我將@Kerry99 中的 sol 和我的原始程式碼結合起來,效果很好!

funcapprove()已被覆蓋。

contract MyEscrow {

   mapping(address => mapping(address => uint256)) public _deposits;
   address payable payee = payable(msg.sender);
   address tokenaddress = 0x...;
   MyToken token = MyToken(tokenaddress);

   function deposit(uint256 amount) public payable {
       token.approve(msg.sender, address(this), amount);
       token.transferFrom(msg.sender, address(this), amount);
       _deposits[payee][tokenaddress] += amount;
   }

   function depositsOf() public view returns (uint256) {
       return _deposits[payee][tokenaddress];
   }

   function withdraw(uint256 payment) public payable {
       _deposits[payee][tokenaddress] -= payment;
       token.transfer(msg.sender, payment);
   }
}

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