ERC20和ERC223的區別
我仍然不明白“如果你向合約發送 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
. 這是一種救援的可能性,但前提是該功能包含在接收契約中:
- 愛麗絲將
XYZ
令牌發送到contract FOO
。FOO
不知道這一點,但它的地址在 XYZ 中有餘額。- Alice 將錯誤報告給 Bob(讓 Bob 頭疼)。只有Bob有權退出
owner
.FOO``XYZ``FOO
- Bob
reclaimToken(address XYZ)
用來恢復擱淺的代幣。- Bob 將
XYZ
後面的內容轉發給 Alice。- 愛麗絲很高興。
您可能會注意到,無論如何這對 Bob 來說都不是理想的選擇。如果合約無法返回錯誤的代幣,那麼 Bob 必須向 Alice 解釋這一點。如果合約是去中心化的並且沒有特權所有者,那麼這種解決方法可能不切實際。如果合約確實具有恢復功能,那麼 Bob 將承擔可能不受歡迎的服務責任。這一切都假設愛麗絲可以找到鮑勃。
我認為有理由說許多(全部?)被擱置的代幣案例是一種或另一種形式的操作員錯誤(或開發),因為如果契約沒有,向契約發送東西沒有多大意義想要或期待它。預設情況下,這是一個不可恢復的錯誤。ERC223 試圖預防性地糾正這種危險情況。
ERC223 是帶有一點額外邏輯的 ERC20。它向後兼容並通過以下方式解決此問題:
- 檢查接收方是否為契約。契約有程式碼,所以(偽)
if(bytecode.length > 0)
,,那麼它就是一個契約。- 如果接收者是合約,則呼叫接收者的
tokenFallback()
函式(如果存在),否則呼叫正常的備份函式。這讓接收者有機會做出反應。現在呼叫接收契約,而不是不知道收據。怎麼辦……嗯……
拒絕(帶有
revert()
)意外類型的標記怎麼樣?Rejection (byrevert()
) 會將令牌返回給發送者,這可能是我們想要的。可以想像一份不期望任何形式的付款並且沒有辦法處理它的契約。關於意外乙太幣的預設設置已經到位,因為
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 代幣將剛剛到達,因為接收者無法拒絕它們。
希望能幫助到你。