Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds rule to EIP-1 that references to other EIPs must use relative path format and the first reference must be linked. #2947

Merged
merged 2 commits into from
Sep 30, 2020

Conversation

MicahZoltu
Copy link
Contributor

I have gone through and updated all existing EIPs to match this rule, including EIP-1.

In some cases, people were using markdown citations, I suspect because the long-form was a bit verbose to inline. Since the relative path is quite short, I moved these to inline but I wouldn't be opposed to putting them back to citation format if that is desired by the authors.

In doing the migration/cleanup, I found some EIP references to EIPs that don't actually exist. In these cases I tried to excise the reference from the EIP as best I could.

It is worth noting that the Readme actually already had this rule, it just wasn't expressed properly in EIP-1 and the "Citation Format" section of the readme I think caused people a bit of confusion (when citing externally, you should use the citation format).

cc @axic @lightclient @Souptacular @gcolvin. I propose each of you approve or reject this PR, and if everyone approves we can merge it in without further delay. If someone rejects, we can use that as a signal that we need further discussion.

@MicahZoltu MicahZoltu force-pushed the eip-linking branch 2 times, most recently from 48b4506 to d7316e1 Compare September 6, 2020 04:06
@MicahZoltu
Copy link
Contributor Author

If someone can provide some insight as to why the build is failing that would be much appreciated. It says that ./eip-1702.md doesn't exist when linked from EIPS/eip-615.md. 1702 shows up on GitHub, and on the EIPs site, and I have verified neither the link nor the filename have any tricky characters in them (e.g., O instead of 0).

@axic
Copy link
Member

axic commented Sep 6, 2020

It is worth noting that the Readme actually already had this rule, it just wasn't expressed properly in EIP-1 and the "Citation Format" section of the readme I think caused people a bit of confusion (when citing externally, you should use the citation format).

The readme is not in sync with EIP-1, and EIP-1 takes precedence. Some people updated the README when updating EIP-1, other did not. There was also some push to drop all this duplication from the readme.

I'd have suggested to open a discussion topic on this before going lengths at doing the changes :)

@MicahZoltu
Copy link
Contributor Author

I'd have suggested to open a discussion topic on this before going lengths at doing the changes :)

Meh, if we don't follow through it isn't a big deal. Took me maybe 15-30 minutes to get all the right regex find/replaces in. Also, if we do decide to go with eips website only, it will be very simple to convert this PR into that now that all EIP links are standardized across the repository.

The readme is not in sync with EIP-1, and EIP-1 takes precedence. Some people updated the README when updating EIP-1, other did not. There was also some push to drop all this duplication from the readme.

I think you already know this, but for those who haven't been following our recent discussions on this topic:

  • EIP-1 doesn't explicitly specify how internal EIP links should handled
  • we have "Citation Format" which says anyone citing an EIP should use the EIPs website
  • we have that excerpt from the readme (which is non-normative) that says EIP links should be relative

@axic
Copy link
Member

axic commented Sep 6, 2020

There's a lot of info on this topic on the #eips discord channel. There was some reason brought up earlier for not using internal links. I'm not sure if that is still valid, but we should verify those claims (by checking a local build with these changes, etc.) before merging anything like this.

More importantly I think we should clean up the README and the front page on eips.ethereum.org -- both duplicate a lot of content with EIP-1 and in most cases in an inconsistent manner. I think EIP-1 should describe all the rules, and perhaps some technicality regarding GitHub and the automerger can remain outside of it, but wouldn't fight against even keeping that within some appendix of EIP-1.

@MicahZoltu
Copy link
Contributor Author

More importantly I think we should clean up the README and the front page on eips.ethereum.org -- both duplicate a lot of content with EIP-1 and in most cases in an inconsistent manner. I think EIP-1 should describe all the rules, and perhaps some technicality regarding GitHub and the automerger can remain outside of it, but wouldn't fight against even keeping that within some appendix of EIP-1.

I support this endeavor. However, I think it should be separate from this PR to keep the discussions/blockers/disagreements/etc. separate.

There was some reason brought up earlier for not using internal links. I'm not sure if that is still valid, but we should verify those claims (by checking a local build with these changes, etc.) before merging anything like this.

According to #1730 (comment), relative linking currently works on the EIPs site (also my personal experience agrees with this, and the HTML-proofer tangentially validates this). Does anyone here have the infrastructure setup to run this PR locally to further validate? Maybe @lightclient since you were previously working on some bot stuff?

Also according to that comment, I believe the primary argument for eips.ethereum.org hard links was to try to redirect people to the EIPs site and away from GitHub in case they stumble upon GitHub. My argument against that I believe the intersection of people who land on some random GitHub fork of the EIPs repository and the people who are browsing the EIPs repository by clicking on links is incredibly small and not worth breaking appropriate linking for people working in pull requests, mirrors, forks, etc.

@MicahZoltu
Copy link
Contributor Author

Discussed on call today, will rebase tomorrow and merge unless someone says something.

@MicahZoltu
Copy link
Contributor Author

Ugh, I actually still need help on figuring out why the HTML proofer is failing on that one EIP. 😢

@axic
Copy link
Member

axic commented Sep 9, 2020

Discussed on call today, will rebase tomorrow and merge unless someone says something.

What call do you mean?

@MicahZoltu
Copy link
Contributor Author

EIPIP call.

@axic
Copy link
Member

axic commented Sep 9, 2020

EIPIP call.

Hm, okay.

There's a lot of info on this topic on the #eips discord channel. There was some reason brought up earlier for not using internal links. I'm not sure if that is still valid, but we should verify those claims (by checking a local build with these changes, etc.) before merging anything like this.

Did anyone verify that everything works with these changes?

Because apparently CI is failing with it:

- ./_site/EIPS/eip-615.html
  *  internally linking to ./eips-1702.md, which does not exist (line 521)
     <a href="./eips-1702.md">EIP-1702</a>
htmlproofer 3.15.3 | Error:  HTML-Proofer found 1 failure!

@MicahZoltu MicahZoltu force-pushed the eip-linking branch 2 times, most recently from 122426e to 0644ab9 Compare September 9, 2020 16:35
@MicahZoltu
Copy link
Contributor Author

