Solidity

ERC20/ERC721 safeTransferFrom 需要 from 地址是否有原因?為什麼不直接使用safeTransferTo呢?

  • March 14, 2022

我可以理解函式中的from地址safeTransferFrom可以由經過批准的操作員使用。但我也想知道為什麼不為實際所有者提供另一個safeTransferTo不需要提供from地址的函式呢?

safeTransferTo(address to, uint tokenId, bytes memory_data);

在這種情況下,它from是隱含的,因為它來自msg.sender地址。這不是更方便嗎?

這樣做是否有任何影響,例如我沒有看到人們這樣做的安全問題?如果我願意,我應該在自己的契約中實現這樣的功能嗎?

這不是更方便嗎?

並不真地。當您通過在此假設下執行的 gui 執行此操作時,您不會from手動填寫 - 它將通過 javascript 在 dApp/網站中製作交易來代表您完成;當您收到元遮罩提示時,您只需在交易上簽字。

另一方面,將額外的程式碼部署到區塊鍊是昂貴的。在這種情況下,一個功能可以完成這一切,意味著部署的 gas 成本更低,創建錯誤和審計的程式碼更少。

這樣做是否有任何影響,例如我沒有看到人們這樣做的安全問題?如果我願意,我應該在自己的契約中實現這樣的功能嗎?

從表面上看,為什麼不呢?**但是,在實踐中,是的,可能很多人會失去很多代幣……**或者,在考慮了這些建議之後,該功能可能永遠不會被使用。:)

因為 ERC20 不是 ETH,並且將 ERC20 發送到合約不會觸發receive()orfallback()函式,所以我們幾乎總是將 ERC20 發送到合約的方式是通過approving()合約,然後讓合約從您那里取 ERC20,而不是推送ERC20給它。(ERC777通過實現鉤子和操作符來處理這個問題,消除了對approve()步驟的需要,以及相關的成本和問題。)

試圖將 ERC20送到合約基本上是它失敗的第一種方式——就在兩個月前,一個人通過將 ERC20 wETH送到 wETH 合約意外燒掉了 50 萬美元在 etherscan 上)(新聞) 。為什麼這是個問題?因為幾乎可以肯定,wETH 合約就像所有其他 ERC20 操縱合約一樣,是針對代幣設計的,而不是從推送中接收它們。pull

快速了解其餘部分:

雖然您可能會safeTransferFrom()在 ERC20 和 ERC721 相關程式碼中看到,但這兩個函式基本上彼此無關,並且聲稱“安全”的原因也大不相同。它是ERC721規範的官方部分,但不是規範的一部分ERC20

ERC721規範檢查以確保,如果接收者是合約,則接收者可以返回一個魔法值,以確認它被設計為接收 ERC721 NFT。

我熟悉的 ERC20 實現來自 Open Zeppelin’s SafeERC20.sol,其中“安全”是指與不符合標準且無法正常失敗的令牌進行互動和處理。他們的 tldr:

圍繞引發失敗的 ERC20 操作的包裝器(當代幣合約返回 false 時)。還支持不返回值(而是還原或拋出失敗)的令牌,假定非還原呼叫是成功的。

你可以處理其中一個/兩個問題,但是因為你推送它而不是讓合約它,它會永遠失去,因為一般來說,合約無法知道是誰發送的。

作為 的一部分safeTransferTo(),您必須指定一個新的EIP165-esque 檢查以確保接收者(如果它是一個合約)期望並且將處理直接送給它的代幣。但是,鑑於沒有項目知道您的代幣,並且您的代幣將是唯一開始這樣做的項目(在新範式上獲得動力很難,並且有一個原因我們不做更直覺to的而不是from,如已闡明的那樣在這個答案的開頭),這個功能可能最終不會有太多用處。

ERC20 是一個有問題的、搖搖欲墜的舊標準,我們之所以繼續使用它是因為它具有廣泛的互操作性,儘管我們都知道它容易出錯。與其添加一些新的不符合標準的功能,最好繼續使用SafeERC20——或者只是切換到ERC777!

…只需確保您已完全預料到鉤子可能導致的重入後果。:)

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