/**
* @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
* implementation address that can be changed. This address is stored in storage in the location specified by
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the
* implementation behind the proxy.
* @dev 此合约实现了一个可升级的代理。 它是可升级的,因为调用被委托给一个可以更改的实现地址。
* @dev 此地址存储在 https://eips.ethereum.org/EIPS/eip-1967[EIP1967] 指定的位置的存储中,
* @dev 以便它不会与代理后面实现的存储布局冲突。
*/contractERC1967ProxyisProxy,ERC1967Upgrade{/**
* @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.
* @dev 使用 `_logic` 指定的初始实现来初始化可升级代理。
*
* If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded
* function call, and allows initializing the storage of the proxy like a Solidity constructor.
* 如果 `_data` 不为空,它将用作委托调用 `_logic` 中的数据。 这通常是一个编码的函数调用,
* 并且允许像 Solidity 构造函数一样初始化代理的存储。
*/constructor(address_logic,bytesmemory_data)payable{assert(_IMPLEMENTATION_SLOT==bytes32(uint256(keccak256("eip1967.proxy.implementation"))-1));_upgradeToAndCall(_logic,_data,false);}/**
* @dev Returns the current implementation address.
* @dev 返回当前的实现地址。
*/function_implementation()internalviewvirtualoverridereturns(addressimpl){returnERC1967Upgrade._getImplementation();}}/**
* @dev This abstract contract provides getters and event emitting update functions for
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
* @dev 这个抽象合约为 https://eips.ethereum.org/EIPS/eip-1967[EIP1967] 插槽提供了 getter 和事件发射更新函数。
*/abstractcontractERC1967Upgrade{// This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
// 这是 "eip1967.proxy.rollback" 的 keccak-256 哈希值减 1
bytes32privateconstant_ROLLBACK_SLOT=0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
* @dev 具有当前实现地址的存储槽。
* @dev 这是 "eip1967.proxy.implementation" 的 keccak-256 哈希值减 1,并在构造函数中进行验证。
*/bytes32internalconstant_IMPLEMENTATION_SLOT=0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;/**
* @dev Emitted when the implementation is upgraded.
* @dev 当实现被升级时发出。
*/eventUpgraded(addressindexedimplementation);/**
* @dev Returns the current implementation address.
* @dev 返回当前的实现地址。
*/function_getImplementation()internalviewreturns(address){returnStorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;}/**
* @dev Stores a new address in the EIP1967 implementation slot.
* @dev 在 EIP1967 实现槽中存储一个新地址。
*/function_setImplementation(addressnewImplementation)private{require(Address.isContract(newImplementation),"ERC1967: new implementation is not a contract");StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value=newImplementation;}/**
* @dev Perform implementation upgrade
* @dev 执行实现升级
*
* Emits an {Upgraded} event.
* 发出 {Upgraded} 事件。
*/function_upgradeTo(addressnewImplementation)internal{_setImplementation(newImplementation);emitUpgraded(newImplementation);}/**
* @dev Perform implementation upgrade with additional setup call.
* @dev 使用额外的设置调用执行实现升级。
*
* Emits an {Upgraded} event.
* 发出 {Upgraded} 事件。
*/function_upgradeToAndCall(addressnewImplementation,bytesmemorydata,boolforceCall)internal{_upgradeTo(newImplementation);if(data.length>0||forceCall){Address.functionDelegateCall(newImplementation,data);}}/**
* @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
* @dev 对 UUPS 代理执行带有安全检查的实现升级,并带有额外的设置调用。
*
* Emits an {Upgraded} event.
* 发出 {Upgraded} 事件。
*/function_upgradeToAndCallSecure(addressnewImplementation,bytesmemorydata,boolforceCall)internal{addressoldImplementation=_getImplementation();// Initial upgrade and setup call
// 初始升级和设置调用
_setImplementation(newImplementation);if(data.length>0||forceCall){Address.functionDelegateCall(newImplementation,data);}// Perform rollback test if not already in progress
// 如果尚未进行,则执行回滚测试
StorageSlot.BooleanSlotstoragerollbackTesting=StorageSlot.getBooleanSlot(_ROLLBACK_SLOT);if(!rollbackTesting.value){// Trigger rollback using upgradeTo from the new implementation
// 使用来自新实现的 upgradeTo 触发回滚
rollbackTesting.value=true;Address.functionDelegateCall(newImplementation,abi.encodeWithSignature("upgradeTo(address)",oldImplementation));rollbackTesting.value=false;// Check rollback was effective
// 检查回滚是否有效
require(oldImplementation==_getImplementation(),"ERC1967Upgrade: upgrade breaks further upgrades");// Finally reset to the new implementation and log the upgrade
// 最后重置为新的实现并记录升级
_upgradeTo(newImplementation);}}/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
* validated in the constructor.
* @dev 具有合约管理地址的存储槽。
* @dev 这是 "eip1967.proxy.admin" 的 keccak-256 哈希值减 1,并在构造函数中进行验证。
*/bytes32internalconstant_ADMIN_SLOT=0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;/**
* @dev Emitted when the admin account has changed.
* @dev 当 admin 帐户已更改时发出。
*/eventAdminChanged(addresspreviousAdmin,addressnewAdmin);/**
* @dev Returns the current admin.
* @dev 返回当前的 admin。
*/function_getAdmin()internalviewreturns(address){returnStorageSlot.getAddressSlot(_ADMIN_SLOT).value;}/**
* @dev Stores a new address in the EIP1967 admin slot.
* @dev 在 EIP1967 admin 槽中存储一个新地址。
*/function_setAdmin(addressnewAdmin)private{require(newAdmin!=address(0),"ERC1967: new admin is the zero address");StorageSlot.getAddressSlot(_ADMIN_SLOT).value=newAdmin;}/**
* @dev Changes the admin of the proxy.
* @dev 更改代理的 admin。
*
* Emits an {AdminChanged} event.
* 发出 {AdminChanged} 事件。
*/function_changeAdmin(addressnewAdmin)internal{emitAdminChanged(_getAdmin(),newAdmin);_setAdmin(newAdmin);}/**
* @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
* This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.
* @dev UpgradeableBeacon 合约的存储槽,它定义了此代理的实现。
* @dev 这是 bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) 并在构造函数中进行验证。
*/bytes32internalconstant_BEACON_SLOT=0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;/**
* @dev Emitted when the beacon is upgraded.
* @dev 当信标升级时发出。
*/eventBeaconUpgraded(addressindexedbeacon);/**
* @dev Returns the current beacon.
* @dev 返回当前的信标。
*/function_getBeacon()internalviewreturns(address){returnStorageSlot.getAddressSlot(_BEACON_SLOT).value;}/**
* @dev Stores a new beacon in the EIP1967 beacon slot.
* @dev 将新信标存储在 EIP1967 信标槽中。
*/function_setBeacon(addressnewBeacon)private{require(Address.isContract(newBeacon),"ERC1967: new beacon is not a contract");require(Address.isContract(IBeacon(newBeacon).implementation()),"ERC1967: beacon implementation is not a contract");StorageSlot.getAddressSlot(_BEACON_SLOT).value=newBeacon;}/**
* @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
* not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
* @dev 执行带有额外设置调用的信标升级。 注意:这会升级信标的地址,而不会升级信标中包含的实现(请参阅 {UpgradeableBeacon-_setImplementation})。
*
* Emits a {BeaconUpgraded} event.
* 发出 {BeaconUpgraded} 事件。
*/function_upgradeBeaconToAndCall(addressnewBeacon,bytesmemorydata,boolforceCall)internal{_setBeacon(newBeacon);emitBeaconUpgraded(newBeacon);if(data.length>0||forceCall){Address.functionDelegateCall(IBeacon(newBeacon).implementation(),data);}}}/**
* @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
* instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
* be specified by overriding the virtual {_implementation} function.
* @dev 这个抽象合约提供了一个回退函数,它使用 EVM 指令 `delegatecall` 将所有调用委托给另一个合约。
* @dev 我们将代理后面的第二个合约称为_实现_,它必须通过覆盖虚拟的 {_implementation} 函数来指定。
*
* Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
* different contract through the {_delegate} function.
* 此外,可以通过 {_fallback} 函数手动触发对实现的委托,或者通过 {_delegate} 函数触发对不同合约的委托。
*
* The success and return data of the delegated call will be returned back to the caller of the proxy.
* 委托调用的成功和返回数据将返回给代理的调用者。
*/abstractcontractProxy{/**
* @dev Delegates the current call to `implementation`.
* @dev 将当前调用委托给 `implementation`。
*
* This function does not return to its internal call site, it will return directly to the external caller.
* 此函数不会返回到其内部调用站点,它将直接返回到外部调用者。
*/function_delegate(addressimplementation)internalvirtual{assembly{// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
// 复制 msg.data。 我们在这个内联汇编块中完全控制内存,因为它不会返回到 Solidity 代码。
// 我们覆盖内存位置 0 处的 Solidity 草稿板。
calldatacopy(0,0,calldatasize())// Call the implementation.
// out and outsize are 0 because we don't know the size yet.
// 调用实现。
// out 和 outsize 为 0,因为我们还不知道大小。
letresult:=delegatecall(gas(),implementation,0,calldatasize(),0,0)// Copy the returned data.
// 复制返回的数据。
returndatacopy(0,0,returndatasize())switchresult// delegatecall returns 0 on error.
// delegatecall 在出错时返回 0。
case0{revert(0,returndatasize())}default{return(0,returndatasize())}}}/**
* @dev This is a virtual function that should be overridden so it returns the address to which the fallback function
* and {_fallback} should delegate.
* @dev 这是一个虚拟函数,应该被覆盖,以便它返回回退函数和 {_fallback} 应该委托到的地址。
*/function_implementation()internalviewvirtualreturns(address);/**
* @dev Delegates the current call to the address returned by `_implementation()`.
* @dev 将当前调用委托给 `_implementation()` 返回的地址。
*
* This function does not return to its internal call site, it will return directly to the external caller.
* 此函数不会返回到其内部调用站点,它将直接返回到外部调用者。
*/function_fallback()internalvirtual{_beforeFallback();_delegate(_implementation());}/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
* function in the contract matches the call data.
* @dev 回退函数,它将调用委托给 `_implementation()` 返回的地址。
* @dev 如果合约中没有其他函数与调用数据匹配,则将运行。
*/fallback()externalpayablevirtual{_fallback();}/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
* is empty.
* @dev 回退函数,它将调用委托给 `_implementation()` 返回的地址。
* @dev 如果调用数据为空,则将运行。
*/receive()externalpayablevirtual{_fallback();}/**
* @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`
* call, or as part of the Solidity `fallback` or `receive` functions.
* @dev 在回退到实现之前调用的 Hook。
* @dev 可以作为手动 `_fallback` 调用的一部分发生,也可以作为 Solidity `fallback` 或 `receive` 函数的一部分发生。
*
* If overridden should call `super._beforeFallback()`.
* 如果被覆盖,应该调用 `super._beforeFallback()`。
*/function_beforeFallback()internalvirtual{}}/**
* @dev Library for reading and writing primitive types to specific storage slots.
* @dev 用于读取和写入原始类型到特定存储槽的库。
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
* 存储槽通常用于避免在处理可升级合约时出现存储冲突。
* 该库有助于读取和写入此类槽,而无需内联汇编。
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
* 此库中的函数返回包含 `value` 成员的 Slot 结构,该成员可用于读取或写入。
*/libraryStorageSlot{structAddressSlot{addressvalue;}structBooleanSlot{boolvalue;}structBytes32Slot{bytes32value;}structUint256Slot{uint256value;}/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
* @dev 返回一个 `AddressSlot`,其成员 `value` 位于 `slot`。
*/functiongetAddressSlot(bytes32slot)internalpurereturns(AddressSlotstorager){assembly{r.slot:=slot}}/**
* @dev Returns an `BooleanSlot` with member `value` located at `slot`.
* @dev 返回一个 `BooleanSlot`,其成员 `value` 位于 `slot`。
*/functiongetBooleanSlot(bytes32slot)internalpurereturns(BooleanSlotstorager){assembly{r.slot:=slot}}/**
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
* @dev 返回一个 `Bytes32Slot`,其成员 `value` 位于 `slot`。
*/functiongetBytes32Slot(bytes32slot)internalpurereturns(Bytes32Slotstorager){assembly{r.slot:=slot}}/**
* @dev Returns an `Uint256Slot` with member `value` located at `slot`.
* @dev 返回一个 `Uint256Slot`,其成员 `value` 位于 `slot`。
*/functiongetUint256Slot(bytes32slot)internalpurereturns(Uint256Slotstorager){assembly{r.slot:=slot}}}