Finally fixed that issue with 615. I didn't realize there were two different links to 1702 in the file and one of them was wrong (I kept checking the right one when investigating).

I also have verified that relative links work on the eips site, though I don't think there was any reason to doubt this seeing as how that is how all links used to be, and many links today are currently relative.

@eip-automerger
Copy link

eip-automerger commented Sep 9, 2020

Hi! I'm a bot, and I wanted to automerge your PR, but couldn't because of the following issue(s):

  • EIP 1 is in state Active, not Draft or Last Call
  • EIP 1013 is in state Final, not Draft or Last Call
  • EIP 1014 is in state Final, not Draft or Last Call
  • Error checking file EIPS/eip-1015.md
  • EIP 1052 is in state Final, not Draft or Last Call
  • Error checking file EIPS/eip-1056.md
  • Error checking file EIPS/eip-1077.md
  • Error checking file EIPS/eip-1078.md
  • EIP 1108 is in state Final, not Draft or Last Call
  • EIP 1123 is in state Abandoned, not Draft or Last Call
  • EIP 1155 is in state Final, not Draft or Last Call
  • EIP 1193 is in state Final, not Draft or Last Call
  • EIP 1234 is in state Final, not Draft or Last Call
  • EIP 1344 is in state Final, not Draft or Last Call
  • EIP 137 is in state Final, not Draft or Last Call
  • Error checking file EIPS/eip-1459.md
  • Error checking file EIPS/eip-1462.md
  • Error checking file EIPS/eip-1474.md
  • Error checking file EIPS/eip-1484.md
  • Error checking file EIPS/eip-1485.md
  • Error checking file EIPS/eip-1592.md
  • Error checking file EIPS/eip-1613.md
  • EIP 162 is in state Final, not Draft or Last Call
  • EIP 1679 is in state Final, not Draft or Last Call
  • EIP 1682 is in state Abandoned, not Draft or Last Call
  • EIP 1706 is in state Abandoned, not Draft or Last Call
  • EIP 1820 is in state Final, not Draft or Last Call
  • Error checking file EIPS/eip-1829.md
  • EIP 1884 is in state Final, not Draft or Last Call
  • EIP 190 is in state Final, not Draft or Last Call
  • Error checking file EIPS/eip-1922.md
  • Error checking file EIPS/eip-1923.md
  • Error checking file EIPS/eip-1996.md
  • File EIPS/eip-20-token-standard.md is not an EIP
  • Error checking file EIPS/eip-2009.md
  • Error checking file EIPS/eip-2018.md
  • Error checking file EIPS/eip-2019.md
  • Error checking file EIPS/eip-2020.md
  • Error checking file EIPS/eip-2021.md
  • Error checking file EIPS/eip-2098.md
  • EIP 2200 is in state Final, not Draft or Last Call
  • Error checking file EIPS/eip-2304.md
  • EIP 2384 is in state Final, not Draft or Last Call
  • EIP 2387 is in state Final, not Draft or Last Call
  • EIP 607 is in state Final, not Draft or Last Call
  • EIP 609 is in state Final, not Draft or Last Call
  • EIP 695 is in state Final, not Draft or Last Call
  • Error checking file EIPS/eip-712.md
  • EIP 721 is in state Final, not Draft or Last Call
  • EIP 777 is in state Final, not Draft or Last Call
  • EIP 820 is in state Superseded, not Draft or Last Call
  • Error checking file EIPS/eip-831.md
  • EIP 908 is in state Abandoned, not Draft or Last Call
  • Error checking file EIPS/eip-969.md
  • Error checking file EIPS/eip-998.md
  • File ISSUE_TEMPLATE.md is not an EIP
  • File README.md is not an EIP
  • EIP 1066 requires approval from one of (@carchrae, @naumenkogs, @expede)
  • EIP 1202 requires approval from one of (@yingogobot, @xinbenlv, @evbots)
  • EIP 1276 requires approval from one of (@eosclassicteam)
  • EIP 1444 requires approval from one of (@expede, @jenncoop)
  • EIP 1710 requires approval from one of (@brunobar79)
  • EIP 173 requires approval from one of (@danfinlay, @mudgen)
  • EIP 1775 requires approval from one of (@danfinlay, @Bunjin)
  • EIP 1803 requires approval from one of (@axic)
  • EIP 1812 requires approval from one of (@pelle)
  • EIP 1898 requires approval from one of (@charles-cooper)
  • EIP 1901 requires approval from one of (@shanejonas, @BelfordZ)
  • EIP 191 requires approval from one of (@Arachnid, @holiman)
  • EIP 1921 requires approval from one of (@ctzurcanu, @loredanacirstea)
  • EIP 1930 requires approval from one of (@wighawag)
  • EIP 1948 requires approval from one of (@johannbarbie, @pinkiebell, @benjaminbollen)
  • EIP 1959 requires approval from one of (@wighawag)
  • EIP 1962 requires approval from one of (@shamatar)
  • EIP 1965 requires approval from one of (@wighawag)
  • EIP 1967 requires approval from one of (@spalladino)
  • EIP 1985 requires approval from one of (@chfast, @axic)
  • EIP 2003 requires approval from one of (@chfast, @axic)
  • EIP 2014 requires approval from one of (@axic)
  • EIP 2015 requires approval from one of (@pedrouid)
  • EIP 2025 requires approval from one of (@MadeofTin)
  • EIP 2029 requires approval from one of (@AlexeyAkhunov)
  • EIP 2031 requires approval from one of (@AlexeyAkhunov)
  • EIP 2035 requires approval from one of (@AlexeyAkhunov)
  • EIP 2045 requires approval from one of (@cdetrio, @axic)
  • EIP 2046 requires approval from one of (@axic)
  • EIP 2070 requires approval from one of (@axic)
  • EIP 2124 requires approval from one of (@karalabe, @fjl)
  • EIP 2135 requires approval from one of (@xinbenlv)
  • EIP 2193 requires approval from one of (@ctzurcanu, @loredanacirstea)
  • EIP 2242 requires approval from one of (@adlerjohn)
  • EIP 2255 requires approval from one of (@danfinlay, @rekmarks)
  • EIP 2256 requires approval from one of (@loredanacirstea)
  • EIP 2327 requires approval from one of (@MrChico)
  • EIP 233 requires approval from one of (@axic)
  • EIP 2334 requires approval from one of (@CarlBeek)
  • EIP 2335 requires approval from one of (@CarlBeek)
  • EIP 2364 requires approval from one of (@karalabe)
  • EIP 2400 requires approval from one of (@3esmit, @yenda)
  • EIP 2470 requires approval from one of (@3esmit)
  • EIP 2477 requires approval from one of (@coinfork, @fulldecent, @xpepermint)
  • EIP 2488 requires approval from one of (@axic)
  • EIP 2525 requires approval from one of (@Amxx)
  • EIP 2535 requires approval from one of (@mudgen)
  • EIP 2565 requires approval from one of (@simonatsn, @dankrad, @JustinDrake, @sean-sn, @ineffectualproperty)
  • EIP 2569 requires approval from one of (@zhous, @dgczhh, @whtyfhas)
  • EIP 2583 requires approval from one of (@holiman)
  • EIP 2612 requires approval from one of (@MrChico)
  • EIP 2677 requires approval from one of (@chfast, @axic, @holiman)
  • EIP 2678 requires approval from one of (@gnidan, @chriseth, @iamdefinitelyahuman, @fubuloubu, @pipermerriam, @njgheorghita)
  • EIP 2681 requires approval from one of (@axic)
  • EIP 2733 requires approval from one of (@lightclient)
  • EIP 2746 requires approval from one of (@juanfranblanco, @jaerith)
  • EIP 2926 requires approval from one of (@axic, @s1na)
  • EIP 2929 requires approval from one of (@holiman, @vbuterin)
  • EIP 615 requires approval from one of (@chfast, @gcolvin, @expede, @chriseth)
  • EIP 663 requires approval from one of (@axic)
  • EIP 689 requires approval from one of (@pirapira)
  • EIP 725 requires approval from one of (@tyleryasaka, @frozeman)
  • EIP 868 requires approval from one of (@fjl)

