Web3js

具有多個合約“發送”請求的交易

  • May 16, 2021

最近,我們試圖創建一個應用程序,允許使用者使用 ERC-20 代幣購買 NFT(假設出於這些目的,它是像 DAI 或 USDC 這樣的穩定幣)。所以從弄清楚一切我們

 public async approve(): Promise<void> {
   const ticketPrice = 100;

   // Approve the contract to transfer on your behalf
   const contract = new this.web3js.eth.Contract(TestUSDContract.abi, this.USD_ADDRESS);
   const success = await contract.methods.approve('<CONTRACT ADDRESS>', ticketPrice).send({from: '<USER ADDRESS>'});
   console.log('Status ' + success);

   //Then purchase the item the user wants
   const contract2 = new this.web3js.eth.Contract(LotteryContract.abi, this.CONTRACT_ADDRESS);
   const value = await contract2.methods.buyItem().send({from: '<USER ADDRESS>'});
   console.log('contract2 ' + value);
 }

為了透明起見,以下是用於測試的合約方法

 function buyTicket() external returns (string memory) {
   testUsdContract.transferFrom(msg.sender, address(this), itemAmount);
   return "SUCCESS";
 }

這一切都有效,然而,從使用者體驗的角度來看,使用者從使用者界面中獲得了兩個對話框,這似乎是糟糕的使用者體驗。同樣根據我的理解(並且有意義),必須從使用者的帳戶呼叫批准方法(並且不能來自契約,因為msg.senderERC-20 代幣將是我們的契約)。

  1. 我想知道對此存在哪些解決方法以及其他應用程序如何完成接受 ERC-20 項目作為付款(最好以使用者友好的方式)。
  2. 這也引出了一個問題,當第一個請求成功而第二個請求失敗時會發生什麼(可能是網路錯誤或契約異常),通常在 DAPP 中如何處理(以及其他 dapps 是如何做到的?)

目前沒有辦法使用 ERC-20 代幣進行兩次approve交易transferFrom。你不能直接向合約發送代幣,因為接收合約不知道交易(就像普通的 ETH 交易一樣)。

大多數 dApp 預先以最大可能uint256值進行批准,這實質上意味著 dApp 可以轉移無限數量的代幣。這樣您就不必對每筆交易進行批准,只需一次即可讓使用者加入。然而,這樣做的缺點是你的合約現在控制了使用者的全部代幣餘額,從安全形度來看這並不是很好。

有一些 EIP 試圖解決這個問題,例如:

  • EIP-2711,它引入了新的交易類型,包括進行批量交易的交易類型。您可以在一個批量交易中進行審批和轉賬。如果您有興趣了解有關交易類型的更多資訊,我寫了一篇關於這些和 EIP-2711 的部落格文章,您可以在此處找到。
  • EIP-3074,它允許合約在 EOA 的上下文中發送交易。這樣,合約可以使用AUTHCALL操作碼進行呼叫,並且msg.sender是使用者的地址,而不是合約地址。我制定了一個可以進行任意(批量)呼叫的契約,您可以在此處找到。

不幸的是,在乙太坊網路中包含其中一個(或另一個類似的 EIP)之前,沒有辦法繞過必鬚髮送兩個交易

這也引出了一個問題,當第一個請求成功而第二個請求失敗時會發生什麼(可能是網路錯誤或契約異常),通常在 DAPP 中如何處理(以及其他 dapps 是如何做到的?)

您可以事先檢查使用者是否已經批准(通過檢查 ERC-20 契約上的津貼是否足夠高)。這樣,第二次交易是否失敗並不重要。

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