Solidity

如何在函式呼叫中將 ERC20 代幣轉移到合約中

  • February 13, 2022

我創建了一個智能合約,我希望自定義令牌與之互動。

例子:

pragma solidity >=0.7.0 <0.9.0;

contract PaymentInvoiceSplit {
   uint productPrice;

   constructor (uint defaultProductPrice) {
       owner = msg.sender;
       productPrice = defaultProductPrice;
   }

   function payInvoice (uint invoiceId) payable public {
     // Receive Amount
     // Split payment
     // Emit event
   }

   function kill () public onlyOwner() {
       selfdestruct(payable(owner));
   }
}

我正在使用 MetaMask:

  • 網路:智能鏈
  • 已導入帳戶
  • 自定義令牌添加為資產
  • 我在 BNB 上有用於 gas 和 Custom Token 的資金

MetaMask 賬戶和資產

然後我連接了前端並嘗試呼叫合約,但是當呼叫合約時它使用的是 ETH,但我想使用自定義令牌來代替:

window.onload = async () => {
   await window.ethereum.enable()

   web3 = new Web3(web3.currentProvider)
   const accounts = await ethereum.request({ method: 'eth_accounts' })

   const paymentInvoiceAbi = [
     {
       "inputs": [
         {
           "internalType": "uint256",
           "name": "invoiceId",
           "type": "uint256"
         }
       ],
       "name": "payInvoice",
       "outputs": [],
       "stateMutability": "payable",
       "type": "function"
     }
   ]

   const paymentInvoiceAddress = '0x'
   const paymentInvoiceContract = new web3.eth.Contract(paymentInvoiceAbi, paymentInvoiceAddress)

   const invoiceId = '123'
   const data = paymentInvoiceContract.methods.payInvoice(invoiceId).send({ from: accounts[0] })
 }

我可以將資金從自定義令牌轉移到我的智能合約,但這樣我只能發送金額並且我不能呼叫合約方法:

window.onload = async () => {
   await window.ethereum.enable()

   web3 = new Web3(web3.currentProvider)
   const accounts = await ethereum.request({ method: 'eth_accounts' })

   const tokenAbi = [
     {
       inputs: [
         {
           internalType: "address",
           name: "recipient",
           type: "address"
         },
         {
           internalType: "uint256",
           name: "amount",
           type: "uint256"
         }
       ],
       name: "transfer",
       outputs: [
         {
           internalType: "bool",
           name: "",
           type: "bool"
         }
       ],
       stateMutability: "nonpayable",
       type: "function"
     }
   ]

   const tokenAddress = '0xa'
   const paymentInvoiceAddress = '0xb'
   const tokenContract = new web3.eth.Contract(tokenAbi, tokenAddress)

   const value = web3.utils.toHex('3000000')
   const data = tokenContract.methods.transfer(paymentInvoiceAddress, value).send({ from: accounts[0] })
 }

有什麼方法可以互動這兩個合約?使用自定義令牌處理我的智能合約?

我的目標是創建一個智能合約,從 BEP20 等自定義代幣接收資金,並使用智能合約進行處理。

謝謝!

如果您希望使用者使用代幣支付。

您的契約應如下所示

pragma solidity >=0.7.0 <0.9.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
// npm install @openzeppelin-contracts required

contract PaymentInvoiceSplit {
   uint productPrice;

   constructor (uint defaultProductPrice) {
       owner = msg.sender;
       productPrice = defaultProductPrice;
   }

   function payInvoice (uint invoiceId, address token) payable public {

   IERC20 paymentToken = IERC20(token);
   uint256 amountToPay;

     // You must pull the amount
     // The amount must be approved by the account before the transfer

   require(paymentToken.allowance(msg.sender, address(this)) >= amountToPay,"Insuficient Allowance");
   require(paymentToken.transferFrom(msg.sender,address(this),amountToPay),"transfer Failed");

     // At this point you have the amountToPay in the contract
     // Do your stuff
     // Emit event
   }

}

在此範例中,呼叫者將提供他想要支付的令牌的地址,並且該函式將執行轉移。

如果您的代幣合約中有特殊的自定義功能,您將不得不對它們進行介面。

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