簡體   English   中英

Ethers js 在合約之間傳輸 ERC20

[英]Ethers js transferring ERC20 between contracts

我有 2 個合約,第一個是 openzeppelin ERC20 代幣,第二個是彩票合約,玩家可以在其中下注一個數字。

彩票.sol

pragma solidity ^0.8.4;
import "./Token.sol"; //import ERC20 token
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract Lottery is Ownable {

Token token;
constructor(Token _token) public {
   token = _token;
}

// store information about player's bet
struct PlayersStruct {
   uint betAmount;
   uint betOnNumber;
}

mapping(address => PlayersStruct) public balances;

function enterLottery(string memory _betOnNumber) public payable {

    address player = msg.sender;
    uint amount = msg.value;

    // transfer token from player's wallet to lottery contract
    token.transferFrom(player, address(this), betAmount);

    balances[player].betAmount += amount ;
    balances[player].betOnNumber = _betOnNumber;

}

這就是我從 ReactJS 中調用它的方式

async function stakeBet() {
   const amount = ethers.utils.parseEther("10");
   const maxAmount = ethers.utils.parseEther("1000000");

  // approve token once so player can save on gas in future
  await token.approve(stakingContract.address, maxAmount);

  // bet 10 tokens on number 20
  await lottery.enterLottery(20, {value: amount,});
}

這段代碼有兩個問題:

  1. 我每次都必須批准合同,即使我批准的 maxAmount 高於投注金額。 我如何讓 Metamask 知道合同已經被批准?
  2. 批准ERC20代幣后,轉出的代幣實際上是ETH,而不是Token.sol中定義的ERC20代幣,如何指定ERC20為轉出的代幣?

我正在 Kovan 測試網上進行測試。

在您的stakeBet function 中,您按順序調用這些函數:

 await token.approve(stakingContract.address, maxAmount);

  // bet 10 tokens on number 20
  await lottery.enterLottery(20, {value: amount,});

當您調用批准時,您實際上是在更新allowance映射。 讓合同知道,您允許一定數量的地址用於允許的地址。 它應該像這樣實現:

function approve(address _spender, uint _value)public returns (bool success){
        // allowance  tells how many tokens can be sent
        allowance[msg.sender][_spender]=_value;
        // This event must trigger when a successful call is made to the approve function.    
        emit Approval(msg.sender,_spender,_value);
        return true;
 }

代幣轉賬或代幣轉賬實際上是在更新合約內的 state。 隨着approve function 您更新了津貼。 現在token.transferFrom應該像這樣實現:

// my address is allowing your address for this much token
mapping(address=>mapping(address=>uint)) public allowance;

function transferFrom(address _from, address _to, uint256 _value) public returns (bool success){
        // check the allowance
        require(_value <=allowance[_from][msg.sender]);
        // update the balances
        balanceOf[_to]+=_value;
        balanceOf[_from]-=_value;
        allowance[_from][msg.sender]-=_value;
        // emitting an event
        emit Transfer(_from,_to,_value);
        return true;
    }
  • ETH 不是 ERC20 代幣。 相反,您必須實施 WETH 代幣並轉移 WETH 代幣。 WETH 是 eth 的包裝版本。 https://weth.io/

所有以太坊錢包地址都兼容 ERC20。 此外,這意味着每次 ERC20 轉賬都可能發生在兩個以太坊錢包地址或 ERC20 兼容地址之間。 這通常包括所有與 EVM 兼容的區塊鏈。 您發送 weth 令牌,用戶可以交換元掩碼:

在此處輸入圖像描述

對於第一部分,您已經完成了您打算做的事情,即您已將津貼設置為最大金額,這樣用戶就不必每次為 allow() 調用交易付費。

MetaMask 要求您同意向合約發送“betAmount”數量的代幣的汽油費(以 ETH 為單位)。

我是以太坊的新手,但在我的項目中也遇到過類似的情況。 所以,這是根據我的理解。

另外,對於第二個問題,正如我之前所說,MetaMask 正在征求您的同意以支付汽油費(它需要 ETH,但也必須進行實際的代幣轉移。只是,一些 ETH 用於“燃氣費”。

我有一篇非常好的文章討論了同樣的事情。 鏈接: https://medium.com/ethex-market/erc20-approve-allow-explained-88d6de921ce9

你可以看到我剛才所說的演示。 您可以看到 Gas 費用以 ETH 計入。 此外,如果您之前沒有將津貼設置為最大值,您將不得不支付兩次汽油費以使您的合約發生交易,首先調用approve()以獲得津貼,然后獲得“betAmount”數量的代幣轉入合同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM