Solidity
如何為非抽象合約做supportsInterface
我有以下情況。
contract GovernanceERC20 is ERC165Upgradeable, ERC20VotesUpgradeable, { bytes4 private constant GOVERNANCE_INTERFACE_ID; /// @inheritdoc ERC165Upgradeable function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == GOVERNANCE_INTERFACE_ID || interfaceId == type(IERC20Upgradeable).interfaceId || interfaceId == type(IERC20PermitUpgradeable).interfaceId || interfaceId == type(IERC20MetadataUpgradeable).interfaceId || interfaceId == type(ERC20VotesUpgradeable).interfaceId || super.supportsInterface(interfaceId); } function initialize() public view returns(uint) { return 10; } function mint(address to, uint256 amount) external { _mint(to, amount); } function great() public view returns(uint) { return 10; } }
如您所見,我在想
GOVERNANCE_INTERFACE_ID
應該是什麼。方式 1:我不能做
GOVERNANCE_INTERFACE_ID = type(GovernanceERC20).interfaceId as
GovernanceERC20` 不是抽象的。方式 2:我不想為
GovernanceERC20
.應該
GOVERNANCE_INTERFACE_ID
是什麼?選項 A:
GOVERNANCE_INTERFACE_ID = this.initialize.selector ^ this.great.selector ^ this.mint.selector;
選項 B:
GOVERNANCE_INTERFACE_ID = type(IERC20Upgradeable).interfaceId ^ type(IERC20PermitUpgradeable).interfaceId ^ type(IERC20MetadataUpgradeable).interfaceId ^ type(ERC20VotesUpgradeable).interfaceId ^ this.initialize.selector ^ this.great.selector ^ this.mint.selector;
嚴格來說,只要它不與其他標識符衝突,它並不重要。
您可能知道,EIP-165指定瞭如何確定合約來實現介面。它有一個例子:
return i.hello.selector ^ i.world.selector;
. 所以基本上將其功能的選擇器異或在一起。有一個EIP-881包含更多細節,但尚未最終確定。至於您的選項A和B,選項A更符合介面中ID的計算方式:介面不關心其他介面實現了什麼,ID只說明該特定介面支持什麼。因此,檢查多個
supportsInterface
ID 以查看實現支持的所有功能通常很有用。從這個意義上說,我會選擇選項 A。我不確定您為什麼不想只為您的額外功能添加一個介面,但我仍然會以與從介面相同的方式計算 ID。所以選項A。