粗略瀏覽過一次,先有大概的構想
詳細精讀重要的部分,略讀較不重要或自己會了的部分
Hook 某些操作發生之前或之後調用的函數。它們提供了一個集中點來連接和擴展原始行為。
使用鉤子會導致代碼更乾淨、更安全,而不必依賴對父級內部結構的深入理解。
virtual每當您覆蓋父掛鉤時,將屬性重新應用於掛鉤。這將允許子合約向鉤子添加更多功能。
始終使用super. 這將確保調用繼承樹中的所有鉤子:像這樣的合約ERC20Pausable依賴於這種行為。
oz 的可升級合約套件:https://docs.openzeppelin.com/upgrades-plugins/1.x/
UUPS
看敘述還是不太明白,可能要看合約
token合約(ERC):
Governance
Utilities
Note that a contract can also be the owner of another one! This opens the door to using, for example, a Gnosis Multisig or Gnosis Safe, an Aragon DAO, an ERC725/uPort identity contract, or a totally custom contract that you create.
TimelockController is a proxy that is governed by proposers and executors.
工具
兼容性(與基於Compound 的GovernorAlpha 和GovernorBravo):
Tally是一個成熟的應用程序,用於用戶擁有的鏈上治理。它包括投票儀表板、提案創建嚮導、實時研究和分析以及教育內容。
對於所有這些選項,Governor 將與 Tally 兼容:用戶將能夠創建提案、可視化投票權和擁護者、瀏覽提案並投票。特別是對於提案創建,項目還可以使用 Defender Admin 作為替代界面。
其他oz的套件包:
External interface of AccessControl declared to support ERC165 detection
FUNCTIONS
Contract module that allows children to implement role-based access control mechanisms. This is a lightweight version that doesn’t allow enumerating role members except through off-chain means by accessing the contract event logs. Some applications may benefit from on-chain enumerability, for those cases see AccessControlEnumerable.
FUNCTIONS
IAccessControl +
ERC2981:與 ERC721 和 ERC1155 兼容的 NFT 版稅
ERC20Permit
這些合約是上述功能的預配置組合。它們可以通過繼承或作為模型來複製和粘貼其源代碼。
SafeERC20
一個代幣持有者合約,允許受益人在給定的發佈時間後提取代幣。
對於簡單的歸屬時間表很有用,例如“顧問在 1 年後獲得所有代幣”。
ERC20進化版
operator ->代替別人傳送或銷毀代幣
標準化接口
ERC-1271中定義的合約的 ERC1271 標準簽名驗證方法的接口。
isValidSignature(hash, signature)
ERC20加強版
onTransferReceived(operator, from, value, data)
Any ERC1363 smart contract calls this function on the recipient after a transfer or a transferFrom. This function MAY throw to revert and reject the transfer. Return of other than the magic value MUST result in the transaction being reverted. Note: the token contract address is always the message sender.
->拒絕傳送
IERC20PERMIT
NFT 版稅標準的接口。
一種檢索不可替代代幣 (NFT) 版稅支付信息的標準化方法,以實現對所有 NFT 市場和生態系統參與者的版稅支付的普遍支持。
根據可能以任何交換單位計價的銷售價格,返回應支付的特許權使用費以及向誰支付。特許權使用費金額以相同的交換單位計價並應支付。
IERC3156FlashLender
IERC3156FlashBorrower
ERC2771Context
Context variant with ERC2771 support.
為了避免與代理背後的實現合約的存儲變量發生衝突,我們使用EIP1967存儲槽。
ERC1967Upgrade:獲取和設置 EIP1967 中定義的存儲槽的內部函數。
ERC1967Proxy:使用 EIP1967 存儲槽的代理。默認不可升級。
有兩種方法可以為 ERC1967 代理添加可升級性。
正確安全地使用可升級代理是一項艱鉅的任務,需要深入了解代理模式、Solidity 和 EVM。除非您想要大量低級控制,否則我們建議使用OpenZeppelin Upgrades Plugins for Truffle 和 Hardhat。
Hardhat: https://www.npmjs.com/package/@openzeppelin/hardhat-upgrades
A different family of proxies are beacon proxies. This pattern, popularized by Dharma, allows multiple proxies to be upgraded to a different implementation in a single transaction.
在這種模式下,代理合約不像 ERC1967 代理那樣將實現地址保存在存儲中,而是將地址存儲在單獨的信標合約中。發送到信標而不是代理合約的upgrade操作,以及遵循該信標的所有代理都會自動升級。
OpenZeppelin 中包含的原始代理遵循Transparent代理模式。雖然仍然提供這種模式,但我們的建議現在轉向 UUPS 代理,它既輕量級又多功能。UUPS 的名稱來自EIP1822,它首先記錄了該模式。
雖然這兩者共享相同的升級接口,但在 UUPS 代理中,升級由實現處理,並且最終可以被刪除。另一方面,透明代理在代理本身中包含升級和管理邏輯。這意味著TransparentUpgradeableProxy部署比使用 UUPS 代理更昂貴。
UUPS 代理使用ERC1967Proxy. 代理本身不可升級。除了合約的邏輯之外,實現的作用是包含更新存儲在代理存儲空間中特定插槽中的實現地址所需的所有代碼。這就是UUPSUpgradeable合約的用武之地。從它繼承(並_authorizeUpgrade使用相關的訪問控制機制覆蓋該功能)會將您的合約變成符合 UUPS 的實現。
請注意,由於兩個代理使用相同的存儲槽作為實現地址,因此使用符合 UUPS 的實現和 aTransparentUpgradeableProxy可能允許非管理員執行升級操作。
默認情況下,其中包含的升級功能UUPSUpgradeable包含一個安全機制,該機制將阻止對不符合 UUPS 的實施進行任何升級。這可以防止升級到不包含必要升級機制的實現合約,因為它會永遠鎖定代理的可升級性。此安全機制可以通過以下任一方式繞過:
在實現中添加一個標誌機制,在觸發時將禁用升級功能。
在沒有額外安全檢查的情況下升級到具有升級機制的實現,然後再次升級到沒有升級機制的另一個實現。
這種安全機制的當前實現使用EIP1822來檢測實現使用的存儲槽。以前的實現,現在已棄用,依賴於回滾檢查。可以從使用舊機制的合約升級到新機制。然而,反過來是不可能的,因為舊的實現(4.5 版之前)不包括該ERC1822接口。
這個抽象合約提供了一個回退函數,它使用 EVM 指令將所有調用委託給另一個合約delegatecall。我們將第二個合約稱為代理背後的實現,它必須通過覆蓋虛擬_implementation函數來指定。
此外,可以通過該函數手動觸發對實現的委託,也可以通過該函數觸發_fallback不同的合約_delegate。
委託調用的成功和返回數據將返回給代理的調用者。
FUNCTIONS
ERC1967Proxy
該合約實現了一個可升級的代理。它是可升級的,因為調用被委託給可以更改的實現地址。此地址存儲在 EIP1967指定位置的 storage 中,因此它不會與代理後面的實現的存儲佈局衝突。
ERC1967PROXY
ERC1967UPGRADE
管理員無法使用代理功能,所以應使用專用帳戶
輔助合約
這是一份輔助合同,旨在被指定為TransparentUpgradeableProxy. 有關為什麼要使用它的說明,請參閱TransparentUpgradeableProxy.
該合約實現了一個代理,該代理從UpgradeableBeacon.
信標地址存儲在 storage slotuint256(keccak256('eip1967.proxy.beacon')) - 1中,因此它不會與代理背後的實現的存儲佈局衝突。
UpgradeableBeacon