{"action":"created","comment":{"url":"https://api.github.com/repos/ethereum/EIPs/pulls/comments/168738822","pull_request_review_id":97156550,"id":168738822,"diff_hunk":"@@ -0,0 +1,230 @@\n+## Preamble\n+\n+```\n+EIP: <to be assigned>\n+Title: ERC-165 Standard Interface Detection\n+Author: Christian Reitwießner <chris@ethereum.org>, Nick Johnson <nick@ethereum.org>, RJ Catalano <rj@monax.io>, Fabian Vogelsteller <fabian@frozeman.de>, Hudson Jameson <hudson@hudsonjameson.com>, Jordi Baylina <jordi@baylina.cat>, Griff Green <saveoursonics@gmail.com>, Konrad Feldmeier <konrad.feldmeier@brainbot.com>, William Entriken <github.com@phor.net>\n+Type: Standard Track\n+Category: ERC\n+Status: Draft\n+Created: 2018-01-23\n+```\n+\n+## Simple Summary\n+\n+Creates a standard method to publish and detect what interfaces a smart contract implements.\n+\n+## Abstract\n+\n+Herein, we standardize the following:\n+\n+1. How interfaces are identified\n+2. How a contract will publish the interfaces it implements\n+3. How to detect if a contract implements ERC-165\n+4. How to detect if a contract implements any given interface\n+\n+## Motivation\n+\n+For some \"standard interfaces\" like [the ERC-20 token interface](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md), it is sometimes useful to query whether a contract supports the interface and if yes, which version of the interface, in order to adapt the way in which the contract is to be interfaced with. Specifically for ERC-20, a version identifier has already been proposed. This proposal stadardizes the concept of interfaces and standardizes the identification (naming) of interfaces.\n+\n+## Specification\n+\n+### How Interfaces are Identified\n+\n+For this standard, an *interface* is a set of [function selectors as calculated in Solidity](http://solidity.readthedocs.io/en/develop/abi-spec.html#function-selector). This a subset of [Solidity's concept of interfaces](http://solidity.readthedocs.io/en/develop/abi-spec.html) and the  `interface` keyword definition which also define return types, mutability and events.","path":"EIPS/eip-165.md","position":null,"original_position":34,"commit_id":"ad70b8d27686de2b324491b1a7f6667963f5aa2e","original_commit_id":"50f59da47f40c76c433e9bd54c00a4a44aa78d18","user":{"login":"fulldecent","id":382183,"avatar_url":"https://avatars0.githubusercontent.com/u/382183?v=4","gravatar_id":"","url":"https://api.github.com/users/fulldecent","html_url":"https://github.com/fulldecent","followers_url":"https://api.github.com/users/fulldecent/followers","following_url":"https://api.github.com/users/fulldecent/following{/other_user}","gists_url":"https://api.github.com/users/fulldecent/gists{/gist_id}","starred_url":"https://api.github.com/users/fulldecent/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fulldecent/subscriptions","organizations_url":"https://api.github.com/users/fulldecent/orgs","repos_url":"https://api.github.com/users/fulldecent/repos","events_url":"https://api.github.com/users/fulldecent/events{/privacy}","received_events_url":"https://api.github.com/users/fulldecent/received_events","type":"User","site_admin":false},"body":"Updated: \"function selectors as defined by the Ethereum ABI\"","created_at":"2018-02-16T11:58:54Z","updated_at":"2018-02-16T11:58:55Z","html_url":"https://github.com/ethereum/EIPs/pull/881#discussion_r168738822","pull_request_url":"https://api.github.com/repos/ethereum/EIPs/pulls/881","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/ethereum/EIPs/pulls/comments/168738822"},"html":{"href":"https://github.com/ethereum/EIPs/pull/881#discussion_r168738822"},"pull_request":{"href":"https://api.github.com/repos/ethereum/EIPs/pulls/881"}},"in_reply_to_id":168735859},"pull_request":{"url":"https://api.github.com/repos/ethereum/EIPs/pulls/881","id":168772717,"html_url":"https://github.com/ethereum/EIPs/pull/881","diff_url":"https://github.com/ethereum/EIPs/pull/881.diff","patch_url":"https://github.com/ethereum/EIPs/pull/881.patch","issue_url":"https://api.github.com/repos/ethereum/EIPs/issues/881","number":881,"state":"open","locked":false,"title":"ERC-165 Standard Interface Detection","user":{"login":"fulldecent","id":382183,"avatar_url":"https://avatars0.githubusercontent.com/u/382183?v=4","gravatar_id":"","url":"https://api.github.com/users/fulldecent","html_url":"https://github.com/fulldecent","followers_url":"https://api.github.com/users/fulldecent/followers","following_url":"https://api.github.com/users/fulldecent/following{/other_user}","gists_url":"https://api.github.com/users/fulldecent/gists{/gist_id}","starred_url":"https://api.github.com/users/fulldecent/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fulldecent/subscriptions","organizations_url":"https://api.github.com/users/fulldecent/orgs","repos_url":"https://api.github.com/users/fulldecent/repos","events_url":"https://api.github.com/users/fulldecent/events{/privacy}","received_events_url":"https://api.github.com/users/fulldecent/received_events","type":"User","site_admin":false},"body":"**Reference**\r\n\r\n* The original ERC-165 issue https://github.com/ethereum/EIPs/issues/165\r\n\r\n**Work plan**\r\n\r\n- [x] Need a best practice test case\r\n   - [x] Update EIP165Cache from @jbaylina, https://github.com/jbaylina/EIP165Cache/issues/1, https://github.com/jbaylina/EIP165Cache/issues/2, https://github.com/jbaylina/EIP165Cache/issues/3, https://github.com/jbaylina/EIP165Cache/issues/4\r\n- [x] Add implementations\r\n   - [x] Add an example using the `mapping(bytes4=>bool)` approach (this is O(1) gas)\r\n   - [x] Add an example using the `interfaceId == a || interfaceId == b || ...` approach (this is O(n) gas)\r\n   - [x] Compare the gas costs, when does the O(n) exceed the O(1)?\r\n- [ ] Get to draft status\r\n- [ ] Prepare to deploy the caching contract to all networks using the same deploy address\r\n- [ ] Get to approved\r\n- [ ] Actually deploy the caching contract to all networks using the same deploy address\r\n\r\nBELOW IS A COMPLETE COPY OF THE [LATEST FULL TEXT PROPOSAL](https://github.com/fulldecent/EIPs/blob/patch-4/EIPS/eip-165.md) **(VERSION 529ce1b)** FOR YOUR CONVENIENCE.\r\n\r\n---\r\n\r\n---\r\n\r\n## Preamble\r\n\r\n```\r\nEIP: <to be assigned>\r\nTitle: ERC-165 Standard Interface Detection\r\nAuthor: Christian Reitwießner <chris@ethereum.org>, Nick Johnson <nick@ethereum.org>, RJ Catalano <rj@monax.io>, Fabian Vogelsteller <fabian@frozeman.de>, Hudson Jameson <hudson@hudsonjameson.com>, Jordi Baylina <jordi@baylina.cat>, Griff Green <saveoursonics@gmail.com>, Konrad Feldmeier <konrad.feldmeier@brainbot.com>, William Entriken <github.com@phor.net>\r\nType: Standard Track\r\nCategory: ERC\r\nStatus: Draft\r\nCreated: 2018-01-23\r\n```\r\n\r\n## Simple Summary\r\n\r\nCreates a standard method to publish and detect what interfaces a smart contract implements.\r\n\r\n## Abstract\r\n\r\nHerein, we standardize the following:\r\n\r\n1. How interfaces are identified\r\n2. How a contract will publish the interfaces it implements\r\n3. How to detect if a contract implements ERC-165\r\n4. How to detect if a contract implements any given interface\r\n\r\n## Motivation\r\n\r\nFor some \"standard interfaces\" like [the ERC-20 token interface](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md), it is sometimes useful to query whether a contract supports the interface and if yes, which version of the interface, in order to adapt the way in which the contract is to be interfaced with. Specifically for ERC-20, a version identifier has already been proposed. This proposal stadardizes the concept of interfaces and standardizes the identification (naming) of interfaces.\r\n\r\n## Specification\r\n\r\n### How Interfaces are Identified\r\n\r\nFor this standard, an *interface* is a set of [function selectors as calculated in Solidity](http://solidity.readthedocs.io/en/develop/abi-spec.html#function-selector). This a subset of [Solidity's concept of interfaces](http://solidity.readthedocs.io/en/develop/abi-spec.html) and the  `interface` keyword definition which also define return types, mutability and events.\r\n\r\nWe define the interface identifier as the XOR of all function selectors in the interface. This code example shows how to calculate an interface identifier:\r\n\r\n```solidity\r\npragma solidity ^0.4.20;\r\n\r\ninterface Solidity101 {\r\n    function hello() external pure;\r\n    function world(int) external pure;\r\n}\r\n\r\ncontract Selector {\r\n    function calculateSelector() public pure returns (bytes4) {\r\n        Solidity101 i;\r\n        return i.hello.selector ^ i.world.selector;\r\n    }\r\n}\r\n```\r\n\r\nNote: interfaces do not permit optional functions, therefore, the interface identity will not them.\r\n\r\n### How a Contract will Publish the Interfaces it Implements\r\n\r\nA contract that is compliant with ERC-165 shall implement the following interface (referred as `ERC165.sol`):\r\n\r\n```solidity\r\npragma solidity ^0.4.20;\r\n\r\ninterface ERC165 {\r\n    /// @notice Query if a contract implements an interface\r\n    /// @param interfaceID The interface identifier, as specified in ERC-165\r\n    /// @dev Interface identification is specified in ERC-165. This function\r\n    ///  use less than 30000 gas.\r\n    /// @return `true` if the contract implements `interfaceID` and\r\n    ///  `interfaceID` is not 0xffffffff, `false` otherwise\r\n    function supportsInterface(bytes4 interfaceID) external view returns (bool);\r\n}\r\n```\r\n\r\nThe interface identifier for this interface is `0x01ffc9a7`. You can calculate this by running `        bytes4(keccak256('supportsInterface(bytes4)'));` or using the `Selector` contract above.\r\n\r\nTherefore the implementing contract will have a `supportsInterface` function that returns:\r\n\r\n- `true` when `interfaceID` is `0x01ffc9a7` (EIP165 interface)\r\n- `false` when `interfaceID` is `0xffffffff`\r\n- `true` for any other `interfaceID` this contract implements\r\n- `false` for any other `interfaceID`\r\n\r\nThis function must return a bool and use at most 30000 gas.\r\n\r\nImplementation note, there are several logical ways to implement this function. Please see the example implementations and the discussion on gas usage.\r\n\r\n### How to Detect if a Contract Implements ERC-165\r\n\r\n1. The source contact makes a static `CALL` to the destination address with input data: `0x01ffc9a701ffc9a7` value: 0 and gas 30000. This corresponds to `contract.supportsInterface(\"0x01ffc9a7\")`.\r\n2. If the call fails or return false, the destination contract does not implement ERC-165.\r\n3. If the call returns true, a second call is made with input data `0x01ffc9a7ffffffff`.\r\n4. If the second call fails or returns true, the destination contract does not implement ERC-165.\r\n5. Otherwise it implements EIP165.\r\n\r\n### How to Detect if a Contract Implements any Given Interface\r\n\r\n1. If you are not sure if the contract implements ERC-165 Interface, use the previous procedure to confirm.\r\n2. If it does not implement ERC-165, then you will have to see what methods it uses the old fashioned way.\r\n3. If it implements ERC-165 then just call `supportsInterface(interfaceID)` to determine if it implements an interface you can use.\r\n\r\n## Rationale\r\n\r\nWe tried to keep this specification as simple as possible. This implementation is also compatible with the current Solidity version.\r\n\r\n## Backwards Compatibility\r\n\r\nThe mechanism described above (with `0xffffffff`) should work with most of the contracts previous to this standard to determine that they do not implement ERC-165.\r\n\r\nAlso [the ENS](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-137.md) already implements this EIP.\r\n\r\n## Test Cases\r\n\r\nFollowing is a caching contract that detects which interfaces other contracts implement. From @fulldecent and @jbaylina.\r\n\r\n```solidity\r\npragma solidity ^0.4.20;\r\n\r\ncontract ERC165Cache {\r\n    bytes4 constant InvalidID = 0xffffffff;\r\n    bytes4 constant ERC165ID = 0x01ffc9a7;\r\n\r\n    enum ImplStatus { Unknown, No, Yes }\r\n    mapping (address => mapping (bytes4 => ImplStatus)) cache;\r\n\r\n    // Return value from cache if available\r\n    function interfaceSupported(address _contract, bytes4 _interfaceId) external returns (bool) {\r\n        ImplStatus status = cache[_contract][_interfaceId];\r\n        if (status == ImplStatus.Unknown) {\r\n            return checkInterfaceSupported(_contract, _interfaceId);\r\n        }\r\n        return status == ImplStatus.Yes;\r\n    }\r\n\r\n    // Repull result into cache\r\n    function checkInterfaceSupported(address _contract, bytes4 _interfaceId) public returns (bool) {\r\n        ImplStatus status = determineInterfaceImplementationStatus(_contract, _interfaceId);\r\n        cache[_contract][_interfaceId] = status;\r\n        return status == ImplStatus.Yes;\r\n    }\r\n\r\n    function determineInterfaceImplementationStatus(address _contract, bytes4 _interfaceId) internal view returns (ImplStatus) {\r\n        uint256 success;\r\n        uint256 result;\r\n        \r\n        (success, result) = noThrowCall(_contract, ERC165ID);\r\n        if ((success==0)||(result==0)) {\r\n            return ImplStatus.No;\r\n        }\r\n\r\n        (success, result) = noThrowCall(_contract, InvalidID);\r\n        if ((success==0)||(result!=0)) {\r\n            return ImplStatus.No;\r\n        }\r\n\r\n        (success, result) = noThrowCall(_contract, _interfaceId);\r\n        if ((success==1)&&(result==1)) {\r\n            return ImplStatus.Yes;\r\n        }\r\n        return ImplStatus.No;\r\n    }\r\n\r\n    function noThrowCall(address _contract, bytes4 _interfaceId) constant internal returns (uint256 success, uint256 result) {\r\n        bytes4 erc165ID = ERC165ID;\r\n\r\n        assembly {\r\n                let x := mload(0x40)               // Find empty storage location using \"free memory pointer\"\r\n                mstore(x, erc165ID)                // Place signature at begining of empty storage\r\n                mstore(add(x, 0x04), _interfaceId) // Place first argument directly next to signature\r\n\r\n                success := staticcall(\r\n                                    30000,         // 5k gas\r\n                                    _contract,     // To addr\r\n                                    x,             // Inputs are stored at location x\r\n                                    0x8,           // Inputs are 8 byes long\r\n                                    x,             // Store output over input (saves space)\r\n                                    0x20)          // Outputs are 32 bytes long\r\n\r\n                result := mload(x)                 // Load the result\r\n        }\r\n    }\r\n}\r\n```\r\n\r\n## Implementation\r\n\r\nThis approach uses a `view` function implementation of `supportsInterface`. The execution cost is 586 gas for any input. But contract initialization requires storing each interface (`SSTORE` is 20,000 gas). The `ERC165MappingImplementation` contract is generic and reusable.\r\n\r\n```solidity\r\npragma solidity ^0.4.19;\r\n\r\nimport \"./ERC165.sol\";\r\n\r\ncontract ERC165MappingImplementation is ERC165 {\r\n    /// @dev You must not set element 0xffffffff to true\r\n    mapping(bytes4 => bool) internal supportedInterfaces;\r\n\r\n    function ERC165MappingImplementation() internal {\r\n        supportedInterfaces[this.supportsInterface.selector] = true;\r\n    }\r\n\r\n    function supportsInterface(bytes4 interfaceID) external view returns (bool) {\r\n        return supportedInterfaces[interfaceID];\r\n    }\r\n}\r\n\r\ninterface Simpson {\r\n    function is2D() external returns (bool);\r\n    function skinColor() external returns (string);\r\n}\r\n\r\ncontract Lisa is ERC165MappingImplementation, Simpson {\r\n    function Lisa() public {\r\n        supportedInterfaces[this.is2D.selector ^ this.skinColor.selector] = true;\r\n    }\r\n    \r\n    function is2D() external returns (bool){}\r\n    function skinColor() external returns (string){}\r\n}\r\n```\r\n\r\nFollowing is a `pure` function implementation of `supportsInterface`. The worst-case execution cost is 236 gas, but increases linearly with a higher number of supported interfaces.\r\n\r\n```solidity\r\npragma solidity ^0.4.19;\r\n\r\nimport \"./ERC165.sol\";\r\n\r\ninterface Simpson {\r\n    function is2D() external returns (bool);\r\n    function skinColor() external returns (string);\r\n}\r\n\r\ncontract Homer is ERC165, Simpson {\r\n    function supportsInterface(bytes4 interfaceID) external view returns (bool) {\r\n        return \r\n          interfaceID == this.supportsInterface.selector || // ERC165\r\n          interfaceID == this.is2D.selector \r\n                         ^ this.skinColor.selector; // Simpson\r\n    }\r\n}\r\n```\r\n\r\nWith three or more supported interfaces (including ERC165 itself as a required supported interface), the mapping table approach (for any case) costs less gas than the worst case for pure approach.\r\n\r\n## Copyright\r\n\r\nCopyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).","created_at":"2018-02-13T07:35:53Z","updated_at":"2018-02-16T11:58:55Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9a1cb006eef10c3abdf8a98f0397ba7f72e68dd5","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/ethereum/EIPs/pulls/881/commits","review_comments_url":"https://api.github.com/repos/ethereum/EIPs/pulls/881/comments","review_comment_url":"https://api.github.com/repos/ethereum/EIPs/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ethereum/EIPs/issues/881/comments","statuses_url":"https://api.github.com/repos/ethereum/EIPs/statuses/ad70b8d27686de2b324491b1a7f6667963f5aa2e","head":{"label":"fulldecent:patch-4","ref":"patch-4","sha":"ad70b8d27686de2b324491b1a7f6667963f5aa2e","user":{"login":"fulldecent","id":382183,"avatar_url":"https://avatars0.githubusercontent.com/u/382183?v=4","gravatar_id":"","url":"https://api.github.com/users/fulldecent","html_url":"https://github.com/fulldecent","followers_url":"https://api.github.com/users/fulldecent/followers","following_url":"https://api.github.com/users/fulldecent/following{/other_user}","gists_url":"https://api.github.com/users/fulldecent/gists{/gist_id}","starred_url":"https://api.github.com/users/fulldecent/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fulldecent/subscriptions","organizations_url":"https://api.github.com/users/fulldecent/orgs","repos_url":"https://api.github.com/users/fulldecent/repos","events_url":"https://api.github.com/users/fulldecent/events{/privacy}","received_events_url":"https://api.github.com/users/fulldecent/received_events","type":"User","site_admin":false},"repo":{"id":117486770,"name":"EIPs","full_name":"fulldecent/EIPs","owner":{"login":"fulldecent","id":382183,"avatar_url":"https://avatars0.githubusercontent.com/u/382183?v=4","gravatar_id":"","url":"https://api.github.com/users/fulldecent","html_url":"https://github.com/fulldecent","followers_url":"https://api.github.com/users/fulldecent/followers","following_url":"https://api.github.com/users/fulldecent/following{/other_user}","gists_url":"https://api.github.com/users/fulldecent/gists{/gist_id}","starred_url":"https://api.github.com/users/fulldecent/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fulldecent/subscriptions","organizations_url":"https://api.github.com/users/fulldecent/orgs","repos_url":"https://api.github.com/users/fulldecent/repos","events_url":"https://api.github.com/users/fulldecent/events{/privacy}","received_events_url":"https://api.github.com/users/fulldecent/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/fulldecent/EIPs","description":"The Ethereum Improvement Proposal","fork":true,"url":"https://api.github.com/repos/fulldecent/EIPs","forks_url":"https://api.github.com/repos/fulldecent/EIPs/forks","keys_url":"https://api.github.com/repos/fulldecent/EIPs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/fulldecent/EIPs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/fulldecent/EIPs/teams","hooks_url":"https://api.github.com/repos/fulldecent/EIPs/hooks","issue_events_url":"https://api.github.com/repos/fulldecent/EIPs/issues/events{/number}","events_url":"https://api.github.com/repos/fulldecent/EIPs/events","assignees_url":"https://api.github.com/repos/fulldecent/EIPs/assignees{/user}","branches_url":"https://api.github.com/repos/fulldecent/EIPs/branches{/branch}","tags_url":"https://api.github.com/repos/fulldecent/EIPs/tags","blobs_url":"https://api.github.com/repos/fulldecent/EIPs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/fulldecent/EIPs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/fulldecent/EIPs/git/refs{/sha}","trees_url":"https://api.github.com/repos/fulldecent/EIPs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/fulldecent/EIPs/statuses/{sha}","languages_url":"https://api.github.com/repos/fulldecent/EIPs/languages","stargazers_url":"https://api.github.com/repos/fulldecent/EIPs/stargazers","contributors_url":"https://api.github.com/repos/fulldecent/EIPs/contributors","subscribers_url":"https://api.github.com/repos/fulldecent/EIPs/subscribers","subscription_url":"https://api.github.com/repos/fulldecent/EIPs/subscription","commits_url":"https://api.github.com/repos/fulldecent/EIPs/commits{/sha}","git_commits_url":"https://api.github.com/repos/fulldecent/EIPs/git/commits{/sha}","comments_url":"https://api.github.com/repos/fulldecent/EIPs/comments{/number}","issue_comment_url":"https://api.github.com/repos/fulldecent/EIPs/issues/comments{/number}","contents_url":"https://api.github.com/repos/fulldecent/EIPs/contents/{+path}","compare_url":"https://api.github.com/repos/fulldecent/EIPs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/fulldecent/EIPs/merges","archive_url":"https://api.github.com/repos/fulldecent/EIPs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/fulldecent/EIPs/downloads","issues_url":"https://api.github.com/repos/fulldecent/EIPs/issues{/number}","pulls_url":"https://api.github.com/repos/fulldecent/EIPs/pulls{/number}","milestones_url":"https://api.github.com/repos/fulldecent/EIPs/milestones{/number}","notifications_url":"https://api.github.com/repos/fulldecent/EIPs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/fulldecent/EIPs/labels{/name}","releases_url":"https://api.github.com/repos/fulldecent/EIPs/releases{/id}","deployments_url":"https://api.github.com/repos/fulldecent/EIPs/deployments","created_at":"2018-01-15T02:21:45Z","updated_at":"2018-01-14T14:36:15Z","pushed_at":"2018-02-16T11:58:04Z","git_url":"git://github.com/fulldecent/EIPs.git","ssh_url":"git@github.com:fulldecent/EIPs.git","clone_url":"https://github.com/fulldecent/EIPs.git","svn_url":"https://github.com/fulldecent/EIPs","homepage":"","size":935,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":1,"license":null,"forks":1,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"ethereum:master","ref":"master","sha":"b943077ce8febb2aef149daeb907023d3e84e67f","user":{"login":"ethereum","id":6250754,"avatar_url":"https://avatars3.githubusercontent.com/u/6250754?v=4","gravatar_id":"","url":"https://api.github.com/users/ethereum","html_url":"https://github.com/ethereum","followers_url":"https://api.github.com/users/ethereum/followers","following_url":"https://api.github.com/users/ethereum/following{/other_user}","gists_url":"https://api.github.com/users/ethereum/gists{/gist_id}","starred_url":"https://api.github.com/users/ethereum/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ethereum/subscriptions","organizations_url":"https://api.github.com/users/ethereum/orgs","repos_url":"https://api.github.com/users/ethereum/repos","events_url":"https://api.github.com/users/ethereum/events{/privacy}","received_events_url":"https://api.github.com/users/ethereum/received_events","type":"Organization","site_admin":false},"repo":{"id":44971752,"name":"EIPs","full_name":"ethereum/EIPs","owner":{"login":"ethereum","id":6250754,"avatar_url":"https://avatars3.githubusercontent.com/u/6250754?v=4","gravatar_id":"","url":"https://api.github.com/users/ethereum","html_url":"https://github.com/ethereum","followers_url":"https://api.github.com/users/ethereum/followers","following_url":"https://api.github.com/users/ethereum/following{/other_user}","gists_url":"https://api.github.com/users/ethereum/gists{/gist_id}","starred_url":"https://api.github.com/users/ethereum/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ethereum/subscriptions","organizations_url":"https://api.github.com/users/ethereum/orgs","repos_url":"https://api.github.com/users/ethereum/repos","events_url":"https://api.github.com/users/ethereum/events{/privacy}","received_events_url":"https://api.github.com/users/ethereum/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ethereum/EIPs","description":"The Ethereum Improvement Proposal","fork":false,"url":"https://api.github.com/repos/ethereum/EIPs","forks_url":"https://api.github.com/repos/ethereum/EIPs/forks","keys_url":"https://api.github.com/repos/ethereum/EIPs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ethereum/EIPs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ethereum/EIPs/teams","hooks_url":"https://api.github.com/repos/ethereum/EIPs/hooks","issue_events_url":"https://api.github.com/repos/ethereum/EIPs/issues/events{/number}","events_url":"https://api.github.com/repos/ethereum/EIPs/events","assignees_url":"https://api.github.com/repos/ethereum/EIPs/assignees{/user}","branches_url":"https://api.github.com/repos/ethereum/EIPs/branches{/branch}","tags_url":"https://api.github.com/repos/ethereum/EIPs/tags","blobs_url":"https://api.github.com/repos/ethereum/EIPs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ethereum/EIPs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ethereum/EIPs/git/refs{/sha}","trees_url":"https://api.github.com/repos/ethereum/EIPs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ethereum/EIPs/statuses/{sha}","languages_url":"https://api.github.com/repos/ethereum/EIPs/languages","stargazers_url":"https://api.github.com/repos/ethereum/EIPs/stargazers","contributors_url":"https://api.github.com/repos/ethereum/EIPs/contributors","subscribers_url":"https://api.github.com/repos/ethereum/EIPs/subscribers","subscription_url":"https://api.github.com/repos/ethereum/EIPs/subscription","commits_url":"https://api.github.com/repos/ethereum/EIPs/commits{/sha}","git_commits_url":"https://api.github.com/repos/ethereum/EIPs/git/commits{/sha}","comments_url":"https://api.github.com/repos/ethereum/EIPs/comments{/number}","issue_comment_url":"https://api.github.com/repos/ethereum/EIPs/issues/comments{/number}","contents_url":"https://api.github.com/repos/ethereum/EIPs/contents/{+path}","compare_url":"https://api.github.com/repos/ethereum/EIPs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ethereum/EIPs/merges","archive_url":"https://api.github.com/repos/ethereum/EIPs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ethereum/EIPs/downloads","issues_url":"https://api.github.com/repos/ethereum/EIPs/issues{/number}","pulls_url":"https://api.github.com/repos/ethereum/EIPs/pulls{/number}","milestones_url":"https://api.github.com/repos/ethereum/EIPs/milestones{/number}","notifications_url":"https://api.github.com/repos/ethereum/EIPs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ethereum/EIPs/labels{/name}","releases_url":"https://api.github.com/repos/ethereum/EIPs/releases{/id}","deployments_url":"https://api.github.com/repos/ethereum/EIPs/deployments","created_at":"2015-10-26T13:57:23Z","updated_at":"2018-02-16T11:35:49Z","pushed_at":"2018-02-16T11:58:06Z","git_url":"git://github.com/ethereum/EIPs.git","ssh_url":"git@github.com:ethereum/EIPs.git","clone_url":"https://github.com/ethereum/EIPs.git","svn_url":"https://github.com/ethereum/EIPs","homepage":"","size":755,"stargazers_count":2106,"watchers_count":2106,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":495,"mirror_url":null,"archived":false,"open_issues_count":242,"license":null,"forks":495,"open_issues":242,"watchers":2106,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ethereum/EIPs/pulls/881"},"html":{"href":"https://github.com/ethereum/EIPs/pull/881"},"issue":{"href":"https://api.github.com/repos/ethereum/EIPs/issues/881"},"comments":{"href":"https://api.github.com/repos/ethereum/EIPs/issues/881/comments"},"review_comments":{"href":"https://api.github.com/repos/ethereum/EIPs/pulls/881/comments"},"review_comment":{"href":"https://api.github.com/repos/ethereum/EIPs/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ethereum/EIPs/pulls/881/commits"},"statuses":{"href":"https://api.github.com/repos/ethereum/EIPs/statuses/ad70b8d27686de2b324491b1a7f6667963f5aa2e"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"fulldecent"}}