Solidity

ERC20和ERC223的區別

  • March 23, 2019

我仍然不明白“如果你向合約發送 100 個 ERC20,他們就會卡在那裡,這 100 個 ERC20 將永遠失去”……我真的不明白……就像合約有一個地址和任何普通賬戶一樣的錢包。如果我們將 ERC20 發送到合約,我們為什麼不使用轉賬方法,例如將儲存在智能合約中的代幣帶到其他賬戶地址。任何人都可以舉例說明這一點嗎?提前謝謝。

一開始並不是特別明顯。

合約可以輕鬆地接受 ERC20 代幣並與之交易。但是,合約不能做任何它在部署之前沒有設計做的事情。雖然說合約是一個地址很容易,理論上它可以轉發代幣,但實際上它可能不知道如何。合約不會執行未預先編碼的任意操作。

Open Zeppelin 有一個CanReclaimTokens解決方案(https://github.com/OpenZeppelin/openzeppelin-solidity/blob/v1.12.0/contracts/ownership/CanReclaimToken.sol),它接受一個任意的 ERC20 合約地址(因為流入的隨機代幣可以是任何東西) 並允許接收方的owner. 這是一種救援的可能性,但前提是該功能包含在接收契約中:

  1. 愛麗絲將XYZ令牌發送到contract FOOFOO不知道這一點,但它的地址在 XYZ 中有餘額。
  2. Alice 將錯誤報告給 Bob(讓 Bob 頭疼)。只有Bob有權退出owner.FOO``XYZ``FOO
  3. BobreclaimToken(address XYZ)用來恢復擱淺的代幣。
  4. Bob 將XYZ後面的內容轉發給 Alice。
  5. 愛麗絲很高興。

您可能會注意到,無論如何這對 Bob 來說都不是理想的選擇。如果合約無法返回錯誤的代幣,那麼 Bob 必須向 Alice 解釋這一點。如果合約是去中心化的並且沒有特權所有者,那麼這種解決方法可能不切實際。如果合約確實具有恢復功能,那麼 Bob 將承擔可能不受歡迎的服務責任。這一切都假設愛麗絲可以找到鮑勃。

我認為有理由說許多(全部?)被擱置的代幣案例是一種或另一種形式的操作員錯誤(或開發),因為如果契約沒有,向契約發送東西沒有多大意義想要或期待它。預設情況下,這是一個不可恢復的錯誤。ERC223 試圖預防性地糾正這種危險情況。

ERC223 是帶有一點額外邏輯的 ERC20。它向後兼容並通過以下方式解決此問題:

  1. 檢查接收方是否為契約。契約有程式碼,所以(偽) if(bytecode.length > 0),,那麼它就是一個契約。
  2. 如果接收者是合約,則呼叫接收者的tokenFallback()函式(如果存在),否則呼叫正常的備份函式。這讓接收者有機會做出反應。現在呼叫接收契約,而不是不知道收據。

怎麼辦……嗯……

拒絕(帶有revert())意外類型的標記怎麼樣?Rejection (by revert()) 會將令牌返回給發送者,這可能是我們想要的。

可以想像一份不期望任何形式的付款並且沒有辦法處理它的契約。關於意外乙太幣的預設設置已經到位,因為payable如果附加了乙太幣,則必須標記功能。payable並且,由 solc 創建並由 EVM 執行的預設回退函式(不是)如果發送了 ether,則拒絕其他所有內容。

邏輯將這個tokenFallback()想法擴展到代幣合約,並提出了一種標準化的處理方式。

考慮:

function tokenFallback(args ...) public {
  revert("Don't send tokens here. This contract has no idea what to do with them.");
}

它在這裡更加充實:https ://github.com/OpenZeppelin/openzeppelin-solidity/blob/v1.12.0/contracts/ownership/HasNoTokens.sol 。

這可以保護 ERC223 代幣的發送者。ERC20 代幣將剛剛到達,因為接收者無法拒絕它們。

希望能幫助到你。

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