Copy link
Contributor

@chaitanyapotti chaitanyapotti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lgtm

@MicahZoltu
Copy link
Contributor Author

Please ignore the bot mentions here. This is a cleanup by the editors to fix some inconsistencies, no need for everyone to review. 😄

EIPS/eip-1015.md Outdated
@@ -28,16 +28,16 @@ Moving to PoS has been on the roadmap since day 0 for ethereum, along with a red

#### Asics and advantadges of PoW

[EIP 960](https://eips.ethereum.org/EIPS/eip-969) proposes a change in algorithm to avoid mining being dominated by ASICS. Counter arguments by Phil Daian argue among others than [resisting economies of scale is futile and there might be specific security advantadges to specialized hardware](https://pdaian.com/blog/anti-asic-forks-considered-harmful/). One of the main arguments for PoW mining, even when it doesn't provide security, it is useful as a fair distribution mechanism, that **PoW allows any person with a computer, internet access and electricity to obtain currency without having to deal with government imposed currency controls**.
[EIP 960](./eip-969.md) proposes a change in algorithm to avoid mining being dominated by ASICS. Counter arguments by Phil Daian argue among others than [resisting economies of scale is futile and there might be specific security advantadges to specialized hardware](https://pdaian.com/blog/anti-asic-forks-considered-harmful/). One of the main arguments for PoW mining, even when it doesn't provide security, it is useful as a fair distribution mechanism, that **PoW allows any person with a computer, internet access and electricity to obtain currency without having to deal with government imposed currency controls**.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, is it EIP 960 or EIP-960?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And why does it link to eip-969 ?

EIPS/eip-1056.md Outdated
@@ -19,7 +19,7 @@ This ERC describes a standard for creating and updating identities with a limite

## Motivation

As we have been developing identity systems for the last couple of years at uPort it has become apparent that the cost of identity creation is a large issue. The previous Identity proposal [ERC725](https://eips.ethereum.org/EIPS/eip-725) faces this exact issue. Our requirements when creating this ERC is that identity creation should be free, and should be possible to do in an offline environment (e.g. refugee scenario). However it must also be possible to rotate keys without changing the primary identifier of the identity. The identity system should be fit to use off-chain as well as on-chain.
As we have been developing identity systems for the last couple of years at uPort it has become apparent that the cost of identity creation is a large issue. The previous Identity proposal [ERC725](./eip-725.md) faces this exact issue. Our requirements when creating this ERC is that identity creation should be free, and should be possible to do in an offline environment (e.g. refugee scenario). However it must also be possible to rotate keys without changing the primary identifier of the identity. The identity system should be fit to use off-chain as well as on-chain.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And these ERC links don't have a dash.

EIPS/eip-1155.md Outdated
@@ -39,7 +39,7 @@ pragma solidity ^0.5.9;

/**
@title ERC-1155 Multi Token Standard
@dev See https://eips.ethereum.org/EIPS/eip-1155
@dev See ./eip-1155.md
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not so sure about this change. I assume this interface is copy pasted somewhere else and then this link becomes useless. Moreso, this is a Natspec definition which will be part of the contract metadata and this link will be useless.

EIPS/eip-1462.md Outdated

The scope of this standard is being kept as narrow as possible to avoid restricting potential use-cases of this base security token. Any additional functionality and limitations not defined in this standard may be enforced on per-project basis.

## Motivation

There are several security token standards that have been proposed recently. Examples include [ERC-1400](https://github.com/ethereum/EIPs/issues/1411), also [ERC-1450](https://eips.ethereum.org/EIPS/eip-1450). We have concerns about each of them, mostly because the scope of each of these EIPs contains many project-specific or market-specific details. Since many EIPs are coming from the respective backing companies, they capture many niche requirements that are excessive for a general case.
There are several security token standards that have been proposed recently. Examples include [ERC-1400](https://github.com/ethereum/EIPs/issues/1411), also [ERC-1450](./eip-1450.md). We have concerns about each of them, mostly because the scope of each of these EIPs contains many project-specific or market-specific details. Since many EIPs are coming from the respective backing companies, they capture many niche requirements that are excessive for a general case.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[ERC-1400](https://github.com/ethereum/EIPs/issues/1411)

Is it 1400 or 1411?


For instance, ERC-1411 uses dependency on [ERC-1410](https://github.com/ethereum/eips/issues/1410) but it falls out of the "security tokens" scope. Also its dependency on [ERC-777](https://eips.ethereum.org/EIPS/eip-777) will block the adoption for a quite period of time before ERC-777 is finalized, but the integration guidelines for existing ERC-20 workflows are not described in that EIP, yet. Another attempt to make a much simpler base standard [ERC-1404](https://github.com/ethereum/EIPs/issues/1404) is missing a few important points, specifically it doesn't provide enough granularity to distinguish between different ERC-20 transfer functions such as `transfer` and `transferFrom`. It also doesn't provide a way to bind legal documentation to the issued tokens.
For instance, ERC-1411 uses dependency on [ERC-1410](https://github.com/ethereum/eips/issues/1410) but it falls out of the "security tokens" scope. Also its dependency on [ERC-777](./eip-777.md) will block the adoption for a quite period of time before ERC-777 is finalized, but the integration guidelines for existing ERC-20 workflows are not described in that EIP, yet. Another attempt to make a much simpler base standard [ERC-1404](https://github.com/ethereum/EIPs/issues/1404) is missing a few important points, specifically it doesn't provide enough granularity to distinguish between different ERC-20 transfer functions such as `transfer` and `transferFrom`. It also doesn't provide a way to bind legal documentation to the issued tokens.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And then here it calls "ERC-1411" which is not linked.

EIPS/eip-1682.md Outdated
@@ -32,13 +32,7 @@ upper bound on the size of the Ethereum state.
Adding these new rules changes fundamental guarantees of the system and requires a hard
fork. Users of Ethereum already pay for the creation and modification of accounts and
their storage entries. Under the rules introduced in this EIP, users must also pay to keep
accounts accessible. A similar rent scheme was proposed in [EIP-103] but rejected
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These very early EIPs were handled differently. They had some random number picked, and were kept in an issue with a different number.

I think removing this on the bases that it is an "invalid link" is not good enough.

EIPS/eip-1820.md Outdated
@@ -102,7 +102,7 @@ interface ERC1820ImplementerInterface {
/// @title ERC1820 Pseudo-introspection Registry Contract
/// @author Jordi Baylina and Jacques Dafflon
/// @notice This contract is the official implementation of the ERC1820 Registry.
/// @notice For more details, see https://eips.ethereum.org/EIPS/eip-1820
/// @notice For more details, see ./eip-1820.md
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, natspec change.

EIPS/eip-1820.md Outdated
@@ -651,7 +651,7 @@ The contract has the address above for every chain on which it is deployed.
},
"sources": {
"./contracts/ERC1820Registry.sol": {
"content": "/* ERC1820 Pseudo-introspection Registry Contract\n * This standard defines a universal registry smart contract where any address (contract or regular account) can\n * register which interface it supports and which smart contract is responsible for its implementation.\n *\n * Written in 2019 by Jordi Baylina and Jacques Dafflon\n *\n * To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to\n * this software to the public domain worldwide. This software is distributed without any warranty.\n *\n * You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see\n * <http://creativecommons.org/publicdomain/zero/1.0/>.\n *\n * ███████╗██████╗ ██████╗ ██╗ █████╗ ██████╗ ██████╗\n * ██╔════╝██╔══██╗██╔════╝███║██╔══██╗╚════██╗██╔═████╗\n * █████╗ ██████╔╝██║ ╚██║╚█████╔╝ █████╔╝██║██╔██║\n * ██╔══╝ ██╔══██╗██║ ██║██╔══██╗██╔═══╝ ████╔╝██║\n * ███████╗██║ ██║╚██████╗ ██║╚█████╔╝███████╗╚██████╔╝\n * ╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚════╝ ╚══════╝ ╚═════╝\n *\n * ██████╗ ███████╗ ██████╗ ██╗███████╗████████╗██████╗ ██╗ ██╗\n * ██╔══██╗██╔════╝██╔════╝ ██║██╔════╝╚══██╔══╝██╔══██╗╚██╗ ██╔╝\n * ██████╔╝█████╗ ██║ ███╗██║███████╗ ██║ ██████╔╝ ╚████╔╝\n * ██╔══██╗██╔══╝ ██║ ██║██║╚════██║ ██║ ██╔══██╗ ╚██╔╝\n * ██║ ██║███████╗╚██████╔╝██║███████║ ██║ ██║ ██║ ██║\n * ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝\n *\n */\npragma solidity 0.5.3;\n// IV is value needed to have a vanity address starting with '0x1820'.\n// IV: 53759\n\n/// @dev The interface a contract MUST implement if it is the implementer of\n/// some (other) interface for any address other than itself.\ninterface ERC1820ImplementerInterface {\n /// @notice Indicates whether the contract implements the interface 'interfaceHash' for the address 'addr' or not.\n /// @param interfaceHash keccak256 hash of the name of the interface\n /// @param addr Address for which the contract will implement the interface\n /// @return ERC1820_ACCEPT_MAGIC only if the contract implements 'interfaceHash' for the address 'addr'.\n function canImplementInterfaceForAddress(bytes32 interfaceHash, address addr) external view returns(bytes32);\n}\n\n\n/// @title ERC1820 Pseudo-introspection Registry Contract\n/// @author Jordi Baylina and Jacques Dafflon\n/// @notice This contract is the official implementation of the ERC1820 Registry.\n/// @notice For more details, see https://eips.ethereum.org/EIPS/eip-1820\ncontract ERC1820Registry {\n /// @notice ERC165 Invalid ID.\n bytes4 constant internal INVALID_ID = 0xffffffff;\n /// @notice Method ID for the ERC165 supportsInterface method (= `bytes4(keccak256('supportsInterface(bytes4)'))`).\n bytes4 constant internal ERC165ID = 0x01ffc9a7;\n /// @notice Magic value which is returned if a contract implements an interface on behalf of some other address.\n bytes32 constant internal ERC1820_ACCEPT_MAGIC = keccak256(abi.encodePacked(\"ERC1820_ACCEPT_MAGIC\"));\n\n /// @notice mapping from addresses and interface hashes to their implementers.\n mapping(address => mapping(bytes32 => address)) internal interfaces;\n /// @notice mapping from addresses to their manager.\n mapping(address => address) internal managers;\n /// @notice flag for each address and erc165 interface to indicate if it is cached.\n mapping(address => mapping(bytes4 => bool)) internal erc165Cached;\n\n /// @notice Indicates a contract is the 'implementer' of 'interfaceHash' for 'addr'.\n event InterfaceImplementerSet(address indexed addr, bytes32 indexed interfaceHash, address indexed implementer);\n /// @notice Indicates 'newManager' is the address of the new manager for 'addr'.\n event ManagerChanged(address indexed addr, address indexed newManager);\n\n /// @notice Query if an address implements an interface and through which contract.\n /// @param _addr Address being queried for the implementer of an interface.\n /// (If '_addr' is the zero address then 'msg.sender' is assumed.)\n /// @param _interfaceHash Keccak256 hash of the name of the interface as a string.\n /// E.g., 'web3.utils.keccak256(\"ERC777TokensRecipient\")' for the 'ERC777TokensRecipient' interface.\n /// @return The address of the contract which implements the interface '_interfaceHash' for '_addr'\n /// or '0' if '_addr' did not register an implementer for this interface.\n function getInterfaceImplementer(address _addr, bytes32 _interfaceHash) external view returns (address) {\n address addr = _addr == address(0) ? msg.sender : _addr;\n if (isERC165Interface(_interfaceHash)) {\n bytes4 erc165InterfaceHash = bytes4(_interfaceHash);\n return implementsERC165Interface(addr, erc165InterfaceHash) ? addr : address(0);\n }\n return interfaces[addr][_interfaceHash];\n }\n\n /// @notice Sets the contract which implements a specific interface for an address.\n /// Only the manager defined for that address can set it.\n /// (Each address is the manager for itself until it sets a new manager.)\n /// @param _addr Address for which to set the interface.\n /// (If '_addr' is the zero address then 'msg.sender' is assumed.)\n /// @param _interfaceHash Keccak256 hash of the name of the interface as a string.\n /// E.g., 'web3.utils.keccak256(\"ERC777TokensRecipient\")' for the 'ERC777TokensRecipient' interface.\n /// @param _implementer Contract address implementing '_interfaceHash' for '_addr'.\n function setInterfaceImplementer(address _addr, bytes32 _interfaceHash, address _implementer) external {\n address addr = _addr == address(0) ? msg.sender : _addr;\n require(getManager(addr) == msg.sender, \"Not the manager\");\n\n require(!isERC165Interface(_interfaceHash), \"Must not be an ERC165 hash\");\n if (_implementer != address(0) && _implementer != msg.sender) {\n require(\n ERC1820ImplementerInterface(_implementer)\n .canImplementInterfaceForAddress(_interfaceHash, addr) == ERC1820_ACCEPT_MAGIC,\n \"Does not implement the interface\"\n );\n }\n interfaces[addr][_interfaceHash] = _implementer;\n emit InterfaceImplementerSet(addr, _interfaceHash, _implementer);\n }\n\n /// @notice Sets '_newManager' as manager for '_addr'.\n /// The new manager will be able to call 'setInterfaceImplementer' for '_addr'.\n /// @param _addr Address for which to set the new manager.\n /// @param _newManager Address of the new manager for 'addr'. (Pass '0x0' to reset the manager to '_addr'.)\n function setManager(address _addr, address _newManager) external {\n require(getManager(_addr) == msg.sender, \"Not the manager\");\n managers[_addr] = _newManager == _addr ? address(0) : _newManager;\n emit ManagerChanged(_addr, _newManager);\n }\n\n /// @notice Get the manager of an address.\n /// @param _addr Address for which to return the manager.\n /// @return Address of the manager for a given address.\n function getManager(address _addr) public view returns(address) {\n // By default the manager of an address is the same address\n if (managers[_addr] == address(0)) {\n return _addr;\n } else {\n return managers[_addr];\n }\n }\n\n /// @notice Compute the keccak256 hash of an interface given its name.\n /// @param _interfaceName Name of the interface.\n /// @return The keccak256 hash of an interface name.\n function interfaceHash(string calldata _interfaceName) external pure returns(bytes32) {\n return keccak256(abi.encodePacked(_interfaceName));\n }\n\n /* --- ERC165 Related Functions --- */\n /* --- Developed in collaboration with William Entriken. --- */\n\n /// @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n /// @param _contract Address of the contract for which to update the cache.\n /// @param _interfaceId ERC165 interface for which to update the cache.\n function updateERC165Cache(address _contract, bytes4 _interfaceId) external {\n interfaces[_contract][_interfaceId] = implementsERC165InterfaceNoCache(\n _contract, _interfaceId) ? _contract : address(0);\n erc165Cached[_contract][_interfaceId] = true;\n }\n\n /// @notice Checks whether a contract implements an ERC165 interface or not.\n // If the result is not cached a direct lookup on the contract address is performed.\n // If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n // 'updateERC165Cache' with the contract address.\n /// @param _contract Address of the contract to check.\n /// @param _interfaceId ERC165 interface to check.\n /// @return True if '_contract' implements '_interfaceId', false otherwise.\n function implementsERC165Interface(address _contract, bytes4 _interfaceId) public view returns (bool) {\n if (!erc165Cached[_contract][_interfaceId]) {\n return implementsERC165InterfaceNoCache(_contract, _interfaceId);\n }\n return interfaces[_contract][_interfaceId] == _contract;\n }\n\n /// @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\n /// @param _contract Address of the contract to check.\n /// @param _interfaceId ERC165 interface to check.\n /// @return True if '_contract' implements '_interfaceId', false otherwise.\n function implementsERC165InterfaceNoCache(address _contract, bytes4 _interfaceId) public view returns (bool) {\n uint256 success;\n uint256 result;\n\n (success, result) = noThrowCall(_contract, ERC165ID);\n if (success == 0 || result == 0) {\n return false;\n }\n\n (success, result) = noThrowCall(_contract, INVALID_ID);\n if (success == 0 || result != 0) {\n return false;\n }\n\n (success, result) = noThrowCall(_contract, _interfaceId);\n if (success == 1 && result == 1) {\n return true;\n }\n return false;\n }\n\n /// @notice Checks whether the hash is a ERC165 interface (ending with 28 zeroes) or not.\n /// @param _interfaceHash The hash to check.\n /// @return True if '_interfaceHash' is an ERC165 interface (ending with 28 zeroes), false otherwise.\n function isERC165Interface(bytes32 _interfaceHash) internal pure returns (bool) {\n return _interfaceHash & 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0;\n }\n\n /// @dev Make a call on a contract without throwing if the function does not exist.\n function noThrowCall(address _contract, bytes4 _interfaceId)\n internal view returns (uint256 success, uint256 result)\n {\n bytes4 erc165ID = ERC165ID;\n\n assembly {\n let x := mload(0x40) // Find empty storage location using \"free memory pointer\"\n mstore(x, erc165ID) // Place signature at beginning of empty storage\n mstore(add(x, 0x04), _interfaceId) // Place first argument directly next to signature\n\n success := staticcall(\n 30000, // 30k gas\n _contract, // To addr\n x, // Inputs are stored at location x\n 0x24, // Inputs are 36 (4 + 32) bytes long\n x, // Store output over input (saves space)\n 0x20 // Outputs are 32 bytes long\n )\n\n result := mload(x) // Load the result\n }\n }\n}\n",
"content": "/* ERC1820 Pseudo-introspection Registry Contract\n * This standard defines a universal registry smart contract where any address (contract or regular account) can\n * register which interface it supports and which smart contract is responsible for its implementation.\n *\n * Written in 2019 by Jordi Baylina and Jacques Dafflon\n *\n * To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to\n * this software to the public domain worldwide. This software is distributed without any warranty.\n *\n * You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see\n * <http://creativecommons.org/publicdomain/zero/1.0/>.\n *\n * ███████╗██████╗ ██████╗ ██╗ █████╗ ██████╗ ██████╗\n * ██╔════╝██╔══██╗██╔════╝███║██╔══██╗╚════██╗██╔═████╗\n * █████╗ ██████╔╝██║ ╚██║╚█████╔╝ █████╔╝██║██╔██║\n * ██╔══╝ ██╔══██╗██║ ██║██╔══██╗██╔═══╝ ████╔╝██║\n * ███████╗██║ ██║╚██████╗ ██║╚█████╔╝███████╗╚██████╔╝\n * ╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚════╝ ╚══════╝ ╚═════╝\n *\n * ██████╗ ███████╗ ██████╗ ██╗███████╗████████╗██████╗ ██╗ ██╗\n * ██╔══██╗██╔════╝██╔════╝ ██║██╔════╝╚══██╔══╝██╔══██╗╚██╗ ██╔╝\n * ██████╔╝█████╗ ██║ ███╗██║███████╗ ██║ ██████╔╝ ╚████╔╝\n * ██╔══██╗██╔══╝ ██║ ██║██║╚════██║ ██║ ██╔══██╗ ╚██╔╝\n * ██║ ██║███████╗╚██████╔╝██║███████║ ██║ ██║ ██║ ██║\n * ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝\n *\n */\npragma solidity 0.5.3;\n// IV is value needed to have a vanity address starting with '0x1820'.\n// IV: 53759\n\n/// @dev The interface a contract MUST implement if it is the implementer of\n/// some (other) interface for any address other than itself.\ninterface ERC1820ImplementerInterface {\n /// @notice Indicates whether the contract implements the interface 'interfaceHash' for the address 'addr' or not.\n /// @param interfaceHash keccak256 hash of the name of the interface\n /// @param addr Address for which the contract will implement the interface\n /// @return ERC1820_ACCEPT_MAGIC only if the contract implements 'interfaceHash' for the address 'addr'.\n function canImplementInterfaceForAddress(bytes32 interfaceHash, address addr) external view returns(bytes32);\n}\n\n\n/// @title ERC1820 Pseudo-introspection Registry Contract\n/// @author Jordi Baylina and Jacques Dafflon\n/// @notice This contract is the official implementation of the ERC1820 Registry.\n/// @notice For more details, see ./eip-1820.md\ncontract ERC1820Registry {\n /// @notice ERC165 Invalid ID.\n bytes4 constant internal INVALID_ID = 0xffffffff;\n /// @notice Method ID for the ERC165 supportsInterface method (= `bytes4(keccak256('supportsInterface(bytes4)'))`).\n bytes4 constant internal ERC165ID = 0x01ffc9a7;\n /// @notice Magic value which is returned if a contract implements an interface on behalf of some other address.\n bytes32 constant internal ERC1820_ACCEPT_MAGIC = keccak256(abi.encodePacked(\"ERC1820_ACCEPT_MAGIC\"));\n\n /// @notice mapping from addresses and interface hashes to their implementers.\n mapping(address => mapping(bytes32 => address)) internal interfaces;\n /// @notice mapping from addresses to their manager.\n mapping(address => address) internal managers;\n /// @notice flag for each address and erc165 interface to indicate if it is cached.\n mapping(address => mapping(bytes4 => bool)) internal erc165Cached;\n\n /// @notice Indicates a contract is the 'implementer' of 'interfaceHash' for 'addr'.\n event InterfaceImplementerSet(address indexed addr, bytes32 indexed interfaceHash, address indexed implementer);\n /// @notice Indicates 'newManager' is the address of the new manager for 'addr'.\n event ManagerChanged(address indexed addr, address indexed newManager);\n\n /// @notice Query if an address implements an interface and through which contract.\n /// @param _addr Address being queried for the implementer of an interface.\n /// (If '_addr' is the zero address then 'msg.sender' is assumed.)\n /// @param _interfaceHash Keccak256 hash of the name of the interface as a string.\n /// E.g., 'web3.utils.keccak256(\"ERC777TokensRecipient\")' for the 'ERC777TokensRecipient' interface.\n /// @return The address of the contract which implements the interface '_interfaceHash' for '_addr'\n /// or '0' if '_addr' did not register an implementer for this interface.\n function getInterfaceImplementer(address _addr, bytes32 _interfaceHash) external view returns (address) {\n address addr = _addr == address(0) ? msg.sender : _addr;\n if (isERC165Interface(_interfaceHash)) {\n bytes4 erc165InterfaceHash = bytes4(_interfaceHash);\n return implementsERC165Interface(addr, erc165InterfaceHash) ? addr : address(0);\n }\n return interfaces[addr][_interfaceHash];\n }\n\n /// @notice Sets the contract which implements a specific interface for an address.\n /// Only the manager defined for that address can set it.\n /// (Each address is the manager for itself until it sets a new manager.)\n /// @param _addr Address for which to set the interface.\n /// (If '_addr' is the zero address then 'msg.sender' is assumed.)\n /// @param _interfaceHash Keccak256 hash of the name of the interface as a string.\n /// E.g., 'web3.utils.keccak256(\"ERC777TokensRecipient\")' for the 'ERC777TokensRecipient' interface.\n /// @param _implementer Contract address implementing '_interfaceHash' for '_addr'.\n function setInterfaceImplementer(address _addr, bytes32 _interfaceHash, address _implementer) external {\n address addr = _addr == address(0) ? msg.sender : _addr;\n require(getManager(addr) == msg.sender, \"Not the manager\");\n\n require(!isERC165Interface(_interfaceHash), \"Must not be an ERC165 hash\");\n if (_implementer != address(0) && _implementer != msg.sender) {\n require(\n ERC1820ImplementerInterface(_implementer)\n .canImplementInterfaceForAddress(_interfaceHash, addr) == ERC1820_ACCEPT_MAGIC,\n \"Does not implement the interface\"\n );\n }\n interfaces[addr][_interfaceHash] = _implementer;\n emit InterfaceImplementerSet(addr, _interfaceHash, _implementer);\n }\n\n /// @notice Sets '_newManager' as manager for '_addr'.\n /// The new manager will be able to call 'setInterfaceImplementer' for '_addr'.\n /// @param _addr Address for which to set the new manager.\n /// @param _newManager Address of the new manager for 'addr'. (Pass '0x0' to reset the manager to '_addr'.)\n function setManager(address _addr, address _newManager) external {\n require(getManager(_addr) == msg.sender, \"Not the manager\");\n managers[_addr] = _newManager == _addr ? address(0) : _newManager;\n emit ManagerChanged(_addr, _newManager);\n }\n\n /// @notice Get the manager of an address.\n /// @param _addr Address for which to return the manager.\n /// @return Address of the manager for a given address.\n function getManager(address _addr) public view returns(address) {\n // By default the manager of an address is the same address\n if (managers[_addr] == address(0)) {\n return _addr;\n } else {\n return managers[_addr];\n }\n }\n\n /// @notice Compute the keccak256 hash of an interface given its name.\n /// @param _interfaceName Name of the interface.\n /// @return The keccak256 hash of an interface name.\n function interfaceHash(string calldata _interfaceName) external pure returns(bytes32) {\n return keccak256(abi.encodePacked(_interfaceName));\n }\n\n /* --- ERC165 Related Functions --- */\n /* --- Developed in collaboration with William Entriken. --- */\n\n /// @notice Updates the cache with whether the contract implements an ERC165 interface or not.\n /// @param _contract Address of the contract for which to update the cache.\n /// @param _interfaceId ERC165 interface for which to update the cache.\n function updateERC165Cache(address _contract, bytes4 _interfaceId) external {\n interfaces[_contract][_interfaceId] = implementsERC165InterfaceNoCache(\n _contract, _interfaceId) ? _contract : address(0);\n erc165Cached[_contract][_interfaceId] = true;\n }\n\n /// @notice Checks whether a contract implements an ERC165 interface or not.\n // If the result is not cached a direct lookup on the contract address is performed.\n // If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling\n // 'updateERC165Cache' with the contract address.\n /// @param _contract Address of the contract to check.\n /// @param _interfaceId ERC165 interface to check.\n /// @return True if '_contract' implements '_interfaceId', false otherwise.\n function implementsERC165Interface(address _contract, bytes4 _interfaceId) public view returns (bool) {\n if (!erc165Cached[_contract][_interfaceId]) {\n return implementsERC165InterfaceNoCache(_contract, _interfaceId);\n }\n return interfaces[_contract][_interfaceId] == _contract;\n }\n\n /// @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.\n /// @param _contract Address of the contract to check.\n /// @param _interfaceId ERC165 interface to check.\n /// @return True if '_contract' implements '_interfaceId', false otherwise.\n function implementsERC165InterfaceNoCache(address _contract, bytes4 _interfaceId) public view returns (bool) {\n uint256 success;\n uint256 result;\n\n (success, result) = noThrowCall(_contract, ERC165ID);\n if (success == 0 || result == 0) {\n return false;\n }\n\n (success, result) = noThrowCall(_contract, INVALID_ID);\n if (success == 0 || result != 0) {\n return false;\n }\n\n (success, result) = noThrowCall(_contract, _interfaceId);\n if (success == 1 && result == 1) {\n return true;\n }\n return false;\n }\n\n /// @notice Checks whether the hash is a ERC165 interface (ending with 28 zeroes) or not.\n /// @param _interfaceHash The hash to check.\n /// @return True if '_interfaceHash' is an ERC165 interface (ending with 28 zeroes), false otherwise.\n function isERC165Interface(bytes32 _interfaceHash) internal pure returns (bool) {\n return _interfaceHash & 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0;\n }\n\n /// @dev Make a call on a contract without throwing if the function does not exist.\n function noThrowCall(address _contract, bytes4 _interfaceId)\n internal view returns (uint256 success, uint256 result)\n {\n bytes4 erc165ID = ERC165ID;\n\n assembly {\n let x := mload(0x40) // Find empty storage location using \"free memory pointer\"\n mstore(x, erc165ID) // Place signature at beginning of empty storage\n mstore(add(x, 0x04), _interfaceId) // Place first argument directly next to signature\n\n success := staticcall(\n 30000, // 30k gas\n _contract, // To addr\n x, // Inputs are stored at location x\n 0x24, // Inputs are 36 (4 + 32) bytes long\n x, // Store output over input (saves space)\n 0x20 // Outputs are 32 bytes long\n )\n\n result := mload(x) // Load the result\n }\n }\n}\n",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes the source, renders the hash below invalid, and therefore breaks this EIP.

@MicahZoltu
Copy link
Contributor Author

MicahZoltu commented Sep 10, 2020

@axic convinced me to redo this PR so it didn't touch as much all at once. Will change strategy to:

  1. Normalize all [EIP?###] to [EIP-###]
  2. Normalize all [ERC?###] to [ERC-###]
  3. Convert all [EIP-###](?) to [EIP-###](./eip-###.md)
  4. Convert all [ERC-###](?) to [ERC-###](./eip-###.md)
  5. Wait for bot to run.
  6. Revert everything the bot complains about.
  7. Wait for bot to pass.
  8. Get approval from Axic/Lightclient.
  9. Merge.

@MicahZoltu MicahZoltu marked this pull request as draft September 10, 2020 05:56
@MicahZoltu MicahZoltu force-pushed the eip-linking branch 5 times, most recently from f43f6ca to fab86a5 Compare September 12, 2020 08:29
…th format and the first reference must be linked.

I have gone through and updated all existing EIPs to match this rule, including EIP-1.

In some cases, people were using markdown citations, I suspect because the long-form was a bit verbose to inline.  Since the relative path is quite short, I moved these to inline but I wouldn't be opposed to putting them back to citation format if that is desired by the authors.

In doing the migration/cleanup, I found some EIP references to EIPs that don't actually exist.  In these cases I tried to excise the reference from the EIP as best I could.

It is worth noting that the Readme actually already had this rule, it just wasn't expressed properly in EIP-1 and the "Citation Format" section of the readme I think caused people a bit of confusion (when citing externally, you should use the citation format).
@BelfordZ
Copy link

BelfordZ commented Sep 12, 2020

looks valid though I'm not sure I understand the motivation behind wanting only relative links. This makes the EIPs no longer able to be consumed in a stand-alone fashion.

@3esmit
Copy link
Contributor

3esmit commented Sep 14, 2020

Approved (EIP 2400 and EIP 2470).

@MicahZoltu
Copy link
Contributor Author

looks valid though I'm not sure I understand the motivation behind wanting only relative links. This makes the EIPs no longer able to be consumed in a stand-alone fashion.

I believe the opposite is true? When absolute links are used the document breaks when you are working on a fork, or hosting on a mirror, or browsing via IPFS, or local filesystem while offline, etc.. If you use relative links, then no matter how you are browsing the EIP repository, you'll be able to access everything.

Copy link
Member

@lightclient lightclient left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In principle, I'm on board with this PR. I have not had a chance to go through it line-by-line though.

@MicahZoltu
Copy link
Contributor Author

We can always fix mistakes afterward if necessary, so "in principle" is good enough for me. 😀

@BelfordZ
Copy link

looks valid though I'm not sure I understand the motivation behind wanting only relative links. This makes the EIPs no longer able to be consumed in a stand-alone fashion.

I believe the opposite is true? When absolute links are used the document breaks when you are working on a fork, or hosting on a mirror, or browsing via IPFS, or local filesystem while offline, etc.. If you use relative links, then no matter how you are browsing the EIP repository, you'll be able to access everything.

Perhaps I was not clear enough by standalone. If you send the contents of an EIP in an email, none of the links will work. If you use anything other than a web server which is also serving all the other eips, then nothing works.

The opposite certainly is not true.

@lightclient
Copy link
Member

@BelfordZ happy to be proven otherwise, but I think the category of users you're describing is very small. Also, there is a lurking variable in your issue. I think the goal should be that an EIP should be understandable without access to the external resources (assuming the reader has the correct context), so if that's the case then the link format shouldn't matter too much to those users.

@MicahZoltu MicahZoltu marked this pull request as ready for review September 30, 2020 04:21
@MicahZoltu
Copy link
Contributor Author

I have been unable to get a review from any editors except lightclient, so I'm going to merge this as is. We generally green lit this change in an EIPIP meeting, but I was hoping to get some eyes to make sure I didn't screw up the migration. However, since everyone seems to be too busy I'm going to make an executive decision and merge this as is.

@MicahZoltu MicahZoltu merged commit 15f61ed into master Sep 30, 2020
@MicahZoltu MicahZoltu deleted the eip-linking branch September 30, 2020 04:22
tkstanczak pushed a commit to tkstanczak/EIPs that referenced this pull request Nov 7, 2020
…th format and the first reference must be linked. (ethereum#2947)

I have gone through and updated all existing EIPs to match this rule, including EIP-1.

In some cases, people were using markdown citations, I suspect because the long-form was a bit verbose to inline.  Since the relative path is quite short, I moved these to inline but I wouldn't be opposed to putting them back to citation format if that is desired by the authors.

In doing the migration/cleanup, I found some EIP references to EIPs that don't actually exist.  In these cases I tried to excise the reference from the EIP as best I could.

It is worth noting that the Readme actually already had this rule, it just wasn't expressed properly in EIP-1 and the "Citation Format" section of the readme I think caused people a bit of confusion (when citing externally, you should use the citation format).
Arachnid pushed a commit to Arachnid/EIPs that referenced this pull request Mar 6, 2021
…th format and the first reference must be linked. (ethereum#2947)

I have gone through and updated all existing EIPs to match this rule, including EIP-1.

In some cases, people were using markdown citations, I suspect because the long-form was a bit verbose to inline.  Since the relative path is quite short, I moved these to inline but I wouldn't be opposed to putting them back to citation format if that is desired by the authors.

In doing the migration/cleanup, I found some EIP references to EIPs that don't actually exist.  In these cases I tried to excise the reference from the EIP as best I could.

It is worth noting that the Readme actually already had this rule, it just wasn't expressed properly in EIP-1 and the "Citation Format" section of the readme I think caused people a bit of confusion (when citing externally, you should use the citation format).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants