Last active
May 11, 2022 14:59
-
-
Save the-vampiire/1b4e8cd92b20dc4f034457c926210965 to your computer and use it in GitHub Desktop.
ERC165 interface IDs (ERC721 etc)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const INTERFACE_IDS = { | |
ERC165: '0x01ffc9a7', | |
ERC721: '0x80ac58cd', | |
ERC721Enumerable: '0x780e9d63', | |
ERC721Metadata: '0x5b5e139f', | |
ERC1155: '0xd9b67a26', | |
ERC1155Receiver: '0x4e2312e0', | |
AccessControl: '0x7965db0b', | |
AccessControlEnumerable: '0x5a05180f', | |
Governor: '0xbf26d897', | |
GovernorWithParams: '0x79dd796f', | |
GovernorTimelock: '0x6e665ced', | |
ERC2981: '0x2a55205a' | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// computed from open zeppelin | |
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/test/utils/introspection/SupportsInterface.behavior.js | |
// https://github.com/OpenZeppelin/openzeppelin-test-helpers/blob/master/src/makeInterfaceId.js | |
const { soliditySha3 } = require("web3-utils"); | |
const INTERFACES = { | |
ERC165: ["supportsInterface(bytes4)"], | |
ERC721: [ | |
"balanceOf(address)", | |
"ownerOf(uint256)", | |
"approve(address,uint256)", | |
"getApproved(uint256)", | |
"setApprovalForAll(address,bool)", | |
"isApprovedForAll(address,address)", | |
"transferFrom(address,address,uint256)", | |
"safeTransferFrom(address,address,uint256)", | |
"safeTransferFrom(address,address,uint256,bytes)", | |
], | |
ERC721Enumerable: [ | |
"totalSupply()", | |
"tokenOfOwnerByIndex(address,uint256)", | |
"tokenByIndex(uint256)", | |
], | |
ERC721Metadata: ["name()", "symbol()", "tokenURI(uint256)"], | |
ERC1155: [ | |
"balanceOf(address,uint256)", | |
"balanceOfBatch(address[],uint256[])", | |
"setApprovalForAll(address,bool)", | |
"isApprovedForAll(address,address)", | |
"safeTransferFrom(address,address,uint256,uint256,bytes)", | |
"safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)", | |
], | |
ERC1155Receiver: [ | |
"onERC1155Received(address,address,uint256,uint256,bytes)", | |
"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)", | |
], | |
AccessControl: [ | |
"hasRole(bytes32,address)", | |
"getRoleAdmin(bytes32)", | |
"grantRole(bytes32,address)", | |
"revokeRole(bytes32,address)", | |
"renounceRole(bytes32,address)", | |
], | |
AccessControlEnumerable: [ | |
"getRoleMember(bytes32,uint256)", | |
"getRoleMemberCount(bytes32)", | |
], | |
Governor: [ | |
"name()", | |
"version()", | |
"COUNTING_MODE()", | |
"hashProposal(address[],uint256[],bytes[],bytes32)", | |
"state(uint256)", | |
"proposalSnapshot(uint256)", | |
"proposalDeadline(uint256)", | |
"votingDelay()", | |
"votingPeriod()", | |
"quorum(uint256)", | |
"getVotes(address,uint256)", | |
"hasVoted(uint256,address)", | |
"propose(address[],uint256[],bytes[],string)", | |
"execute(address[],uint256[],bytes[],bytes32)", | |
"castVote(uint256,uint8)", | |
"castVoteWithReason(uint256,uint8,string)", | |
"castVoteBySig(uint256,uint8,uint8,bytes32,bytes32)", | |
], | |
GovernorWithParams: [ | |
"name()", | |
"version()", | |
"COUNTING_MODE()", | |
"hashProposal(address[],uint256[],bytes[],bytes32)", | |
"state(uint256)", | |
"proposalSnapshot(uint256)", | |
"proposalDeadline(uint256)", | |
"votingDelay()", | |
"votingPeriod()", | |
"quorum(uint256)", | |
"getVotes(address,uint256)", | |
"getVotesWithParams(address,uint256,bytes)", | |
"hasVoted(uint256,address)", | |
"propose(address[],uint256[],bytes[],string)", | |
"execute(address[],uint256[],bytes[],bytes32)", | |
"castVote(uint256,uint8)", | |
"castVoteWithReason(uint256,uint8,string)", | |
"castVoteWithReasonAndParams(uint256,uint8,string,bytes)", | |
"castVoteBySig(uint256,uint8,uint8,bytes32,bytes32)", | |
"castVoteWithReasonAndParamsBySig(uint256,uint8,string,bytes,uint8,bytes32,bytes32)", | |
], | |
GovernorTimelock: [ | |
"timelock()", | |
"proposalEta(uint256)", | |
"queue(address[],uint256[],bytes[],bytes32)", | |
], | |
ERC2981: ["royaltyInfo(uint256,uint256)"], | |
}; | |
function ERC165(functionSignatures = []) { | |
const INTERFACE_ID_LENGTH = 4; | |
const interfaceIdBuffer = functionSignatures | |
.map((signature) => soliditySha3(signature)) // keccak256 | |
.map( | |
(h) => Buffer.from(h.substring(2), "hex").slice(0, 4) // bytes4() | |
) | |
.reduce((memo, bytes) => { | |
for (let i = 0; i < INTERFACE_ID_LENGTH; i++) { | |
memo[i] = memo[i] ^ bytes[i]; // xor | |
} | |
return memo; | |
}, Buffer.alloc(INTERFACE_ID_LENGTH)); | |
return `0x${interfaceIdBuffer.toString("hex")}`; | |
} | |
const INTERFACE_IDS = {}; | |
const FN_SIGNATURES = {}; | |
for (const k of Object.getOwnPropertyNames(INTERFACES)) { | |
INTERFACE_IDS[k] = ERC165(INTERFACES[k]); | |
for (const fnName of INTERFACES[k]) { | |
// the interface id of a single function is equivalent to its function signature | |
FN_SIGNATURES[fnName] = ERC165([fnName]); | |
} | |
} | |
console.log({ | |
INTERFACE_IDS, | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment