From 7f6be2fc41be3c33167702a0b1f858aab046023a Mon Sep 17 00:00:00 2001 From: wighawag Date: Sat, 7 May 2016 06:30:33 +0100 Subject: [PATCH 0001/1085] draft-dapp-html-authorization --- EIPS/draft-dapp-html-authorization.md | 34 +++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 EIPS/draft-dapp-html-authorization.md diff --git a/EIPS/draft-dapp-html-authorization.md b/EIPS/draft-dapp-html-authorization.md new file mode 100644 index 0000000000000..0cfa9cb5e6700 --- /dev/null +++ b/EIPS/draft-dapp-html-authorization.md @@ -0,0 +1,34 @@ +
+  EIP: draft
+  Title: sendTransaction authorization via html
+  Author: Ronan Sandford 
+  Created: 2016-06-05
+  Status: Draft
+  Type: Standard
+
+ +Abstract +======== +This draft EIP describes the details of an authorization method provided by rpc enabled ethereum node allowing regular website to to send transaction (via "eth_sendTransaction") without the need to enable CORS for the website domain but instead ask the user permission. This would allow user to safely unlock their account while interacting with web based app running in their everyday web browser. + +Motivation +========== +Currently, if a user navigate to a dapp running on a website using his/her everyday browser, the dapp has either full access to "eth_sendTransaction" and "eth_sign" (if the user launched its node with CORS enabled for the website domain) or (more likely) none at all. In other word the user is forced to trust the dapp in order to use it. This is of course not acceptable and force existing dapp to rely on the use of workarround like: +- if the transaction is plain ether transfer the user is asked to enter it in the mist wallet +- For more complex case, the user is asked to enter the transaction manually via the node command line interface. + +Specification +============= +The dapp instead of connecting directly to the node, will instead communicate via 2 channels (a embeded invisible iframe for call that do not require an unlocked keys (most rpc calls) and a window for call to "eth_sendTransaction". call to "eth_sign" are not authorized since there is no way to display to the user the meaningfull content of the transaction in a safe way. +The invisible iframe allow teh dapp to continue making rpc call to the node without any CORS enabled. +The window on the other hand provide the dapp the only way to make a call to "eth_sendTransaction" by asking the user to confirm or cancel the transaction via a html dialog. + + +Rationale +========= + +Backward Compatibility +================= + +Implementations +=============== From 22a8af4b2b881058ffa081af67daaf4fdf79b5c3 Mon Sep 17 00:00:00 2001 From: wighawag Date: Sat, 7 May 2016 08:00:34 +0100 Subject: [PATCH 0002/1085] first draft --- EIPS/draft-dapp-html-authorization.md | 30 +++++++++++++++++++-------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/EIPS/draft-dapp-html-authorization.md b/EIPS/draft-dapp-html-authorization.md index 0cfa9cb5e6700..07a7f3cc475ed 100644 --- a/EIPS/draft-dapp-html-authorization.md +++ b/EIPS/draft-dapp-html-authorization.md @@ -1,6 +1,6 @@
   EIP: draft
-  Title: sendTransaction authorization via html
+  Title: safe "eth_sendTransaction" authorization via html popup
   Author: Ronan Sandford 
   Created: 2016-06-05
   Status: Draft
@@ -9,26 +9,38 @@
 
 Abstract
 ========
-This draft EIP describes the details of an authorization method provided by rpc enabled ethereum node allowing regular website to to send transaction (via "eth_sendTransaction") without the need to enable CORS for the website domain but instead ask the user permission. This would allow user to safely unlock their account while interacting with web based app running in their everyday web browser.
+This draft EIP describes the details of an authorization method provided by rpc enabled ethereum nodes allowing regular websites to send transactions (via ```eth_sendTransaction```) without the need to enable CORS for the website's domain. This is done by asking the user permission via an html popup served by the node itself. This allow users to to safely unlock their account while interacting with web based dapps running in their everyday web browser.
 
 Motivation
 ==========
-Currently, if a user navigate to a dapp running on a website using his/her everyday browser, the dapp has either full access to "eth_sendTransaction" and "eth_sign" (if the user launched its node with CORS enabled for the website domain) or (more likely) none at all. In other word the user is forced to trust the dapp in order to use it. This is of course not acceptable and force existing dapp to rely on the use of workarround like:
-- if the transaction is plain ether transfer the user is asked to enter it in the mist wallet 
+Currently, if a user navigate to a dapp running on a website using her/his everyday browser, the dapp will have by default no access to the rpc node for security reason. The user will have to enable CORS for the website's domain in order for the dapp to work. Unfortunately if the user do so, the dapp will be able to send transaction from any unlocked account without the need for any user consent. In other word not only the user need to change its node default setting but the user is also forced to trust the dapp in order to use it. This is of course not acceptable and force existing dapps to rely on the use of workarround like:
+- if the transaction is a plain ether transfer the user is asked to enter it in a dedicated trusted wallet like "Mist"
 - For more complex case, the user is asked to enter the transaction manually via the node command line interface.
+This proposal aims to provide a safe and user friendly alternative.
 
 Specification
 =============
-The dapp instead of connecting directly to the node, will instead communicate via 2 channels (a embeded invisible iframe for call that do not require an unlocked keys (most rpc calls) and a window for call to "eth_sendTransaction". call to "eth_sign" are not authorized since there is no way to display to the user the meaningfull content of the transaction in a safe way.
-The invisible iframe allow teh dapp to continue making rpc call to the node without any CORS enabled.
-The window on the other hand provide the dapp the only way to make a call to "eth_sendTransaction" by asking the user to confirm or cancel the transaction via a html dialog.
+In order for the mechanism to work, the node need to serve a static html file via http at the url /authorization 
+This file will then be used by the dapp in 2 different modes (invisible iframe and popup window).
+The invisible iframe will be embeded in the dapp to allow the dapp to send its rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port.
+In iframe node the html file's javascript code will ensure that no call requiring an unlocked key can be made. This is to prevent dapp for embedding the visible iframe and tricking the user into clicking the confirm button.
+If the dapp requires to make an ```eth_sendTransaction``` call, the dapp will instead open a new window using the same url.
+In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (not  ```eth_sign``` as there is no way to display to the user the meaningfull content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses as well the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request.
 
 
 Rationale
 =========
+The design for that proposal was chosen for its simplicity and security. A previous idea was to use an oauth-like protocol in order for the user to accept or deny a transaction request. It would have required deeper code change in the node and some geth contributors argues that such change did not fit into geth code base as it would have required dapp aware code. 
+The current design, instead has a very simple implementation (static html file that can be shared across node's implementation) and its safeness is guarantess by browsers' cross domain policies.
+The use of iframe/ window was required to have both security and user friendliness. The invisble iframe allow the dapp to execute read only calls without the need for user input and the window ensure the user approve before making a call. While we could have made it without the window mode by making the iframe confirmation use the native browser "window.confirm" dialog, this would have prevented the use of a more elegant confirmation popup that the current design allow.
 
-Backward Compatibility
-=================
 
 Implementations
 ===============
+In order to implement this design, the following html file need to be served at the url /authorization
+That's it
+
+
+```
+
+```
\ No newline at end of file

From 30fa6b371e49e73893dd53758ee4668d791713e9 Mon Sep 17 00:00:00 2001
From: wighawag 
Date: Sun, 8 May 2016 18:21:04 +0100
Subject: [PATCH 0003/1085] link image

---
 EIPS/draft-dapp-html-authorization.md         | 411 +++++++++++++++++-
 .../authorization.png                         | Bin 0 -> 20405 bytes
 2 files changed, 404 insertions(+), 7 deletions(-)
 create mode 100644 EIPS/draft-dapp-html-authorization/authorization.png

diff --git a/EIPS/draft-dapp-html-authorization.md b/EIPS/draft-dapp-html-authorization.md
index 07a7f3cc475ed..67abb784d4c56 100644
--- a/EIPS/draft-dapp-html-authorization.md
+++ b/EIPS/draft-dapp-html-authorization.md
@@ -9,7 +9,7 @@
 
 Abstract
 ========
-This draft EIP describes the details of an authorization method provided by rpc enabled ethereum nodes allowing regular websites to send transactions (via ```eth_sendTransaction```) without the need to enable CORS for the website's domain. This is done by asking the user permission via an html popup served by the node itself. This allow users to to safely unlock their account while interacting with web based dapps running in their everyday web browser.
+This draft EIP describes the details of an authorization method provided by rpc enabled ethereum nodes allowing regular websites to send transactions (via ```eth_sendTransaction```) without the need to enable CORS for the website's domain. This is done by asking the user permission via an html popup served by the node itself. This allow users to to safely unlock their account while interacting with web based dapps running in their everyday web browser. The html page also allow the user to enter their password when the account is unlocked and the node allowed "personal" api via rpc.
 
 Motivation
 ==========
@@ -17,22 +17,23 @@ Currently, if a user navigate to a dapp running on a website using her/his every
 - if the transaction is a plain ether transfer the user is asked to enter it in a dedicated trusted wallet like "Mist"
 - For more complex case, the user is asked to enter the transaction manually via the node command line interface.
 This proposal aims to provide a safe and user friendly alternative.
+
 
 Specification
 =============
-In order for the mechanism to work, the node need to serve a static html file via http at the url /authorization 
+In order for the mechanism to work, the node need to serve an html file via http at the url /authorization.html
 This file will then be used by the dapp in 2 different modes (invisible iframe and popup window).
-The invisible iframe will be embeded in the dapp to allow the dapp to send its rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port.
+The invisible iframe will be embeded in the dapp to allow the dapp to send its read-only rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port. The iframe first message is a message containing the string "ready" to let the parent know that it know accept messages.
 In iframe node the html file's javascript code will ensure that no call requiring an unlocked key can be made. This is to prevent dapp for embedding the visible iframe and tricking the user into clicking the confirm button.
 If the dapp requires to make an ```eth_sendTransaction``` call, the dapp will instead open a new window using the same url.
-In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (not  ```eth_sign``` as there is no way to display to the user the meaningfull content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses as well the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request.
-
+In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (not  ```eth_sign``` as there is no way to display to the user the meaningfull content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses as well the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request. Similarly to the iframemode, the window first message is a message containing the string "ready" to let the opener know that it know accept messages.
+The html page also check for the availability of the "personal" api and if so, will ask the user to unlock the account if necessary. The unlocking is temporary (3s) so the password will be asked again if a transaction is attempted before the end of this short time.
 
 Rationale
 =========
 The design for that proposal was chosen for its simplicity and security. A previous idea was to use an oauth-like protocol in order for the user to accept or deny a transaction request. It would have required deeper code change in the node and some geth contributors argues that such change did not fit into geth code base as it would have required dapp aware code. 
 The current design, instead has a very simple implementation (static html file that can be shared across node's implementation) and its safeness is guarantess by browsers' cross domain policies.
-The use of iframe/ window was required to have both security and user friendliness. The invisble iframe allow the dapp to execute read only calls without the need for user input and the window ensure the user approve before making a call. While we could have made it without the window mode by making the iframe confirmation use the native browser "window.confirm" dialog, this would have prevented the use of a more elegant confirmation popup that the current design allow.
+The use of iframe/ window was required to have both security and user friendliness. The invisble iframe allow the dapp to execute read only calls without the need for user input and the window ensure the user approve before making a call. While we could have made it without the window mode by making the iframe confirmation use the native browser ```window.confirm``` dialog, this would have prevented the use of a more elegant confirmation popup that the current design allow. It also happen to be that the ```window.confirm``` is not safe in some browser as it give focus to the accept option and can be triggered automatically (https://bugs.chromium.org/p/chromium/issues/detail?id=260653).
 
 
 Implementations
@@ -42,5 +43,401 @@ That's it
 
 
 ```
-
+
+
+    
+        Ethereum Authorization
+    
+    
+    
+    
+    
+    
+
+        
+
+

Please wait...

+
+ +
+
+

+

+ + +
+ + + + + + ``` \ No newline at end of file diff --git a/EIPS/draft-dapp-html-authorization/authorization.png b/EIPS/draft-dapp-html-authorization/authorization.png new file mode 100644 index 0000000000000000000000000000000000000000..b7dc9ae09806c6e93aed38317169b0c12452c1b0 GIT binary patch literal 20405 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 literal 0 HcmV?d00001 From 50ce9f45e4eacd6f45e9ad89bf10a98c2b5d4952 Mon Sep 17 00:00:00 2001 From: wighawag Date: Sun, 8 May 2016 18:26:03 +0100 Subject: [PATCH 0004/1085] add more images --- EIPS/draft-dapp-html-authorization.md | 6 ++++++ .../authorization-locked.png | Bin 0 -> 23224 bytes .../authorization-password.png | Bin 0 -> 22099 bytes 3 files changed, 6 insertions(+) create mode 100644 EIPS/draft-dapp-html-authorization/authorization-locked.png create mode 100644 EIPS/draft-dapp-html-authorization/authorization-password.png diff --git a/EIPS/draft-dapp-html-authorization.md b/EIPS/draft-dapp-html-authorization.md index 67abb784d4c56..479c4338d39be 100644 --- a/EIPS/draft-dapp-html-authorization.md +++ b/EIPS/draft-dapp-html-authorization.md @@ -16,9 +16,15 @@ Motivation Currently, if a user navigate to a dapp running on a website using her/his everyday browser, the dapp will have by default no access to the rpc node for security reason. The user will have to enable CORS for the website's domain in order for the dapp to work. Unfortunately if the user do so, the dapp will be able to send transaction from any unlocked account without the need for any user consent. In other word not only the user need to change its node default setting but the user is also forced to trust the dapp in order to use it. This is of course not acceptable and force existing dapps to rely on the use of workarround like: - if the transaction is a plain ether transfer the user is asked to enter it in a dedicated trusted wallet like "Mist" - For more complex case, the user is asked to enter the transaction manually via the node command line interface. + + This proposal aims to provide a safe and user friendly alternative. + + + + Specification ============= In order for the mechanism to work, the node need to serve an html file via http at the url /authorization.html diff --git a/EIPS/draft-dapp-html-authorization/authorization-locked.png b/EIPS/draft-dapp-html-authorization/authorization-locked.png new file mode 100644 index 0000000000000000000000000000000000000000..4f881bcafe0e75eec48992ab251e811653367cb3 GIT binary patch literal 23224 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 Date: Sun, 8 May 2016 18:28:06 +0100 Subject: [PATCH 0005/1085] title to images --- EIPS/draft-dapp-html-authorization.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/EIPS/draft-dapp-html-authorization.md b/EIPS/draft-dapp-html-authorization.md index 479c4338d39be..1b92bd4322ffa 100644 --- a/EIPS/draft-dapp-html-authorization.md +++ b/EIPS/draft-dapp-html-authorization.md @@ -18,12 +18,20 @@ Currently, if a user navigate to a dapp running on a website using her/his every - For more complex case, the user is asked to enter the transaction manually via the node command line interface. -This proposal aims to provide a safe and user friendly alternative. +This proposal aims to provide a safe and user friendly alternative: + +Account unlocked : +----------------- +Account locked and no "personal" api exposed via rpc: +----------------- + + +Account locked but node exposing the "personal" api via rpc : +----------------- - Specification ============= From d7bdc8c10a86026514ab0a7cba40d454ecec2f73 Mon Sep 17 00:00:00 2001 From: wighawag Date: Sun, 8 May 2016 23:25:30 +0100 Subject: [PATCH 0006/1085] progress --- EIPS/draft-dapp-html-authorization.md | 30 ++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/EIPS/draft-dapp-html-authorization.md b/EIPS/draft-dapp-html-authorization.md index 1b92bd4322ffa..f0809f0c53036 100644 --- a/EIPS/draft-dapp-html-authorization.md +++ b/EIPS/draft-dapp-html-authorization.md @@ -9,50 +9,66 @@ Abstract ======== -This draft EIP describes the details of an authorization method provided by rpc enabled ethereum nodes allowing regular websites to send transactions (via ```eth_sendTransaction```) without the need to enable CORS for the website's domain. This is done by asking the user permission via an html popup served by the node itself. This allow users to to safely unlock their account while interacting with web based dapps running in their everyday web browser. The html page also allow the user to enter their password when the account is unlocked and the node allowed "personal" api via rpc. +This draft EIP describes the details of an authorization method that if provided by rpc enabled ethereum nodes would allow regular websites to send transactions (via ```eth_sendTransaction```) without the need to enable CORS for the website's domain but instead with the required consent from the users. + +For every transaction that the dapp wish to execute, an html popup is presented to the user to allow him/her to cancel or confirm the transaction. This allow users to safely interact with dapp running in their everyday web browser while their accounts are unlocked. In case the account is not unlocked and the node has allowed the "personal" api via rpc,the html page also allow the user to enter their password to unlock the account for the scope of the transaction. Motivation ========== -Currently, if a user navigate to a dapp running on a website using her/his everyday browser, the dapp will have by default no access to the rpc node for security reason. The user will have to enable CORS for the website's domain in order for the dapp to work. Unfortunately if the user do so, the dapp will be able to send transaction from any unlocked account without the need for any user consent. In other word not only the user need to change its node default setting but the user is also forced to trust the dapp in order to use it. This is of course not acceptable and force existing dapps to rely on the use of workarround like: +Currently, if a user navigate to a dapp running on a website using her/his everyday browser, the dapp will have by default no access to the rpc api for security reason. The user will have to enable CORS for the website's domain in order for the dapp to work. Unfortunately if the user do so, the dapp will be able to send transaction from any unlocked account without the need for any user consent. In other word not only the user need to change its node default setting but the user is also forced to trust the dapp in order to use it. This is of course not acceptable and force existing dapps to rely on the use of workarround like: - if the transaction is a plain ether transfer the user is asked to enter it in a dedicated trusted wallet like "Mist" - For more complex case, the user is asked to enter the transaction manually via the node command line interface. This proposal aims to provide a safe and user friendly alternative: +Here are some screenshot of the provided implementation of that html popup: + Account unlocked : ----------------- +When the account is already unlocked, the user is presented with the following popup for every transaction that the dapp attempts to make : + Account locked and no "personal" api exposed via rpc: ----------------- +When the account is locked and the node do not provide access to account unlocking via its rpc interface, the following popup will be presented. This is not ideal since this require the user to know how to unlock an account: + Account locked but node exposing the "personal" api via rpc : ----------------- +A better option is to ask the user the password but this is only possible if the node allow access to the "personal" api via rpc. In such case the following dialog will be presented to the user so he/she can accept the transaction by providing the password required to unlock the account: + Specification ============= -In order for the mechanism to work, the node need to serve an html file via http at the url /authorization.html +In order for the mechanism to work, the node need to serve an html file via http at the url \/authorization.html + This file will then be used by the dapp in 2 different modes (invisible iframe and popup window). -The invisible iframe will be embeded in the dapp to allow the dapp to send its read-only rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port. The iframe first message is a message containing the string "ready" to let the parent know that it know accept messages. + +The invisible iframe will be embeded in the dapp to allow the dapp to send its read-only rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port. The iframe first message is a message containing the string "ready" to let the parent know that it now accepts messages. + In iframe node the html file's javascript code will ensure that no call requiring an unlocked key can be made. This is to prevent dapp for embedding the visible iframe and tricking the user into clicking the confirm button. If the dapp requires to make an ```eth_sendTransaction``` call, the dapp will instead open a new window using the same url. -In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (not ```eth_sign``` as there is no way to display to the user the meaningfull content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses as well the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request. Similarly to the iframemode, the window first message is a message containing the string "ready" to let the opener know that it know accept messages. + +In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (but not ```eth_sign``` as there is no way to display to the user the meaningfull content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses as well the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request. Similarly to the iframe mode, the window first message is a message containing the string "ready" to let the opener know that it now accepts messages. + The html page also check for the availability of the "personal" api and if so, will ask the user to unlock the account if necessary. The unlocking is temporary (3s) so the password will be asked again if a transaction is attempted before the end of this short time. Rationale ========= The design for that proposal was chosen for its simplicity and security. A previous idea was to use an oauth-like protocol in order for the user to accept or deny a transaction request. It would have required deeper code change in the node and some geth contributors argues that such change did not fit into geth code base as it would have required dapp aware code. -The current design, instead has a very simple implementation (static html file that can be shared across node's implementation) and its safeness is guarantess by browsers' cross domain policies. +The current design, instead has a very simple implementation (self contained html file that can be shared across node's implementation) and its safeness is guarantess by browsers' cross domain policies. + The use of iframe/ window was required to have both security and user friendliness. The invisble iframe allow the dapp to execute read only calls without the need for user input and the window ensure the user approve before making a call. While we could have made it without the window mode by making the iframe confirmation use the native browser ```window.confirm``` dialog, this would have prevented the use of a more elegant confirmation popup that the current design allow. It also happen to be that the ```window.confirm``` is not safe in some browser as it give focus to the accept option and can be triggered automatically (https://bugs.chromium.org/p/chromium/issues/detail?id=260653). Implementations =============== -In order to implement this design, the following html file need to be served at the url /authorization +In order to implement this design, the following html file need to be served at the url \/authorization.html That's it From 15e4c31d443363ad1d514689f2da59a816c307bd Mon Sep 17 00:00:00 2001 From: wighawag Date: Mon, 9 May 2016 16:41:46 +0100 Subject: [PATCH 0007/1085] improvements --- EIPS/draft-dapp-html-authorization.md | 791 +++++++++++++------------- 1 file changed, 410 insertions(+), 381 deletions(-) diff --git a/EIPS/draft-dapp-html-authorization.md b/EIPS/draft-dapp-html-authorization.md index f0809f0c53036..f34c59ddcc463 100644 --- a/EIPS/draft-dapp-html-authorization.md +++ b/EIPS/draft-dapp-html-authorization.md @@ -9,9 +9,9 @@ Abstract ======== -This draft EIP describes the details of an authorization method that if provided by rpc enabled ethereum nodes would allow regular websites to send transactions (via ```eth_sendTransaction```) without the need to enable CORS for the website's domain but instead with the required consent from the users. +This draft EIP describes the details of an authorization method that if provided by rpc enabled ethereum nodes would allow regular websites to send transactions (via ```eth_sendTransaction```) without the need to enable CORS. Instead, user would be asked to confirm the transaction via an html popup. -For every transaction that the dapp wish to execute, an html popup is presented to the user to allow him/her to cancel or confirm the transaction. This allow users to safely interact with dapp running in their everyday web browser while their accounts are unlocked. In case the account is not unlocked and the node has allowed the "personal" api via rpc,the html page also allow the user to enter their password to unlock the account for the scope of the transaction. +Every read only rpc calls the dapp want to perform are redirected to an invisible iframe from the node's domain and for every transaction that the dapp wish to execute, an html popup is presented to the user to allow him/her to cancel or confirm the transaction. This allow the dapp to connect to the node's rpc api without being granted any kind of privileges. This allow users to safely interact with dapp running in their everyday web browser while their accounts are unlocked. In case the account is not unlocked and the node has allowed the "personal" api via rpc,the html page also allow the user to enter their password to unlock the account for the scope of the transaction. Motivation ========== @@ -20,7 +20,7 @@ Currently, if a user navigate to a dapp running on a website using her/his every - For more complex case, the user is asked to enter the transaction manually via the node command line interface. -This proposal aims to provide a safe and user friendly alternative: +This proposal aims to provide a safe and user friendly alternative. Here are some screenshot of the provided implementation of that html popup: @@ -49,15 +49,46 @@ In order for the mechanism to work, the node need to serve an html file via http This file will then be used by the dapp in 2 different modes (invisible iframe and popup window). -The invisible iframe will be embeded in the dapp to allow the dapp to send its read-only rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port. The iframe first message is a message containing the string "ready" to let the parent know that it now accepts messages. +The invisible iframe will be embeded in the dapp to allow the dapp to send its read-only rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port. In iframe node the html file's javascript code will ensure that no call requiring an unlocked key can be made. This is to prevent dapp for embedding the visible iframe and tricking the user into clicking the confirm button. If the dapp requires to make an ```eth_sendTransaction``` call, the dapp will instead open a new window using the same url. -In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (but not ```eth_sign``` as there is no way to display to the user the meaningfull content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses as well the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request. Similarly to the iframe mode, the window first message is a message containing the string "ready" to let the opener know that it now accepts messages. +In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (but not ```eth_sign``` as there is no way to display to the user the meaningfull content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses as well the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request. The html page also check for the availability of the "personal" api and if so, will ask the user to unlock the account if necessary. The unlocking is temporary (3s) so the password will be asked again if a transaction is attempted before the end of this short time. +In both iframe mode and window mode, the communication with the dapp is achieved using ```window.postMessage```. +The fist message the iframe/window send is a message containing the string "ready" to let the dapp know that it now accepts messages. Then the dapp can start performing rpc call by sending message using the following object : +``` +{ + id:, //so responses can be match as there is no guarantee of the order of the response + payload: //this is the exact object that usually send to the node +} +``` + +For ```eth_sendTransaction``` the "gas", "gasPrice" and "from" field need to be set in the rpc parameter so that the window can display the correct value. If not all of these are passed in, the window will return an error. + +Upon receiving such message, the iframe will perform the actual rpc call to the node but only if such a call is a read only call (not requiring an unlocked key). If it is not it will return a error. The window on the other will also accept ```eth_sendTransaction``` calls but will display a dialog so the user can accept or cancel the request. + +In all the cases, the iframe/window will send a message back to the dapp using the following object: +``` +{ + id:, + result:, + error: +} +``` + +the error object cannot be a javascript Error object due to postMessage limitation. Instead it is +``` +{ + message:, + type: //type="cancel" means the user cancel the transaction +} +``` + + Rationale ========= The design for that proposal was chosen for its simplicity and security. A previous idea was to use an oauth-like protocol in order for the user to accept or deny a transaction request. It would have required deeper code change in the node and some geth contributors argues that such change did not fit into geth code base as it would have required dapp aware code. @@ -68,406 +99,404 @@ The use of iframe/ window was required to have both security and user friendline Implementations =============== -In order to implement this design, the following html file need to be served at the url \/authorization.html +In order to implement this design, the following html file or an equivalent one need to be served at the url \/authorization.html + That's it ``` - - Ethereum Authorization - + + Ethereum Authorization + + + + + + + +
+
+

Please wait...

+
+ +
+
+

+

+ + +
+ + + + var pleaseWait = document.getElementById("pleasewait"); + var form = document.getElementById("form"); + var cancelButton = document.getElementById("cancel-button"); + var confirmButton = document.getElementById("confirm-button"); + var message = document.getElementById("message"); + var password = document.getElementById("password"); + var passwordField = document.getElementById("passwordField"); + var modalDialog = document.getElementById("modal-dialog"); + var modalDialogButton = document.getElementById("modal-dialog-button"); + var modalDialogTitle = document.getElementById("modal-dialog-title"); + var modalDialogMessage = document.getElementById("modal-dialog-message"); - + }; + + try { + request.send(JSON.stringify(payload)); + } catch(e) { + callback({message:'CONNECTION ERROR: Couldn\'t connect to node '+ url +'.',type:"noConnection"}); + } + } - - -
-
-

Please wait...

-
- -
-
-

-

- - -
+ function addBlocky(message, address){ + var icon = blockies.create({ + seed: address, + size: 8, + scale: 6 + }); + message.appendChild(icon); + } - - - - + }else{ + firstUrl = event.origin; + } + var data = event.data; + processMessage(data,event.source); + } + + function processMessage(data, sourceWindow){ + if(data.payload.method == "eth_sendTransaction" || data.payload.method == "eth_sign"){ + if(inIframe){ + sourceWindow.postMessage({id:data.id,result:null,error:{message:"Cannot make call that require an unlocked key (" + data.payload.method + ") via iframe"},type:"notAllowed"},sourceWindow.location.href); + }else if(data.payload.method == "eth_sign"){ + sourceWindow.postMessage({id:data.id,result:null,error:{message:"cannot sign transaction (" + data.payload.method + ") via html",type:"notAllowed"}},sourceWindow.location.href); + }else{ + var transactionInfo = null; + if(data.payload.params.length > 0){ + if(data.payload.params[0]["gas"] && data.payload.params[0]["gasPrice"] && data.payload.params[0]["to"] && data.payload.params[0]["from"]){ + transactionInfo = data.payload.params[0]; + } + } + if(transactionInfo != null){ + needToAndCanUnlockAccount(transactionInfo.from,data.url,function(requireUnlock,canUnlock){ + if(requireUnlock && canUnlock){ + askAuthorization(transactionInfo,data,true, sourceWindow); + }else if(!requireUnlock){ + askAuthorization(transactionInfo,data,false,sourceWindow); + }else if(requireUnlock && !canUnlock){ + var messageHtml = document.createElement('span'); + addBlocky(messageHtml,transactionInfo.from); + messageHtml.appendChild(document.createElement('br')); + var span = document.createElement('span'); + span.innerHTML = "You need to unlock your account first :
" + transactionInfo.from; + messageHtml.appendChild(span); + + showMessage("Account Locked",messageHtml,function(){ + processMessage(data,sourceWindow); + }, "Done"); + } + + }); + }else{ + sourceWindow.postMessage({id:data.id,result:null,error:{message:"Need to specify from , to, gas and gasPrice"},type:"notValid"},sourceWindow.location.href); + window.close(); + } + } + }else{ + sendAsync(data.url,data.payload,function(error,result){ + sourceWindow.postMessage({id:data.id,result:result,error:error},sourceWindow.location.href); + }); + } + } + + + window.addEventListener("message", receiveMessage); + if(source){ + source.postMessage("ready",source.location.href); + } + + + ``` \ No newline at end of file From f3cb9f599e71f4232e3af7f4147e6d3bdc18aaec Mon Sep 17 00:00:00 2001 From: wighawag Date: Tue, 10 May 2016 18:39:24 +0100 Subject: [PATCH 0008/1085] improvements to html implementation --- EIPS/draft-dapp-html-authorization.md | 91 +++++++++++++++++++-------- 1 file changed, 65 insertions(+), 26 deletions(-) diff --git a/EIPS/draft-dapp-html-authorization.md b/EIPS/draft-dapp-html-authorization.md index f0809f0c53036..025fd318bc78f 100644 --- a/EIPS/draft-dapp-html-authorization.md +++ b/EIPS/draft-dapp-html-authorization.md @@ -198,13 +198,13 @@ That's it

Please wait...

-
+

- - -
+ + + From ed674d282bade2636790ed504edd8f71af18d5b0 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 12 May 2016 01:34:19 -0700 Subject: [PATCH 0013/1085] Corrected some grammar. --- EIPS/eip-XXX.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/EIPS/eip-XXX.md b/EIPS/eip-XXX.md index ba13a3caeb0ab..db829030f7269 100644 --- a/EIPS/eip-XXX.md +++ b/EIPS/eip-XXX.md @@ -11,55 +11,55 @@ Abstract ======== This draft EIP describes the details of an authorization method that if provided by rpc enabled ethereum nodes would allow regular websites to send transactions (via ```eth_sendTransaction```) without the need to enable CORS. Instead, user would be asked to confirm the transaction via an html popup. -Every read only rpc calls the dapp want to perform are redirected to an invisible iframe from the node's domain and for every transaction that the dapp wish to execute, an html popup is presented to the user to allow him/her to cancel or confirm the transaction. This allow the dapp to connect to the node's rpc api without being granted any kind of privileges. This allow users to safely interact with dapp running in their everyday web browser while their accounts are unlocked. In case the account is not unlocked and the node has allowed the "personal" api via rpc,the html page also allow the user to enter their password to unlock the account for the scope of the transaction. +Every read only rpc call the dapp wants to perform is redirected to an invisible iframe from the node's domain and for every transaction that the dapp wish to execute, an html popup is presented to the user to allow him/her to cancel or confirm the transaction. This allows the dapp to connect to the node's rpc api without being granted any kind of privileges. This allows users to safely interact with dapps running in their everyday web browser while their accounts are unlocked. In case the account is not unlocked, and the node has allowed the "personal" api via rpc,the html page also allow the user to enter their password to unlock the account for the scope of the transaction. Motivation ========== -Currently, if a user navigate to a dapp running on a website using her/his everyday browser, the dapp will have by default no access to the rpc api for security reason. The user will have to enable CORS for the website's domain in order for the dapp to work. Unfortunately if the user do so, the dapp will be able to send transaction from any unlocked account without the need for any user consent. In other word not only the user need to change its node default setting but the user is also forced to trust the dapp in order to use it. This is of course not acceptable and force existing dapps to rely on the use of workarround like: -- if the transaction is a plain ether transfer the user is asked to enter it in a dedicated trusted wallet like "Mist" +Currently, if a user navigates to a dapp running on a website using her/his everyday browser, the dapp will by default have no access to the rpc api for security reasons. The user will have to enable CORS for the website's domain in order for the dapp to work. Unfortunately if the user does so, the dapp will be able to send transactions from any unlocked account without the need for any user consent. In other words, not only does the user need to change the node's default setting, but the user is also forced to trust the dapp in order to use it. This is of course not acceptable and forces existing dapps to rely on the use of workarrounds like: +- if the transaction is a plain ether transfer, the user is asked to enter it in a dedicated trusted wallet like "Mist" - For more complex case, the user is asked to enter the transaction manually via the node command line interface. This proposal aims to provide a safe and user friendly alternative. -Here are some screenshot of the provided implementation of that html popup: +Here are some screenshots of the provided implementation of that html popup: Account unlocked : ----------------- -When the account is already unlocked, the user is presented with the following popup for every transaction that the dapp attempts to make : +When the account is already unlocked, the user is presented with the following popup for every transaction that the dapp attempts to make: Account locked and no "personal" api exposed via rpc: ----------------- -When the account is locked and the node do not provide access to account unlocking via its rpc interface, the following popup will be presented. This is not ideal since this require the user to know how to unlock an account: +When the account is locked, and the node does not provide access to account unlocking via its rpc interface, the following popup will be presented. This is not ideal since this requires the user to know how to unlock an account: Account locked but node exposing the "personal" api via rpc : ----------------- -A better option is to ask the user the password but this is only possible if the node allow access to the "personal" api via rpc. In such case the following dialog will be presented to the user so he/she can accept the transaction by providing the password required to unlock the account: +A better option is to ask the user for their password, but this is only possible if the node allows access to the "personal" api via rpc. In such case, the following dialog will be presented to the user so he/she can accept the transaction by providing the password required to unlock the account: Specification ============= -In order for the mechanism to work, the node need to serve an html file via http at the url \/authorization.html +In order for the mechanism to work, the node needs to serve an html file via http at the url \/authorization.html This file will then be used by the dapp in 2 different modes (invisible iframe and popup window). The invisible iframe will be embeded in the dapp to allow the dapp to send its read-only rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port. -In iframe node the html file's javascript code will ensure that no call requiring an unlocked key can be made. This is to prevent dapp for embedding the visible iframe and tricking the user into clicking the confirm button. -If the dapp requires to make an ```eth_sendTransaction``` call, the dapp will instead open a new window using the same url. +In the iframe node, the html file's javascript code will ensure that no call requiring an unlocked key can be made. This is to prevent dapps from embedding the invisible iframe and tricking the user into clicking the confirm button. +If the dapp requires an ```eth_sendTransaction``` call, the dapp will instead open a new window using the same url. -In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (but not ```eth_sign``` as there is no way to display to the user the meaningfull content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses as well the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request. +In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (but not ```eth_sign```, as there is no way to display to the user the meaningful content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses, as well as the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request. -The html page also check for the availability of the "personal" api and if so, will ask the user to unlock the account if necessary. The unlocking is temporary (3s) so the password will be asked again if a transaction is attempted before the end of this short time. +The html page also checks for the availability of the "personal" api and if so, will ask the user to unlock the account if necessary. The unlocking is temporary (3s) so the password will be asked again if a transaction is attempted before the end of this short time. In both iframe mode and window mode, the communication with the dapp is achieved using ```window.postMessage```. -The fist message the iframe/window send is a message containing the string "ready" to let the dapp know that it now accepts messages. Then the dapp can start performing rpc call by sending message using the following object : +The fist message the iframe/window sends is a message containing the string "ready" to let the dapp know that it now accepts messages. Then the dapp can start performing rpc call by sending message using the following object : ``` { id:
, //so responses can be match as there is no guarantee of the order of the response @@ -94,14 +94,14 @@ Rationale The design for that proposal was chosen for its simplicity and security. A previous idea was to use an oauth-like protocol in order for the user to accept or deny a transaction request. It would have required deeper code change in the node and some geth contributors argues that such change did not fit into geth code base as it would have required dapp aware code. The current design, instead has a very simple implementation (self contained html file that can be shared across node's implementation) and its safeness is guarantess by browsers' cross domain policies. -The use of iframe/ window was required to have both security and user friendliness. The invisble iframe allow the dapp to execute read only calls without the need for user input and the window ensure the user approve before making a call. While we could have made it without the window mode by making the iframe confirmation use the native browser ```window.confirm``` dialog, this would have prevented the use of a more elegant confirmation popup that the current design allow. It also happen to be that the ```window.confirm``` is not safe in some browser as it give focus to the accept option and can be triggered automatically (https://bugs.chromium.org/p/chromium/issues/detail?id=260653). +The use of iframe/ window was required to have both security and user friendliness. The invisble iframe allows the dapp to execute read only calls without the need for user input, and the window ensures user approval before making a call. While we could have made it without the window mode by making the iframe confirmation use the native browser ```window.confirm``` dialog, this would have prevented the use of a more elegant confirmation popup that the current design allows. It also happens to be that the ```window.confirm``` is not safe in some browsers, as it gives focus to the accept option and can be triggered automatically (https://bugs.chromium.org/p/chromium/issues/detail?id=260653). Implementations =============== -In order to implement this design, the following html file or an equivalent one need to be served at the url \/authorization.html +In order to implement this design, the following html file or an equivalent one needs to be served at the url \/authorization.html -That's it +That's it. ``` @@ -610,4 +610,4 @@ That's it -``` \ No newline at end of file +``` From 4fa9b321c035424d788b56b172755984af212bad Mon Sep 17 00:00:00 2001 From: wighawag Date: Thu, 12 May 2016 17:14:58 +0100 Subject: [PATCH 0014/1085] fix spelling --- EIPS/eip-XXX.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-XXX.md b/EIPS/eip-XXX.md index db829030f7269..d183d4b2a5c67 100644 --- a/EIPS/eip-XXX.md +++ b/EIPS/eip-XXX.md @@ -51,7 +51,7 @@ This file will then be used by the dapp in 2 different modes (invisible iframe a The invisible iframe will be embeded in the dapp to allow the dapp to send its read-only rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port. -In the iframe node, the html file's javascript code will ensure that no call requiring an unlocked key can be made. This is to prevent dapps from embedding the invisible iframe and tricking the user into clicking the confirm button. +In the iframe mode, the html file's javascript code will ensure that no call requiring an unlocked key can be made. This is to prevent dapps from embedding the invisible iframe and tricking the user into clicking the confirm button. If the dapp requires an ```eth_sendTransaction``` call, the dapp will instead open a new window using the same url. In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (but not ```eth_sign```, as there is no way to display to the user the meaningful content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses, as well as the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request. From 5a483366b6cb9781c5ee0a75eea5abec3eaccbc5 Mon Sep 17 00:00:00 2001 From: ethers Date: Thu, 27 Oct 2016 21:26:52 -0700 Subject: [PATCH 0015/1085] Catalog EIP 150 as accepted For https://github.com/ethereum/EIPs/issues/163 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 75c79c7cd038f..595757f629c73 100644 --- a/README.md +++ b/README.md @@ -17,3 +17,4 @@ First review [EIP-1](EIPS/eip-1.mediawiki). Then clone the repository and add yo | [6](EIPS/eip-6.md) | Renaming Suicide Variable | Hudson Jameson | Meta | | [Draft](https://github.com/ethereum/EIPs/pull/42) | | [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Standard | homestead (hard-fork) | [Accepted](https://github.com/ethereum/EIPs/issues/23) | | [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Standard | Networking | [Accepted](https://github.com/ethereum/EIPs/pull/49) | +| [150](https://github.com/ethereum/EIPs/issues/150) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Standard | Consensus (hard-fork) | [Accepted](https://github.com/ethereum/EIPs/issues/150) | From 2fc9a67718690a2cd924c6b89203cae218174464 Mon Sep 17 00:00:00 2001 From: sandakersmann Date: Fri, 4 Nov 2016 03:47:24 +0100 Subject: [PATCH 0016/1085] HF2 update of README.md HF2 update of README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 595757f629c73..555b388992034 100644 --- a/README.md +++ b/README.md @@ -18,3 +18,6 @@ First review [EIP-1](EIPS/eip-1.mediawiki). Then clone the repository and add yo | [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Standard | homestead (hard-fork) | [Accepted](https://github.com/ethereum/EIPs/issues/23) | | [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Standard | Networking | [Accepted](https://github.com/ethereum/EIPs/pull/49) | | [150](https://github.com/ethereum/EIPs/issues/150) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Standard | Consensus (hard-fork) | [Accepted](https://github.com/ethereum/EIPs/issues/150) | +| [155](https://github.com/ethereum/EIPs/issues/155) | Simple replay attack protection | Vitalik Buterin | Standard | Consensus (hard-fork) | [Accepted](https://github.com/ethereum/EIPs/issues/155) | +| [160](https://github.com/ethereum/EIPs/issues/160) | EXP cost increase | Vitalik Buterin | Standard | Consensus (hard-fork) | [Accepted](https://github.com/ethereum/EIPs/issues/160) | +| [161](https://github.com/ethereum/EIPs/issues/161) | State trie clearing (invariant-preserving alternative) | Gavin Wood | Standard | Consensus (hard-fork) | [Accepted](https://github.com/ethereum/EIPs/issues/161) | From 2e8a1049ceb1f429b506f699e874eb40834504e1 Mon Sep 17 00:00:00 2001 From: sandakersmann Date: Tue, 15 Nov 2016 17:43:42 +0100 Subject: [PATCH 0017/1085] Add EIP170 Add EIP170 (Contract code size limit) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 555b388992034..cb687a5644903 100644 --- a/README.md +++ b/README.md @@ -21,3 +21,4 @@ First review [EIP-1](EIPS/eip-1.mediawiki). Then clone the repository and add yo | [155](https://github.com/ethereum/EIPs/issues/155) | Simple replay attack protection | Vitalik Buterin | Standard | Consensus (hard-fork) | [Accepted](https://github.com/ethereum/EIPs/issues/155) | | [160](https://github.com/ethereum/EIPs/issues/160) | EXP cost increase | Vitalik Buterin | Standard | Consensus (hard-fork) | [Accepted](https://github.com/ethereum/EIPs/issues/160) | | [161](https://github.com/ethereum/EIPs/issues/161) | State trie clearing (invariant-preserving alternative) | Gavin Wood | Standard | Consensus (hard-fork) | [Accepted](https://github.com/ethereum/EIPs/issues/161) | +| [170](https://github.com/ethereum/EIPs/issues/170) | Contract code size limit | Vitalik Buterin | Standard | Consensus (hard-fork) | [Accepted](https://github.com/ethereum/EIPs/issues/170) | From f690686b6598e77710a59bb3c8008888c385e29a Mon Sep 17 00:00:00 2001 From: Hudson Jameson Date: Wed, 7 Dec 2016 19:29:21 -0600 Subject: [PATCH 0018/1085] Update eip-1.mediawiki --- EIPS/eip-1.mediawiki | 69 +++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/EIPS/eip-1.mediawiki b/EIPS/eip-1.mediawiki index 05625c15d8516..7f31439716530 100644 --- a/EIPS/eip-1.mediawiki +++ b/EIPS/eip-1.mediawiki @@ -3,8 +3,8 @@ Title: EIP Purpose and Guidelines Status: Draft Type: Meta - Author: Martin Becze - Created: 2015-10-27 + Author: Martin Becze , Hudson Jameson + Created: 2015-10-27, 2016-12-07
==What is a EIP?== @@ -13,20 +13,19 @@ EIP stands for Ethereum Improvement Proposal. A EIP is a design document providi ==EIP Rational== -We intend EIPs to be the primary mechanisms for proposing new features, for collecting community input on an issue and for documenting the design decisions that have gone into Ethereum. Because the EIPs are maintained as text files in a versioned repository, their revision history is the historical record of the feature proposal. +We intend EIPs to be the primary mechanisms for proposing new features, for collecting community input on an issue, and for documenting the design decisions that have gone into Ethereum. Because the EIPs are maintained as text files in a versioned repository, their revision history is the historical record of the feature proposal. For Ethereum implementers, EIPs are a convenient way to track the progress of their implementation. Ideally each implementation maintainer would list the EIPs that they have implemented. This will give end users a convenient way to know the current status of a given implementation or library. -EIPs are intend to replace the venerable etherpads which described the initial PoC (Proof of Concept) and strike a balance between ease of accessibility and trackablity. - ==EIP Types== -There are three kinds of EIP: - -* A Standard Track EIP describes any change that affects most or all Ethereum implementations, such as a change to the [https://github.com/ethereum/yellowpaper Yellow Paper], the network protocol, a change in block or transaction validity rules, or any change or addition that affects the interoperability of applications using Ethereum. Furthermore Standard EIPs can be broken down into the following categories. -** Consensus - Once PoS has been established it is expected that PoS protocol will have a separate specification. -** Networking - Currently Networking discussion tracks in the [https://github.com/ethereum/devp2p devp2p repository]. +There are three types of EIP: +* A Standard Track EIP describes any change that affects most or all Ethereum implementations, such as a change to the the network protocol, a change in block or transaction validity rules, proposed application standards/conventions, or any change or addition that affects the interoperability of applications using Ethereum. Furthermore Standard EIPs can be broken down into the following categories. +** Core - improvements requiring a consensus fork (e.g. [https://github.com/ethereum/EIPs/blob/master/EIPS/eip-5.md EIP5], [https://github.com/ethereum/EIPs/issues/28 EIP101]), as well as changes that are not necessarily consensus critical but may be relevant to “core dev” discussions (for example, [https://github.com/ethereum/EIPs/issues/90 EIP90], and the miner/node strategy changes 2, 3, and 4 of [https://github.com/ethereum/EIPs/issues/86#issue-145324865 EIP86]). +** Networking - includes improvements around [https://github.com/ethereum/wiki/wiki/%C3%90%CE%9EVp2p-Wire-Protocol devp2p] ([https://github.com/ethereum/EIPs/blob/master/EIPS/eip-8.md EIP8]) and [https://github.com/ethereum/wiki/wiki/Light-client-protocol Light Ethereum Subprotocol], as well as proposed improvements to network protocol specifications of [https://gist.github.com/gluk256/4654922ca45eb9d0846d941d7ca326f4 whisper] and [https://github.com/ethereum/go-ethereum/pull/2959 swarm]. +** Interface - includes improvements around client [https://github.com/ethereum/wiki/wiki/JSON-RPC API/RPC] specifications and standards, and also certain language-level standards like method names ([https://github.com/ethereum/EIPs/issues/59 EIP59], [https://github.com/ethereum/EIPs/blob/master/EIPS/eip-6.md EIP6]) and [https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI contract ABIs]. The label “interface” aligns with the [https://github.com/ethereum/interfaces interfaces repo] and discussion should primarily occur in that repository before an EIP is submitted to the EIPs repository. +** ERC - application-level standards and conventions, including contract standards such as token standards ([https://github.com/ethereum/EIPs/issues/20 ERC20]), name registries ([https://github.com/ethereum/EIPs/issues/26 ERC26], [https://github.com/ethereum/EIPs/issues/137 ERC137]), URI schemes ([https://github.com/ethereum/EIPs/issues/67 ERC67]), library/package formats ([https://github.com/ethereum/EIPs/issues/82 EIP82]), and wallet formats ([https://github.com/ethereum/EIPs/issues/75 EIP75], [https://github.com/ethereum/EIPs/issues/85 EIP85]). * An Informational EIP describes a Ethereum design issue, or provides general guidelines or information to the Ethereum community, but does not propose a new feature. Informational EIPs do not necessarily represent Ethereum community consensus or a recommendation, so users and implementors are free to ignore Informational EIPs or follow their advice. * A Meta EIP describes a process surrounding Ethereum or proposes a change to (or an event in) a process. Process EIPs are like Standards Track EIPs but apply to areas other than the Ethereum protocol itself. They may propose an implementation, but not to Ethereum's codebase; they often require community consensus; unlike Informational EIPs, they are more than recommendations, and users are typically not free to ignore them. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in Ethereum development. Any meta-EIP is also considered a Process EIP. @@ -34,25 +33,23 @@ There are three kinds of EIP: The EIP repository Collaborators change the EIPs status. Please send all EIP-related email to the EIP Collaborators, which is listed under EIP Editors below. Also see EIP Editor Responsibilities & Workflow. -The EIP process begins with a new idea for Ethereum. It is highly recommended that a single EIP contain a single key proposal or new idea. Small enhancements or patches that don't affect consensus often don't need a EIP and can be injected into the Ethereum development workflow with a patch submission to the corresponding Ethereum issue tracker. The more focused the EIP, the more successful it tends to be. The EIP editor reserves the right to reject EIP proposals if they appear too unfocused or too broad. If in doubt, split your EIP into several well-focused ones. +The EIP process begins with a new idea for Ethereum. It is highly recommended that a single EIP contain a single key proposal or new idea. Small enhancements or patches often don't need an EIP and can be injected into the Ethereum development workflow with a patch submission to the corresponding Ethereum issue tracker. The more focused the EIP, the more successful it tends to be. The EIP editor reserves the right to reject EIP proposals if they appear too unfocused or too broad. If in doubt, split your EIP into several well-focused ones. -Each EIP must have a champion -- someone who writes the EIP using the style and format described below, shepherds the discussions in the appropriate forums, and attempts to build community consensus around the idea. The EIP champion (a.k.a. Author) should first attempt to ascertain whether the idea is EIP-able. Posting to the the [https://forum.ethereum.org/categories/protocol-and-client-discussion Protocol Discussion] forum or opening an [https://github.com/ethereum/EIP/issues Issue] is the best way to go about this. +Each EIP must have a champion -- someone who writes the EIP using the style and format described below, shepherds the discussions in the appropriate forums, and attempts to build community consensus around the idea. -Vetting an idea publicly before going as far as writing a EIP is meant to save the potential author time. Asking the Ethereum community first if an idea is original helps prevent too much time being spent on something that is guaranteed to be rejected based on prior discussions (searching the Internet does not always do the trick). It also helps to make sure the idea is applicable to the entire community and not just the author. Just because an idea sounds good to the author does not mean it will work for most people in most areas where Ethereum is used. +Vetting an idea publicly before going as far as writing a EIP is meant to save the potential author time. Asking the Ethereum community first if an idea is original helps prevent too much time being spent on something that is guaranteed to be rejected based on prior discussions (searching the Internet does not always do the trick). It also helps to make sure the idea is applicable to the entire community and not just the author. Just because an idea sounds good to the author does not mean it will work for most people in most areas where Ethereum is used. Examples of appropriate public forums to gauge interest around your EIP include [https://www.reddit.com/r/ethereum/ the Ethereum subreddit] and [https://gitter.im/ethereum/ one of the Ethereum Gitter chat rooms]. -Once the champion has asked the Ethereum community as to whether an idea has any chance of acceptance, a draft EIP should be presented as a Pull Request. This gives the author a chance to flesh out the draft EIP to make properly formatted, of high quality, and to address initial concerns about the proposal. +Once the champion has asked the Ethereum community whether an idea has any chance of acceptance a draft EIP should be presented as a [https://github.com/ethereum/EIPs/pulls pull request]. This gives the author a chance to coninuously edit the draft EIP for proper formatting and quality. It also allows for public comment and the author of the EIP to address concerns about the proposal. Members of the community can publically comment on the draft EIP through the pull request. If the EIP collaborators approves, the EIP editor will assign the EIP a number, label it as Standards Track, Informational, or Process, give it status "Draft", and add it to the git repository. The EIP editor will not unreasonably deny an EIP. Reasons for denying EIP status include duplication of effort, being technically unsound, not providing proper motivation or addressing backwards compatibility, or not in keeping with the Ethereum philosophy. -The EIP author may update the Draft as necessary in the git repository. Updates to drafts may also be submitted by the author as pull requests. - -Standards Track EIPs consist of three parts, a design document, implementation and finally if warranted an update to the [https://github.com/ethereum/yellowpaper formal specification]. The EIP should be reviewed and accepted before an implementation is begun, unless an implementation will aid people in studying the EIP. Standards Track EIPs must be implemented in at least two viable Ethereum clients before it can be considered Final. +Standards Track EIPs consist of three parts, a design document, implementation, and finally if warranted an update to the [https://github.com/ethereum/yellowpaper formal specification]. The EIP should be reviewed and accepted before an implementation is begun, unless an implementation will aid people in studying the EIP. Standards Track EIPs must be implemented in at least two viable Ethereum clients before it can be considered Final. EIP authors are responsible for collecting community feedback on a EIP before submitting it for review. However, wherever possible, long open-ended discussions should be avoided. Strategies to keep the discussions efficient include: having the EIP author accept private comments in the early design phases, setting up a wiki page or git repository, etc. EIP authors should use their discretion here. For a EIP to be accepted it must meet certain minimum criteria. It must be a clear and complete description of the proposed enhancement. The enhancement must represent a net improvement. The proposed implementation, if applicable, must be solid and must not complicate the protocol unduly. -Once a EIP has been accepted, the implementations must be completed. When the implementation is complete in at least two viable clients and accepted by the community, the status will be changed to "Final". An update to the [https://github.com/ethereum/yellowpaper formal specification] should accompany the "Final" status change. +Once a EIP has been accepted, the implementations must be completed. When the implementation is complete and accepted by the community, the status will be changed to "Final". A EIP can also be assigned status "Deferred". The EIP author or editor can assign the EIP this status when no progress is being made on the EIP. Once a EIP is deferred, the EIP editor can re-assign it to draft status. @@ -86,45 +83,42 @@ Each EIP should have the following parts: * Implementations -- The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. It is better to finish the specification and rationale first and reach consensus on it before writing code. +* Simple Summary -- "If you can't explain it simply, you don't understand it well enough." Provide a simplified and layman-accessible explanation of the EIP. + ==EIP Formats and Templates== -EIPs should be written in mediawiki or markdown format. Image files should be included in a subdirectory for that EIP. +EIPs should be written in [https://en.wikipedia.org/wiki/Help:Cheatsheet mediawiki] or [https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet markdown] format. Image files should be included in a subdirectory for that EIP. ==EIP Header Preamble== Each EIP must begin with an RFC 822 style header preamble. The headers must appear in the following order. Headers marked with "*" are optional and are described below. All other headers are required. -
-  EIP: 
+  EIP:  (this is determined by the EIP editor)
   Title: 
   Author: 
-* Discussions-To: 
-  Status: 
-  Type: 
+  * Discussions-To: 
+  Status: 
+  Type: 
   Created: 
-* Replaces: 
-* Superseded-By: 
-* Resolution: 
-
+ * Replaces: + * Superseded-By: + * Resolution: The Author header lists the names, and optionally the email addresses of all the authors/owners of the EIP. The format of the Author header value must be - Random J. User +Random J. User -if the email address is included, and just +if the email address is included, and - Random J. User +Random J. User -if the address is not given. - -If there are multiple authors, each should be on a separate line following RFC 2822 continuation line conventions. +if the email address is not given. Note: The Resolution header is required for Standards Track EIPs only. It contains a URL that should point to an email message or other web resource where the pronouncement about the EIP is made. While a EIP is in private discussions (usually during the initial Draft phase), a Discussions-To header will indicate the mailing list or URL where the EIP is being discussed. No Discussions-To header is necessary if the EIP is being discussed privately with the author. -The Type header specifies the type of EIP: Standards Track, Informational, or Process. +The Type header specifies the type of EIP: Standards Track, Meta, or Informational. If the track is Standards please include the subcategory (core, networking, interface, or ERC). The Created header records the date that the EIP was assigned a number. Both headers should be in yyyy-mm-dd format, e.g. 2001-08-14. @@ -146,6 +140,7 @@ If you are interested in assuming ownership of a EIP, send a message asking to t The current EIP editors are * Martin Becze + * Hudson Jameson ==EIP Editor Responsibilities & Workflow== @@ -174,3 +169,5 @@ The editors don't pass judgment on EIPs. We merely do the administrative & edito ==History== This document was derived heavily from [https://github.com/bitcoin/bips Bitcoin's BIP-0001] written by Amir Taaki which in turn was derived from [https://www.python.org/dev/peps/ Python's PEP-0001]. In many places text was simply copied and modified. Although the PEP-0001 text was written by Barry Warsaw, Jeremy Hylton, and David Goodger, they are not responsible for its use in the Ethereum Improvement Process, and should not be bothered with technical questions specific to Ethereum or the EIP. Please direct all comments to the EIP editors. + +December 7, 2016: EIP 1 has been improved and will be placed as a PR. Hudson Jameson is now the EIP editor. From aaf4d5367ebbafba19e8cd4e756d439eb6e66061 Mon Sep 17 00:00:00 2001 From: Greg Colvin Date: Thu, 29 Dec 2016 03:14:28 -0700 Subject: [PATCH 0019/1085] Create eip-184.md --- EIPS/eip-184.md | 355 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 355 insertions(+) create mode 100644 EIPS/eip-184.md diff --git a/EIPS/eip-184.md b/EIPS/eip-184.md new file mode 100644 index 0000000000000..2e84e122e41ff --- /dev/null +++ b/EIPS/eip-184.md @@ -0,0 +1,355 @@ +``` +EIP: 184 +Title: Subroutines and Static Jumps for the EVM +Status: +Type: Core +Author: Greg Colvin, Paweł Bylica, Christian Reitwiessner +Created: 2016-12-10 +Edited: 2016-29-12 +``` +## Abstract + +This EIP introduces new EVM opcodes and conditions on EVM code to support subroutines and static jumps, disallow dynamic jumps, and thereby make EVM code amenable to linear-time static analysis. This will provide for better compilation, interpretation, transpilation, and formal analysis of EVM code. + +## MOTIVATION + +All current implementations of the Ethereum Virtual Machine, including the just-in-time compilers, are much too slow. This proposal identifies a major reason for this and proposes changes to the EVM specification to address the problem. + +In particular, it imposes restrictions on current EVM code and proposes new instructions to help provide for +* better-optimized compilation to native code +* faster interpretation +* faster transpilation to eWASM +* better compilation from other languages, + including eWASM and Solidity +* better formal analysis tools + +These goals are achieved by +* disallowing dynamic jumps +* introducing subroutines - jumps with return support +* disallowing pathological control flow and uses of the stack + +We also propose to validate - in linear time - that EVM contracts correctly use subroutines, avoid misuse of the stack, and meet other safety conditions _before_ placing them on the blockchain. Validated code precludes most runtime exceptions and the need to test for them. And well-behaved control flow and use of the stack makes life easier for interpreters, compilers, formal analysis, and other tools. + +## THE PROBLEM + +Currently the EVM supports dynamic jumps, where the address to jump to is an argument on the stack. These dynamic jumps obscure the structure of the code and thus mostly inhibit control- and data-flow analysis. This puts the quality and speed of optimized compilation fundamentally at odds. Further, since every jump can potentially be to any jump destination in the code, the number of possible paths through the code goes up as the product of the number of jumps by the number of destinations, as does the time complexity of static analysis. But absent dynamic jumps code can be statically analyzed in linear time. + +Static analysis includes validation, and much of optimization, compilation, transpilation, and formal analysis; every part of the tool chain benefits when linear-time analysis is available. In particular, faster control-flow analysis means faster compilation of EVM code to native code, and better data-flow analysis can help the compiler and the interpreter better track the size of the values on the stack and use native 64- and 32-bit operations when possible. Also, conditions which are checked at validation time don’t have to be checked repeatedly at runtime. + +Note that analyses of a contract’s bytecode before execution - such as optimizations performed before interpretation, JIT compilation, and on-the-fly machine code generation - must be efficient and linear-time. Otherwise, specially crafted contracts can be used as attack vectors against clients that use static analysis of EVM code before the creation or execution of contracts. + +## PROPOSAL + +We propose to deprecate two existing instructions - `JUMP` and `JUMPI`. They take their argument on the stack, which means that unless the value is constant they can jump to any `JUMPDEST`. (In simple cases like `PUSH 0 JUMP` the value on the stack can be known to be constant, but in general it's difficult.) We must nonetheless continue to support them in old code. + +Having deprecated `JUMP` and `JUMPI`, we propose new instructions to support their legitimate uses. + +### Preliminaries + +These forms +* `INSTRUCTION x,` +* `INSTRUCTION x, y` +* `INSTRUCTION n, x ...` + +name instructions with one, two, and two or more arguments, respectively. An instruction is represented in the bytecode as a single-byte opcode. The arguments are laid out as immediate data bytes following the opcode. The size and encoding of immediate data fields is open to change. In particular, easily-parsed variable-length encodings might prove useful for bytecode offsets - which are in practice small but in principle can be large. + +### Primitives + +The two most important uses of `JUMP` and `JUMPI` are static jumps and return jumps. Conditional and unconditional static jumps are the mainstay of control flow. Return jumps are implemented as a dynamic jump to a return address pushed on the stack. With the combination of a static jump and a dynamic return jump you can - and Solidity does - implement subroutines. The problem is that static analysis cannot tell the one place the return jump is going, so it must analyze every possibility. + +Static jumps are provided by +* `JUMPTO jump_target` +* `JUMPIF jump_target` +which are the same as `JUMP` and `JUMPI` except that they jump to an immediate `jump_target`, given as four immediate bytes, rather than an address on the stack. + +To support subroutines, `BEGINSUB`, `JUMPSUB`, and `RETURNSUB` are provided. Brief descriptions follow, and full semantics are given below. + +* `BEGINSUB n_args, n_results` +marks the **single** entry to a subroutine. `n_args` items are taken off of the stack at entry to, and `n_results` items are placed on the stack at return from the subroutine. `n_args` and `n_results` are given as one immediate byte each. The bytecode for a subroutine ends at the next `BEGINSUB` instruction (or `BEGINDATA`, below) or at the end of the bytecode. + +* `JUMPSUB jump_target` +jumps to an immediate subroutine address, given as four immediate bytes. + +* `RETURNSUB` +returns from the current subroutine to the instruction following the JUMPSUB that entered it. + +These five simple instructions form the primitives of the proposal. + +### Data + +In order to validate subroutines, EVM bytecode must be sequentially scanned matching jumps to their destinations. Since creation code has to contain the runtime code as data, that code might not correctly validate in the creation context and also does not have to be validated prior to the execution of the creation code. Because of that, there needs to be a way to place data into the bytecode that will be skipped over and not validated. Such data will prove useful for other purposes as well. + +* `BEGINDATA` +specifies that all of the following bytes to the end of the bytecode are data, and not reachable code. + +### Indirect Jumps + +The primitive operations provide for static jumps. Dynamic jumps are also used for O(1) indirection: an address to jump to is selected to push on the stack and be jumped to. So we also propose two more instructions to provide for constrained indirection. We support these with vectors of `JUMPDEST` or `BEGINSUB` offsets stored inline, which can be selected with an index on the stack. That constrains validation to a specified subset of all possible destinations. The danger of quadratic blow up is avoided because it takes as much space to store the jump vectors as it does to code the worst case exploit. + +Dynamic jumps to a `JUMPDEST` are used to implement O(1) jumptables, which are useful for dense switch statements, and are implemented as instructions similar to this one on most CPUs. +* `JUMPV n, jumpdest ...` +jumps to one of a vector of `n` `JUMPDEST` offsets via a zero-based index on the stack. The vector is stored inline in the bytecode. If the index is greater than or equal to `n - 1` the last (default) offset is used. `n` is given as four immediate bytes, all `JUMPDEST` offsets as four immediate bytes each. + +Dynamic jumps to a `BEGINSUB` are used to implement O(1) virtual functions and callbacks, which take just two pointer dereferences in C. +* `JUMPSUBV n, beginsub ...` +jumps to one of a vector of `n` `BEGINSUB` offsets via a zero-based index on the stack. The vector is stored inline in the bytecode, MSB-first. If the index is greater than or equal to `n - 1` the last (default) offset is used. `n` is given as four immediate bytes, the `n` offsets as four immediate bytes each. + +`JUMPV` and `JUMPSUBV` are not strictly necessary. They provide O(1) operations that can be replaced by O(n) or O(log n) EVM code using static jumps, but that code will be slower, larger and use more gas for things that can and should be fast, small, and cheap, and that are directly supported in WASM with br_table and call_indirect. + +## SEMANTICS + +Jumps to and returns from subroutines are described here in terms of +* the EVM data stack, usually just called “the stack”, +* a return stack of `JUMPSUB` and `JUMPSUBV` offsets, and +* a virtual stack of frame pointers (not needed at runtime). + +We will adopt the following conventions to describe the machine state: +* The _program counter_ `PC` is (as usual) the byte offset of the currently executing instruction. +* The _stack pointer_ `SP` corresponds to the number of items on the stack - the _stack size_. As an offset it addresses the current top of the stack of data values, where new items are pushed. +* The virtual _frame pointer_ `FP` is set to `SP - n_args` at entry to the currently executing subroutine. +* The _stack items_ between the frame pointer and the current stack pointer are called the _frame_. +* The current number of items in the frame, `SP - FP`, is the _frame size_. + +Placing the frame pointer at the beginning of the arguments rather than the end is unconventional, but better fits our stack semantics and simplifies the remainder of the proposal. + +Note that frame pointers and the frame pointer stack, being virtual, are only needed for the following descriptions of subroutine semantics, not for their actual implementation. Also, the return stack is internal to the subroutine mechanism, and not directly accessible to the program. + +The first instruction of an array of EVM bytecode begins execution of a _main_ routine with no arguments, `SP` and `FP` set to 0, and with one value on the return stack - `code size - 1`. (Executing the virtual byte of 0 after this offset causes an EVM to stop. Thus executing a `RETURNSUB` with no prior `JUMPSUB` or `JUMBSUBV` - that is, in the _main_ routine - executes a `STOP`.) + +Execution of a subroutine begins with `JUMPSUB` or `JUMPSUBV`, which +* push `PC` on the return stack, +* push `FP` on the virtual frame stack, +thus suspending execution of the current subroutine, and +* set `FP` to `SP - n_args`, and +* set `PC` to the specified `BEGINSUB` address, +thus beginning execution of the new subroutine. +(The _main_ routine is not addressable by `JUMPSUB` instructions.) + +Execution of a subroutine is suspended during and resumed after execution of nested subroutines, and ends upon encountering a `RETURNSUB`, which +* sets `FP` to the top of the virtual frame stack and pops the stack, and +* sets `PC` to top of the return stack and pops the stack +* advances `PC` to the next instruction +thus resuming execution of the enclosing subroutine or _main_ program. +A `STOP or `RETURN` also ends the execution of a subroutine. + +## VALIDITY + +We would like to consider EVM code valid if and only if no execution of the program can lead to an exceptional halting state. But we must and will validate code in linear time. So our validation does not consider the code’s data and computations, only its control flow and stack use. This means we will reject programs with invalid code paths, even if those paths cannot be executed at runtime. Most conditions can be validated, and will not need to be checked at runtime; the exceptions are sufficient gas and sufficient stack. So some false negatives and runtime checks are the price we pay for linear time validation. + +_Execution_ is as defined in the Yellow Paper - a sequence of changes in the EVM state. The conditions on valid code are preserved by state changes. At runtime, if execution of an instruction would violate a condition the execution is in an exceptional halting state. The yellow paper defines five such states. +>1 Insufficient gas + +>2 More than 1024 stack items + +>3 Insufficient stack items + +>4 Invalid jump destination + +>5 Invalid instruction + +We propose to expand and extend the Yellow Paper conditions to handle the new instructions we propose. + +To handle the return stack we expand the conditions on stack size: +>2a The size of the data stack does not exceed 1024. + +>2b The size of the return stack does not exceed 1024. + +Given our more detailed description of the data stack we restate condition 3 - stack underflow - as +>3 `SP` must be greater than or equal to `FP` + +Since the various `DUP` and `SWAP` operations are formalized as taking items off the stack and putting them back on, this prevents `DUP` and `SWAP` from accessing data below the frame pointer, since taking too many items off of the stack would mean that `SP` is less than `FP`. + +To handle the new jump instructions and subroutine boundaries we expand the conditions on jumps and jump destinations. +>4a `JUMPTO`, `JUMPIF`, and `JUMPV` address only `JUMPDEST` instructions. + +>4b `JUMPSUB` and `JUMPSUBV` address only `BEGINSUB` instructions. + +>4c `JUMP` instructions do not address instructions outside of the subroutine they occur in. + +We have two new conditions on execution to ensure consistent use of the stack by subroutines: +>6 For `JUMPSUB` and `JUMPSUBV` the frame size is at least the `n_args` of the `BEGINSUB`(s) to jump to. + +>7 For `RETURNSUB` the frame size is equal to the `n_results` of the enclosing `BEGINSUB`. + +Finally, we have one condition that prevents pathological uses of the stack: +>8 For every instruction in the code the frame size is constant. + +In practice, we must test at runtime for conditions 1 and 2 - sufficient gas and sufficient stack. We don’t know how much gas there will be, we don’t know how deep a recursion may go, and analysis of stack depth even for non-recursive programs is non-trivial. + +All of the remaining conditions we validate statically. + +## VALIDATION + +Validation comprises two tasks: +* Checking that jump destinations are correct and instructions valid. +* Checking that subroutines satisfy the conditions on control flow and stack use. + +We sketch out these two validation functions in pseudo-C below. To simplify the presentation only the five primitives are handled (`JUMPV` and `JUMPSUBV` would just add more complexity to loop over their vectors), we assume helper functions for extracting instruction arguments from immediate data and managing the stack pointer and program counter, and some optimizations are forgone. + +### Validating jumps + +Validating that jumps are to valid addresses takes two sequential passes over the bytecode - one to build sets of jump destinations and subroutine entry points, another to check that addresses jumped to are in the appropriate sets. +``` + bytecode[code_size] // contains EVM bytecode to validate + is_sub[code_size] // is there a BEGINSUB at PC? + is_dest[code_size] // is there a JUMPDEST at PC? + sub_for_pc[code_size] // which BEGINSUB is PC in? + + bool validate_jumps(PC) + { + current_sub = PC + + // build sets of BEGINSUBs and JUMPDESTs + for (PC = 0; instruction = bytecode[PC]; PC = advance_pc(PC)) + { + if instruction is invalid + return false + if instruction is BEGINDATA + return true + if instruction is BEGINSUB + is_sub[PC] = true + current_sub = PC + sub_for_pc[PC] = current_sub + if instruction is JUMPDEST + is_dest[PC] = true + sub_for_pc[PC] = current_sub + } + + // check that targets are in subroutine + for (PC = 0; instruction = bytecode[PC]; PC = advance_pc(PC)) + { + if instruction is BEGINDATA + break; + if instruction is BEGINSUB + current_sub = PC + if instruction is JUMPSUB + if is_sub[jump_target(PC)] is false + return false + if instruction is JUMPTO or JUMPIF + if is_dest[jump_target(PC)] is false + return false + if sub_for_pc[PC] is not current_sub + return false + } + return true + } +``` +Note that code like this is already run by EVMs to check dynamic jumps, including building the jump destination set every time a contract is run, and doing a lookup in the jump destination set before every jump. + +### Validating subroutines + +This function can be seen as a symbolic execution of a subroutine in the EVM code, where only the effect of the instructions on the state being validated is computed. Thus the structure of this function is very similar to an EVM interpreter. This function can also be seen as an acyclic traversal of the directed graph formed by taking instructions as vertexes and sequential and branching connections as edges, checking conditions along the way. The traversal is accomplished via recursion, and cycles are broken by returning when a vertex which has already been visited is reached. The time complexity of this traversal is O(n-vertices + n-edges) + +The basic approach is to call `validate_subroutine(i, 0, 0)`, for _i_ equal to the first instruction in the EVM code through each `BEGINDATA` offset. `validate_subroutine()` traverses instructions sequentially, recursing when `JUMP` and `JUMPI` instructions are encountered. When a destination is reached that has been visited before it returns, thus breaking cycles. It returns true if the subroutine is valid, false otherwise. + +``` + bytecode[code_size] // contains EVM bytecode to validate + frame_size[code_size ] // is filled with -1 + + // we validate each subroutine individually, as if at top level + // * PC is the offset in the code to start validating at + // * return_pc is the top PC on return stack that RETURNSUB returns to + // * at top level FP = 0, so SP is both the frame size and the stack size + validate_subroutine(PC, return_pc, SP) + { + // traverse code sequentially, recurse for jumps + while true + { + instruction = bytecode[PC] + + // if frame size set we have been here before + if frame_size[PC] >= 0 + { + // check for constant frame size + if instruction is JUMPDEST + if SP != frame_size[PC] + return false + + // return to break cycle + return true + } + frame_size[PC] = SP + + // effect of instruction on stack + n_removed = removed_items(instructions) + n_added = added_items(instruction) + + // check for stack underflow + if SP < n_removed + return false + + // net effect of removing and adding stack items + SP -= n_removed + SP += n_added + + // check for stack overflow + if SP > 1024 + return false + + if instruction is STOP, RETURN, or SUICIDE + return true + + // violates single entry + if instruction is BEGINSUB + return false + + // return to top or from recursion to JUMPSUB + if instruction is RETURNSUB + break; + + if instruction is JUMPSUB + { + // check for enough arguments + sub_pc = jump_target(PC) + if SP < n_args(sub_pc) + return false + return true + } + + // reset PC to destination of jump + if instruction is JUMPTO + { + PC = jump_target(PC) + continue + } + + // recurse to jump to code to validate + if instruction is JUMPIF + { + if not validate_subroutine(jump_target(PC), return_pc, SP) + return false + } + + // advance PC according to instruction + PC = advance_pc(PC) + } + + // check for right number of results + if SP != n_results(return_pc) + return false + return true + } +``` + +### COSTS & CODES + +All of the instructions are O(1) with a small constant, requiring just a few machine operations each, whereas a `JUMP` or `JUMPI` must do an O(log n) binary search of an array of `JUMPDEST` offsets before every jump. With the cost of `JUMPI` being _high_ and the cost of `JUMP` being _mid_, we suggest the cost of `JUMPV` and `JUMPSUBV` should be _mid_, `JUMPSUB` and `JUMPIF` should be _low_, and`JUMPTO` should be _verylow_. Measurement will tell. + +We tentatively suggest the following opcodes: +``` +0x4C JUMPTO 0x5C BEGINSUB +0x4D JUMPIF 0x5D BEGINDATA +0X4E JUMPSUB 0x5E RETURNSUB +0x4F JUMPSUBV +``` + +### GETTING THERE FROM HERE + +These changes would need to be implemented in phases at decent intervals: +>1 If this EIP is accepted, invalid code should be deprecated. Tools should stop generating invalid code, users should stop writing it, and clients should warn about loading it. + +>2 A later hard fork would require clients to place only valid code on the block chain. Note that despite the fork old EVM code will still need to be supported indefinitely. + +If desired, the period of deprecation can be extended indefinitely by continuing to accept code not versioned as new - but without validation. Since we must continue to run old code this is not technically difficult. + +Implementation of this proposal need not be difficult, At the least, interpreters can simply be extended with the new opcodes and run unchanged otherwise. The new opcodes require only a stack for the return offsets and the few pushes, pops, and assignments described above. JIT code can use native calls. Further optimizations include minimizing runtime checks for exceptions and taking advantage of validated code wherever possible. From 09f47e65b1f44dc5df248422cc11a10300c586ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Wed, 25 Jan 2017 18:29:44 +0100 Subject: [PATCH 0020/1085] EIP5: include DELEGATECALL --- EIPS/eip-5.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-5.md b/EIPS/eip-5.md index 243d77ca3a7ca..02408e2fc7a27 100644 --- a/EIPS/eip-5.md +++ b/EIPS/eip-5.md @@ -21,10 +21,10 @@ the time the `CALL` returns. ### Specification -The gas and memory semantics for `CALL` and `CALLCODE` (and `DELEGATE_CALL`, if adopted, see EIP-4) +The gas and memory semantics for `CALL`, `CALLCODE` and `DELEGATECALL` (called later as `CALL*`) are changed in the following way (`CREATE` does not write to memory and is thus unaffected): -Suppose the arguments to `CALL` / `CALLCODE` are `gas, address, value, input_start, input_size, output_start, output_size)`, +Suppose the arguments to `CALL*` are `gas, address, value, input_start, input_size, output_start, output_size`, then, at the beginning of the opcode, gas for growing memory is only charged for `input_start + input_size`, but not for `output_start + output_size`. From 6967a02df07ce0b6b1e0e45de3173812d03c48fb Mon Sep 17 00:00:00 2001 From: Souptacular Date: Wed, 1 Feb 2017 15:50:52 -0800 Subject: [PATCH 0021/1085] Add .md version --- EIPS/eip-1.md | 249 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 EIPS/eip-1.md diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md new file mode 100644 index 0000000000000..541bcde04f9d1 --- /dev/null +++ b/EIPS/eip-1.md @@ -0,0 +1,249 @@ + EIP: 1 + Title: EIP Purpose and Guidelines + Status: Draft + Type: Meta + Author: Martin Becze , Hudson Jameson + Created: 2015-10-27, 2017-02-xx + +What is a EIP? +-------------- + +EIP stands for Ethereum Improvement Proposal. A EIP is a design document providing information to the Ethereum community, or describing a new feature for Ethereum or its processes or environment. The EIP shousld provide a concise technical specification of the feature and a rationale for the feature. The EIP author is responsible for building consensus within the community and documenting dissenting opinions. + +EIP Rational +------------ + +We intend EIPs to be the primary mechanisms for proposing new features, for collecting community input on an issue, and for documenting the design decisions that have gone into Ethereum. Because the EIPs are maintained as text files in a versioned repository, their revision history is the historical record of the feature proposal. + +For Ethereum implementers, EIPs are a convenient way to track the progress of their implementation. Ideally each implementation maintainer would list the EIPs that they have implemented. This will give end users a convenient way to know the current status of a given implementation or library. + +EIP Types +--------- + +There are three types of EIP: + +- A **Standard Track EIP** describes any change that affects most or all Ethereum implementations, such as a change to the the network protocol, a change in block or transaction validity rules, proposed application standards/conventions, or any change or addition that affects the interoperability of applications using Ethereum. Furthermore Standard EIPs can be broken down into the following categories. + - **Core** - improvements requiring a consensus fork (e.g. [EIP5], [EIP101]), as well as changes that are not necessarily consensus critical but may be relevant to “core dev” discussions (for example, [EIP90], and the miner/node strategy changes 2, 3, and 4 of [EIP86]). + - **Networking** - includes improvements around [devp2p] ([EIP8]) and [Light Ethereum Subprotocol], as well as proposed improvements to network protocol specifications of [whisper] and [swarm]. + - **Interface** - includes improvements around client [API/RPC] specifications and standards, and also certain language-level standards like method names ([EIP59], [EIP6]) and [contract ABIs]. The label “interface” aligns with the [interfaces repo] and discussion should primarily occur in that repository before an EIP is submitted to the EIPs repository. + - **ERC** - application-level standards and conventions, including contract standards such as token standards ([ERC20]), name registries ([ERC26], [ERC137]), URI schemes ([ERC67]), library/package formats ([EIP82]), and wallet formats ([EIP75], [EIP85]). + +- An **Informational EIP** describes a Ethereum design issue, or provides general guidelines or information to the Ethereum community, but does not propose a new feature. Informational EIPs do not necessarily represent Ethereum community consensus or a recommendation, so users and implementors are free to ignore Informational EIPs or follow their advice. +- A **Meta EIP** describes a process surrounding Ethereum or proposes a change to (or an event in) a process. Process EIPs are like Standards Track EIPs but apply to areas other than the Ethereum protocol itself. They may propose an implementation, but not to Ethereum's codebase; they often require community consensus; unlike Informational EIPs, they are more than recommendations, and users are typically not free to ignore them. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in Ethereum development. Any meta-EIP is also considered a Process EIP. + +EIP Work Flow +------------- + +The EIP repository Collaborators change the EIPs status. Please send all EIP-related email to the EIP Collaborators, which is listed under EIP Editors below. Also see EIP Editor Responsibilities & Workflow. + +The EIP process begins with a new idea for Ethereum. It is highly recommended that a single EIP contain a single key proposal or new idea. The more focused the EIP, the more successful it tends to be. A change to one client doesn't require an EIP; a change that affects multiple clients, or defines a standard for multiple apps to use, does. The EIP editor reserves the right to reject EIP proposals if they appear too unfocused or too broad. If in doubt, split your EIP into several well-focused ones. + +Each EIP must have a champion -- someone who writes the EIP using the style and format described below, shepherds the discussions in the appropriate forums, and attempts to build community consensus around the idea. + +Vetting an idea publicly before going as far as writing a EIP is meant to save the potential author time. Asking the Ethereum community first if an idea is original helps prevent too much time being spent on something that is guaranteed to be rejected based on prior discussions (searching the Internet does not always do the trick). It also helps to make sure the idea is applicable to the entire community and not just the author. Just because an idea sounds good to the author does not mean it will work for most people in most areas where Ethereum is used. Examples of appropriate public forums to gauge interest around your EIP include [the Ethereum subreddit], [the Issues section of this repository], and [one of the Ethereum Gitter chat rooms]. In particular, [the Issues section of this repository] is an excellent place to discuss your proposal with the community and start creating more formalized language around your EIP. + +Once the champion has asked the Ethereum community whether an idea has any chance of acceptance a draft EIP should be presented as a [pull request]. This gives the author a chance to coninuously edit the draft EIP for proper formatting and quality. This also allows for further public comment and the author of the EIP to address concerns about the proposal. + +If the EIP collaborators approves, the EIP editor will assign the EIP a number (generally the issue or PR number related to the EIP), label it as Standards Track, Informational, or Meta, give it status “Draft”, and add it to the git repository. The EIP editor will not unreasonably deny an EIP. Reasons for denying EIP status include duplication of effort, being technically unsound, not providing proper motivation or addressing backwards compatibility, or not in keeping with the Ethereum philosophy. + +Standards Track EIPs consist of three parts, a design document, implementation, and finally if warranted an update to the [formal specification]. The EIP should be reviewed and accepted before an implementation is begun, unless an implementation will aid people in studying the EIP. Standards Track EIPs must be implemented in at least three viable Ethereum clients before it can be considered Final. + +For an EIP to be accepted it must meet certain minimum criteria. It must be a clear and complete description of the proposed enhancement. The enhancement must represent a net improvement. The proposed implementation, if applicable, must be solid and must not complicate the protocol unduly. + +Once a EIP has been accepted, the implementations must be completed. When the implementation is complete and accepted by the community, the status will be changed to “Final”. + +A EIP can also be assigned status “Deferred”. The EIP author or editor can assign the EIP this status when no progress is being made on the EIP. Once a EIP is deferred, the EIP editor can re-assign it to draft status. + +A EIP can also be “Rejected”. Perhaps after all is said and done it was not a good idea. It is still important to have a record of this fact. + +EIPs can also be superseded by a different EIP, rendering the original obsolete. + +The possible paths of the status of EIPs are as follows: + + + +Some Informational and Process EIPs may also have a status of “Active” if they are never meant to be completed. E.g. EIP 1 (this EIP). + +What belongs in a successful EIP? +--------------------------------- + +Each EIP should have the following parts: + +- Preamble -- RFC 822 style headers containing metadata about the EIP, including the EIP number, a short descriptive title (limited to a maximum of 44 characters), the names, and optionally the contact info for each author, etc. + + + +- Simple Summary -- “If you can’t explain it simply, you don’t understand it well enough.” Provide a simplified and layman-accessible explanation of the EIP. + + + +- Abstract -- a short (~200 word) description of the technical issue being addressed. + + + +- Motivation -- The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright. + + + +- Specification -- The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (cpp-ethereum, go-ethereum, parity, ethereumJ, ethereumjs-lib, …). + + + +- Rationale -- The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion. + + + +- Backwards Compatibility -- All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright. + + + +- Backwards Compatibility -- All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright. + + + +- Test Cases -- Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable. + + + +- Implementations -- The implementations must be completed before any EIP is given status “Final”, but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of “rough consensus and running code” is still useful when it comes to resolving many discussions of API details. + +EIP Formats and Templates +------------------------- + +EIPs should be written in [markdown] format. Image files should be included in a subdirectory for that EIP. + +EIP Header Preamble +------------------- + +Each EIP must begin with an RFC 822 style header preamble. The headers must appear in the following order. Headers marked with "\*" are optional and are described below. All other headers are required. + +` EIP: ` (this is determined by the EIP editor) + +` Title: ` + +` Author: ` + +` * Discussions-To: ` + +` Status: ` + +` Type: ` + +` Created: ` + +` * Replaces: ` + +` * Superseded-By: ` + +` * Resolution: ` + +The Author header lists the names, and optionally the email addresses of all the authors/owners of the EIP. The format of the Author header value must be + +Random J. User <address@dom.ain> + +if the email address is included, and + +Random J. User + +if the email address is not given. + +Note: The Resolution header is required for Standards Track EIPs only. It contains a URL that should point to an email message or other web resource where the pronouncement about the EIP is made. + +While a EIP is in private discussions (usually during the initial Draft phase), a Discussions-To header will indicate the mailing list or URL where the EIP is being discussed. No Discussions-To header is necessary if the EIP is being discussed privately with the author. + +The Type header specifies the type of EIP: Standards Track, Meta, or Informational. If the track is Standards please include the subcategory (core, networking, interface, or ERC). + +The Created header records the date that the EIP was assigned a number. Both headers should be in yyyy-mm-dd format, e.g. 2001-08-14. + +EIPs may have a Requires header, indicating the EIP numbers that this EIP depends on. + +EIPs may also have a Superseded-By header indicating that a EIP has been rendered obsolete by a later document; the value is the number of the EIP that replaces the current document. The newer EIP must have a Replaces header containing the number of the EIP that it rendered obsolete. + +Auxiliary Files +--------------- + +EIPs may include auxiliary files such as diagrams. Such files must be named EIP-XXXX-Y.ext, where “XXXX” is the EIP number, “Y” is a serial number (starting at 1), and “ext” is replaced by the actual file extension (e.g. “png”). + +Transferring EIP Ownership +-------------------------- + +It occasionally becomes necessary to transfer ownership of EIPs to a new champion. In general, we\'d like to retain the original author as a co-author of the transferred EIP, but that\'s really up to the original author. A good reason to transfer ownership is because the original author no longer has the time or interest in updating it or following through with the EIP process, or has fallen off the face of the 'net (i.e. is unreachable or not responding to email). A bad reason to transfer ownership is because you don't agree with the direction of the EIP. We try to build consensus around a EIP, but if that\'s not possible, you can always submit a competing EIP. + +If you are interested in assuming ownership of a EIP, send a message asking to take over, addressed to both the original author and the EIP editor. If the original author doesn\'t respond to email in a timely manner, the EIP editor will make a unilateral decision (it\'s not like such decisions can\'t be reversed :). + +EIP Editors +----------- + +The current EIP editors are + +` * Martin Becze` +` * Hudson Jameson` + +EIP Editor Responsibilities and Workflow +-------------------------------------- + +For each new EIP that comes in, an editor does the following: + +- Read the EIP to check if it is ready: sound and complete. The ideas must make technical sense, even if they don\'t seem likely to be accepted. +- The title should accurately describe the content. +- Edit the EIP for language (spelling, grammar, sentence structure, etc.), markup (for reST EWIPs), code style + +If the EIP isn\'t ready, the editor will send it back to the author for revision, with specific instructions. + +Once the EIP is ready for the repository, the EIP editor will: + +- Assign a EIP number (almost always just the next available number) + + + +- Accept the corresponding pull request + + + +- List the EIP in [README.md] + + + +- Send email back to the EIP author with next step. + +Many EIPs are written and maintained by developers with write access to the Ethereum codebase. The EIP editors monitor EIP changes, and correct any structure, grammar, spelling, or markup mistakes we see. + +The editors don\'t pass judgment on EIPs. We merely do the administrative & editorial part. Except for times like this, there\'s relatively low volume. + +History +------- + +This document was derived heavily from [Bitcoin\'s BIP-0001] written by Amir Taaki which in turn was derived from [Python\'s PEP-0001]. In many places text was simply copied and modified. Although the PEP-0001 text was written by Barry Warsaw, Jeremy Hylton, and David Goodger, they are not responsible for its use in the Ethereum Improvement Process, and should not be bothered with technical questions specific to Ethereum or the EIP. Please direct all comments to the EIP editors. + +December 7, 2016: EIP 1 has been improved and will be placed as a PR. Hudson Jameson is now the EIP editor. + + [EIP5]: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-5.md + [EIP101]: https://github.com/ethereum/EIPs/issues/28 + [EIP90]: https://github.com/ethereum/EIPs/issues/90 + [EIP86]: https://github.com/ethereum/EIPs/issues/86#issue-145324865 + [devp2p]: https://github.com/ethereum/wiki/wiki/%C3%90%CE%9EVp2p-Wire-Protocol + [EIP8]: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-8.md + [Light Ethereum Subprotocol]: https://github.com/ethereum/wiki/wiki/Light-client-protocol + [whisper]: https://gist.github.com/gluk256/4654922ca45eb9d0846d941d7ca326f4 + [swarm]: https://github.com/ethereum/go-ethereum/pull/2959 + [API/RPC]: https://github.com/ethereum/wiki/wiki/JSON-RPC + [EIP59]: https://github.com/ethereum/EIPs/issues/59 + [EIP6]: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-6.md + [contract ABIs]: https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI + [interfaces repo]: https://github.com/ethereum/interfaces + [ERC20]: https://github.com/ethereum/EIPs/issues/20 + [ERC26]: https://github.com/ethereum/EIPs/issues/26 + [ERC137]: https://github.com/ethereum/EIPs/issues/137 + [ERC67]: https://github.com/ethereum/EIPs/issues/67 + [EIP82]: https://github.com/ethereum/EIPs/issues/82 + [EIP75]: https://github.com/ethereum/EIPs/issues/75 + [EIP85]: https://github.com/ethereum/EIPs/issues/85 + [the Ethereum subreddit]: https://www.reddit.com/r/ethereum/ + [one of the Ethereum Gitter chat rooms]: https://gitter.im/ethereum/ + [pull request]: https://github.com/ethereum/EIPs/pulls + [formal specification]: https://github.com/ethereum/yellowpaper + [the Issues section of this repository]: https://github.com/ethereum/EIPs/issues + [markdown]: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet + [README.md]: README.md "wikilink" + [Bitcoin's BIP-0001]: https://github.com/bitcoin/bips + [Python's PEP-0001]: https://www.python.org/dev/peps/ \ No newline at end of file From 0d06b5e7390cccab722435eb834a159d82f3e715 Mon Sep 17 00:00:00 2001 From: Souptacular Date: Wed, 1 Feb 2017 16:14:53 -0800 Subject: [PATCH 0022/1085] Removed MediaWIki version of EIP one. Updated MD EIP 1. Added updated graph. --- EIPS/eip-1.md | 22 +++-- EIPS/eip-1.mediawiki | 173 ------------------------------------- EIPS/eip-1/old_process.png | Bin 0 -> 20813 bytes EIPS/eip-1/process.png | Bin 20813 -> 27422 bytes 4 files changed, 15 insertions(+), 180 deletions(-) delete mode 100644 EIPS/eip-1.mediawiki create mode 100644 EIPS/eip-1/old_process.png diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index 541bcde04f9d1..4c30291a4c51c 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -176,8 +176,15 @@ EIP Editors The current EIP editors are -` * Martin Becze` -` * Hudson Jameson` +` * Casey Detrio (@cdetrio)` +` * Fabian Vogelsteller (@frozeman)` +` * Gavin Wood (@gavofyork)` +` * Hudson Jameson (@Souptacular)` +` * Jeffrey Wilcke (@obscuren)` +` * Martin Becze (@wanderer)` +` * Nick Johnson (@arachnid)` +` * Roman Mandeleil (@romanman)` +` * Vitalik Buterin (@vbuterin)` EIP Editor Responsibilities and Workflow -------------------------------------- @@ -186,13 +193,13 @@ For each new EIP that comes in, an editor does the following: - Read the EIP to check if it is ready: sound and complete. The ideas must make technical sense, even if they don\'t seem likely to be accepted. - The title should accurately describe the content. -- Edit the EIP for language (spelling, grammar, sentence structure, etc.), markup (for reST EWIPs), code style +- Edit the EIP for language (spelling, grammar, sentence structure, etc.), markup (Github flavored Markdown), code style If the EIP isn\'t ready, the editor will send it back to the author for revision, with specific instructions. Once the EIP is ready for the repository, the EIP editor will: -- Assign a EIP number (almost always just the next available number) +- Assign a EIP number (generally the PR number or, if preferred by the author, the Issue # if ther was discussion in the Issues section of this repository about this EIP) @@ -204,18 +211,19 @@ Once the EIP is ready for the repository, the EIP editor will: -- Send email back to the EIP author with next step. +- Send a message back to the EIP author with next step. Many EIPs are written and maintained by developers with write access to the Ethereum codebase. The EIP editors monitor EIP changes, and correct any structure, grammar, spelling, or markup mistakes we see. -The editors don\'t pass judgment on EIPs. We merely do the administrative & editorial part. Except for times like this, there\'s relatively low volume. +The editors don\'t pass judgment on EIPs. We merely do the administrative & editorial part. History ------- This document was derived heavily from [Bitcoin\'s BIP-0001] written by Amir Taaki which in turn was derived from [Python\'s PEP-0001]. In many places text was simply copied and modified. Although the PEP-0001 text was written by Barry Warsaw, Jeremy Hylton, and David Goodger, they are not responsible for its use in the Ethereum Improvement Process, and should not be bothered with technical questions specific to Ethereum or the EIP. Please direct all comments to the EIP editors. -December 7, 2016: EIP 1 has been improved and will be placed as a PR. Hudson Jameson is now the EIP editor. +December 7, 2016: EIP 1 has been improved and will be placed as a PR. +February XX, 2016: EIP 1 has added editors, made draft improvements to process, and has merged with Master stream. [EIP5]: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-5.md [EIP101]: https://github.com/ethereum/EIPs/issues/28 diff --git a/EIPS/eip-1.mediawiki b/EIPS/eip-1.mediawiki deleted file mode 100644 index 7f31439716530..0000000000000 --- a/EIPS/eip-1.mediawiki +++ /dev/null @@ -1,173 +0,0 @@ -
-  EIP: 1
-  Title: EIP Purpose and Guidelines
-  Status: Draft
-  Type: Meta
-  Author: Martin Becze , Hudson Jameson 
-  Created: 2015-10-27, 2016-12-07
-
- -==What is a EIP?== - -EIP stands for Ethereum Improvement Proposal. A EIP is a design document providing information to the Ethereum community, or describing a new feature for Ethereum or its processes or environment. The EIP should provide a concise technical specification of the feature and a rationale for the feature. The EIP author is responsible for building consensus within the community and documenting dissenting opinions. - -==EIP Rational== - -We intend EIPs to be the primary mechanisms for proposing new features, for collecting community input on an issue, and for documenting the design decisions that have gone into Ethereum. Because the EIPs are maintained as text files in a versioned repository, their revision history is the historical record of the feature proposal. - -For Ethereum implementers, EIPs are a convenient way to track the progress of their implementation. Ideally each implementation maintainer would list the EIPs that they have implemented. This will give end users a convenient way to know the current status of a given implementation or library. - -==EIP Types== - -There are three types of EIP: - -* A Standard Track EIP describes any change that affects most or all Ethereum implementations, such as a change to the the network protocol, a change in block or transaction validity rules, proposed application standards/conventions, or any change or addition that affects the interoperability of applications using Ethereum. Furthermore Standard EIPs can be broken down into the following categories. -** Core - improvements requiring a consensus fork (e.g. [https://github.com/ethereum/EIPs/blob/master/EIPS/eip-5.md EIP5], [https://github.com/ethereum/EIPs/issues/28 EIP101]), as well as changes that are not necessarily consensus critical but may be relevant to “core dev” discussions (for example, [https://github.com/ethereum/EIPs/issues/90 EIP90], and the miner/node strategy changes 2, 3, and 4 of [https://github.com/ethereum/EIPs/issues/86#issue-145324865 EIP86]). -** Networking - includes improvements around [https://github.com/ethereum/wiki/wiki/%C3%90%CE%9EVp2p-Wire-Protocol devp2p] ([https://github.com/ethereum/EIPs/blob/master/EIPS/eip-8.md EIP8]) and [https://github.com/ethereum/wiki/wiki/Light-client-protocol Light Ethereum Subprotocol], as well as proposed improvements to network protocol specifications of [https://gist.github.com/gluk256/4654922ca45eb9d0846d941d7ca326f4 whisper] and [https://github.com/ethereum/go-ethereum/pull/2959 swarm]. -** Interface - includes improvements around client [https://github.com/ethereum/wiki/wiki/JSON-RPC API/RPC] specifications and standards, and also certain language-level standards like method names ([https://github.com/ethereum/EIPs/issues/59 EIP59], [https://github.com/ethereum/EIPs/blob/master/EIPS/eip-6.md EIP6]) and [https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI contract ABIs]. The label “interface” aligns with the [https://github.com/ethereum/interfaces interfaces repo] and discussion should primarily occur in that repository before an EIP is submitted to the EIPs repository. -** ERC - application-level standards and conventions, including contract standards such as token standards ([https://github.com/ethereum/EIPs/issues/20 ERC20]), name registries ([https://github.com/ethereum/EIPs/issues/26 ERC26], [https://github.com/ethereum/EIPs/issues/137 ERC137]), URI schemes ([https://github.com/ethereum/EIPs/issues/67 ERC67]), library/package formats ([https://github.com/ethereum/EIPs/issues/82 EIP82]), and wallet formats ([https://github.com/ethereum/EIPs/issues/75 EIP75], [https://github.com/ethereum/EIPs/issues/85 EIP85]). -* An Informational EIP describes a Ethereum design issue, or provides general guidelines or information to the Ethereum community, but does not propose a new feature. Informational EIPs do not necessarily represent Ethereum community consensus or a recommendation, so users and implementors are free to ignore Informational EIPs or follow their advice. -* A Meta EIP describes a process surrounding Ethereum or proposes a change to (or an event in) a process. Process EIPs are like Standards Track EIPs but apply to areas other than the Ethereum protocol itself. They may propose an implementation, but not to Ethereum's codebase; they often require community consensus; unlike Informational EIPs, they are more than recommendations, and users are typically not free to ignore them. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in Ethereum development. Any meta-EIP is also considered a Process EIP. - -==EIP Work Flow== - -The EIP repository Collaborators change the EIPs status. Please send all EIP-related email to the EIP Collaborators, which is listed under EIP Editors below. Also see EIP Editor Responsibilities & Workflow. - -The EIP process begins with a new idea for Ethereum. It is highly recommended that a single EIP contain a single key proposal or new idea. Small enhancements or patches often don't need an EIP and can be injected into the Ethereum development workflow with a patch submission to the corresponding Ethereum issue tracker. The more focused the EIP, the more successful it tends to be. The EIP editor reserves the right to reject EIP proposals if they appear too unfocused or too broad. If in doubt, split your EIP into several well-focused ones. - -Each EIP must have a champion -- someone who writes the EIP using the style and format described below, shepherds the discussions in the appropriate forums, and attempts to build community consensus around the idea. - -Vetting an idea publicly before going as far as writing a EIP is meant to save the potential author time. Asking the Ethereum community first if an idea is original helps prevent too much time being spent on something that is guaranteed to be rejected based on prior discussions (searching the Internet does not always do the trick). It also helps to make sure the idea is applicable to the entire community and not just the author. Just because an idea sounds good to the author does not mean it will work for most people in most areas where Ethereum is used. Examples of appropriate public forums to gauge interest around your EIP include [https://www.reddit.com/r/ethereum/ the Ethereum subreddit] and [https://gitter.im/ethereum/ one of the Ethereum Gitter chat rooms]. - -Once the champion has asked the Ethereum community whether an idea has any chance of acceptance a draft EIP should be presented as a [https://github.com/ethereum/EIPs/pulls pull request]. This gives the author a chance to coninuously edit the draft EIP for proper formatting and quality. It also allows for public comment and the author of the EIP to address concerns about the proposal. Members of the community can publically comment on the draft EIP through the pull request. - -If the EIP collaborators approves, the EIP editor will assign the EIP a number, label it as Standards Track, Informational, or Process, give it status "Draft", and add it to the git repository. The EIP editor will not unreasonably deny an EIP. Reasons for denying EIP status include duplication of effort, being technically unsound, not providing proper motivation or addressing backwards compatibility, or not in keeping with the Ethereum philosophy. - -Standards Track EIPs consist of three parts, a design document, implementation, and finally if warranted an update to the [https://github.com/ethereum/yellowpaper formal specification]. The EIP should be reviewed and accepted before an implementation is begun, unless an implementation will aid people in studying the EIP. Standards Track EIPs must be implemented in at least two viable Ethereum clients before it can be considered Final. - -EIP authors are responsible for collecting community feedback on a EIP before submitting it for review. However, wherever possible, long open-ended discussions should be avoided. Strategies to keep the discussions efficient include: having the EIP author accept private comments in the early design phases, setting up a wiki page or git repository, etc. EIP authors should use their discretion here. - -For a EIP to be accepted it must meet certain minimum criteria. It must be a clear and complete description of the proposed enhancement. The enhancement must represent a net improvement. The proposed implementation, if applicable, must be solid and must not complicate the protocol unduly. - -Once a EIP has been accepted, the implementations must be completed. When the implementation is complete and accepted by the community, the status will be changed to "Final". - -A EIP can also be assigned status "Deferred". The EIP author or editor can assign the EIP this status when no progress is being made on the EIP. Once a EIP is deferred, the EIP editor can re-assign it to draft status. - -A EIP can also be "Rejected". Perhaps after all is said and done it was not a good idea. It is still important to have a record of this fact. - -EIPs can also be superseded by a different EIP, rendering the original obsolete. This is intended for Informational EIPs, where version 2 of an API can replace version 1. - -The possible paths of the status of EIPs are as follows: - - - -Some Informational and Process EIPs may also have a status of "Active" if they are never meant to be completed. E.g. EIP 1 (this EIP). - -==What belongs in a successful EIP?== - -Each EIP should have the following parts: - -* Preamble -- RFC 822 style headers containing metadata about the EIP, including the EIP number, a short descriptive title (limited to a maximum of 44 characters), the names, and optionally the contact info for each author, etc. - -* Abstract -- a short (~200 word) description of the technical issue being addressed. - -* Specification -- The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (cpp-ethereum, go-ethereum, ethereumj, ethereumjs). - -* Motivation -- The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright. - -* Rationale -- The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. - -* The rationale should provide evidence of consensus within the community and discuss important objections or concerns raised during discussion. - -* Backwards Compatibility -- All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright. - -* Implementations -- The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. It is better to finish the specification and rationale first and reach consensus on it before writing code. - -* Simple Summary -- "If you can't explain it simply, you don't understand it well enough." Provide a simplified and layman-accessible explanation of the EIP. - -==EIP Formats and Templates== - -EIPs should be written in [https://en.wikipedia.org/wiki/Help:Cheatsheet mediawiki] or [https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet markdown] format. Image files should be included in a subdirectory for that EIP. - -==EIP Header Preamble== - -Each EIP must begin with an RFC 822 style header preamble. The headers must appear in the following order. Headers marked with "*" are optional and are described below. All other headers are required. - - EIP: (this is determined by the EIP editor) - Title: - Author: - * Discussions-To: - Status: - Type: - Created: - * Replaces: - * Superseded-By: - * Resolution: - -The Author header lists the names, and optionally the email addresses of all the authors/owners of the EIP. The format of the Author header value must be - -Random J. User - -if the email address is included, and - -Random J. User - -if the email address is not given. - -Note: The Resolution header is required for Standards Track EIPs only. It contains a URL that should point to an email message or other web resource where the pronouncement about the EIP is made. - -While a EIP is in private discussions (usually during the initial Draft phase), a Discussions-To header will indicate the mailing list or URL where the EIP is being discussed. No Discussions-To header is necessary if the EIP is being discussed privately with the author. - -The Type header specifies the type of EIP: Standards Track, Meta, or Informational. If the track is Standards please include the subcategory (core, networking, interface, or ERC). - -The Created header records the date that the EIP was assigned a number. Both headers should be in yyyy-mm-dd format, e.g. 2001-08-14. - -EIPs may have a Requires header, indicating the EIP numbers that this EIP depends on. - -EIPs may also have a Superseded-By header indicating that a EIP has been rendered obsolete by a later document; the value is the number of the EIP that replaces the current document. The newer EIP must have a Replaces header containing the number of the EIP that it rendered obsolete. - -==Auxiliary Files== - -EIPs may include auxiliary files such as diagrams. Such files must be named EIP-XXXX-Y.ext, where "XXXX" is the EIP number, "Y" is a serial number (starting at 1), and "ext" is replaced by the actual file extension (e.g. "png"). - -==Transferring EIP Ownership== - -It occasionally becomes necessary to transfer ownership of EIPs to a new champion. In general, we'd like to retain the original author as a co-author of the transferred EIP, but that's really up to the original author. A good reason to transfer ownership is because the original author no longer has the time or interest in updating it or following through with the EIP process, or has fallen off the face of the 'net (i.e. is unreachable or not responding to email). A bad reason to transfer ownership is because you don't agree with the direction of the EIP. We try to build consensus around a EIP, but if that's not possible, you can always submit a competing EIP. - -If you are interested in assuming ownership of a EIP, send a message asking to take over, addressed to both the original author and the EIP editor. If the original author doesn't respond to email in a timely manner, the EIP editor will make a unilateral decision (it's not like such decisions can't be reversed :). - -==EIP Editors== - -The current EIP editors are - * Martin Becze - * Hudson Jameson - -==EIP Editor Responsibilities & Workflow== - -For each new EIP that comes in, an editor does the following: - -* Read the EIP to check if it is ready: sound and complete. The ideas must make technical sense, even if they don't seem likely to be accepted. -* The title should accurately describe the content. -* Edit the EIP for language (spelling, grammar, sentence structure, etc.), markup (for reST EWIPs), code style - -If the EIP isn't ready, the editor will send it back to the author for revision, with specific instructions. - -Once the EIP is ready for the repository, the EIP editor will: - -* Assign a EIP number (almost always just the next available number) - -* Accept the corresponding pull request - -* List the EIP in [[README.mediawiki]] - -* Send email back to the EIP author with next step. - -Many EIPs are written and maintained by developers with write access to the Ethereum codebase. The EIP editors monitor EIP changes, and correct any structure, grammar, spelling, or markup mistakes we see. - -The editors don't pass judgment on EIPs. We merely do the administrative & editorial part. Except for times like this, there's relatively low volume. - -==History== - -This document was derived heavily from [https://github.com/bitcoin/bips Bitcoin's BIP-0001] written by Amir Taaki which in turn was derived from [https://www.python.org/dev/peps/ Python's PEP-0001]. In many places text was simply copied and modified. Although the PEP-0001 text was written by Barry Warsaw, Jeremy Hylton, and David Goodger, they are not responsible for its use in the Ethereum Improvement Process, and should not be bothered with technical questions specific to Ethereum or the EIP. Please direct all comments to the EIP editors. - -December 7, 2016: EIP 1 has been improved and will be placed as a PR. Hudson Jameson is now the EIP editor. diff --git a/EIPS/eip-1/old_process.png b/EIPS/eip-1/old_process.png new file mode 100644 index 0000000000000000000000000000000000000000..51eb2b25826c3f97b38a4fa17425a86d27c0d962 GIT binary patch literal 20813 zcma%@1ymg0w&n}>;7)*GA-D#2_u%gC5Q2pOjRYrHaEIXT?(V@oKyVKpe2V|Q_szUn zZ`PV#D@li{ZmLh6v(Mh&_uC!%K~V|~nFtvG05lnCaTNf7h6kVTAVPzGzX@8>1OI`w z6j2ZXfJNAq>Lu{UEt}ZWyx{O!|Pyyxz zxK8kid?7>~8a|-QsMIL_pCj~I)Gx>Tku{JAP~iir{Qv(BBL?vYOzi41Bmg*Yo5-Kf zVZjeRQf)=~Y5mN@L-f0mUk3jju?;Sa(<&kzWf8Gh32bOp?UxfcgchqLa#zjn_R zlg`e;19%OjH)s;dg}&q%h_KLyBfoKAEErsFPV`Bmf)C)Ur?SvG8G~3Sr2li`7s1Sd zO{A})3Ffz71P{h`Rs4=9_t# za+CFDKSG&R#6AQ6DsM6o40e4P?NSe0ud&dC!_WOU$!_oIEMh0IY2=eIUf9pO^gbvVRspzJVf; z++wcwes}Y|ff@#Q3NC&CGe0=yqPeU`hzhBIaG6F6iE@eh@UT4qc$%Y~mdRn?(~bP< zhnrSWUzyOQSvw@DSU1?RdR(ewbnUYN0N1nf{JM88)Ll#;jIz))X8?f9wRYZmf$Qdr zfdB*E$jzFskoVoEH5y`;%g>xZBjy`m-hmzX>G|p2@#)b0;c^)n+*C-1WJ5$JBVbL%DLjOasq$Sr_tww-q&c2k08! zmPG6JNK^GbCDT^4ZZ0cHKTmte88W3Fa>fc|)r$J)0NS$K`}47PfYH%$>%+7?`CD1+ zP2pvq)@*H<8|gUJxZl)3r&UFUfa^)Ht~Vwo%Nw5rI|qt`ZNj>F=I7k<4`_hX;j?Ya z0x2%%STUQjtMD|&m9)vj-W~yO*XG$P5^f{5hfy<;*~$4pztkm;dS$0@YBcuKuW$} z#AlD;?*vt1o7D|@CR0aWfJTp}FJ5X9UBXg*g0U=%8k7-jj0F?5tBo+gO|Pu#?%O6e zs))AZf)2a(VlD}B`G~gN0h`^;H(~NLB^4DDgM(SLvL&-8zuLTRPFC41MhC~n#)gNH zT?14uA<&AxZ8e7pP!1~7*fb~rWYR#*FxxMUP9b8Z-uKMBCLjGIH2sNef@)c_#;HK)-TBc#kLSU70eM`)mEWf|M zuXyutIj!V-IVlAnU>uG0Io(vs9%@*^U~ag&`Qx&e)6EoT9d&sHRZD#JYmND4(uBkk z`@|a(1}C49^C|e{*=Dw)!$Wv&k>uv!dIR6Nx+h3&?c(R!t1OoTa>u>O3Z|K&YJM(H ztC5d$DJdy;_lD;K_>tb=WnEocw&azBpSyj3 z2=sA_F{X0n%FACNG=IAOEvge_lUg3{)yFn)KyJHNtq~y7i#SrvFq?t~1jv;^Sh|}r z>*@Sv7Xm{_kZfH&>z6AOHFQoXt|ymE^RzUMDV}_%`MSR>4ZVAUg8@|1#O7$g`x)Wvu zPafVb8o?Fvvg541a-AF8oKn~56{xMUdSsXS-ts3I^N*e#qe%Giov*TRF|b0nuI3Ge ze4koXksg&%CkVFEMXgJMwtK&}lC)7P?r5#axn->K(H~@KC(NQ!NNTxV76w*wkU#+t za*CzqZJR_!q2;=Rp}h*hcgcyi3-|pi>~8^br6M0&5fhT>WfczJYei0B^Q(qaMj4Hn z{VB!af*&P-8Fj&T;!Fwx3`B<$9hSTgaO8~pHjCVT`B2i%EX^UO?f2y$XmOCgQpC`* zv0*(%hP*s5kiY&w^Ai?sHvRLcI87ZYo|7vTC3v&qvOAt$v*vq$ZEwaTt*AIYGNM~= zx7g^sDd}N&hoZ5jYTcDkI|L1cB&QnE(KD$*sad|h@0p^0k6rO3s-Qu=^gSV+_j_V2 zIg8EmI6YUzV;B{b@cm?}_FRwWcJNar+Z)NOwqJ9VUM^y=NWc;bnR(90cAmYuBb794 z#P#obJ?kp0@3&;N3_{VPZ5q}x%R>)VDRYlM%2)NZ^vd8rShhEo>@IWBhBbTo%zyX% z3VfLQseU;M8wSs&VwdSu-VMdQTN7|%(Zj4^?n$`NYs3+{Z z2VhjrC3v5eK3$`!rlFA&YWwrZVz2JpqgBLzS-awk`su$`woDw2z~klgTcwOo0wUmg zU#zj5$Pjp0??XdKuISWW9fs+L8%IIqZPv~v+<&gi`_RiZp*y#iaUfb4P%K#lgbLS` zN}m*^udzN4!|zd>X->Aw~2nd;hirfLKnRDK@?SF5-O-+TF~+vAK(;Yds}EV~RZQNFXCL;X|EsdrkX zS7!S9;K!=ATFDi|tw@-;bxOWfig`;}(a10d!?KQrK%VfTxo@^yJTYmH*R&rs1%(MX zG8o8hu-0Ag>Y8VvT+#cg(;B0BZm?wU8Aa?S7FB95jEJ|J2)fz=$(`G-#B7%jiwwC7 ztvoYY*BbQ60YEv70s)MP^$qnTk6Y_q>9PROczzMhO6@>|31vQ=ufQDh#FBWAifK_`t0rLc{@Pn+iJi3{?s9?=}F=pS97smX89*U zkv4nHX-S-ViwpFGgq?9$_Jh(6H^N!}Soe>sXtM09nq}_a`2^VJuNu7(rZ?uOM;gBG z(qD8bY$-o0?d(Kpmb%B_%9u6%AcX>yZ&uL(;5^aX*#VgwTBE`sl16d&;CLS@zrB_}<7RGD*-=hluAC7Sft=ijqAK z?p7IVCro3|#0}ZKPnFNFvz;du^7)b_7bv>X{S~FAx|)rRje>%r_5Mh=#JxG3t}Ylw zmy#@r4(>zGjEsYjT`Z0q)C>@J;_8()wbJ~xe#_JIhL4neg+u-uQ6;>`Z)(|n2W>}j zx{1`|q}DDYkH1h*fEI4KitVK{gQ|~@VCICBTi@W|Ab3G!b7-1sbhFpT%d4cZ(o_|# z=dxgYh*J{WzxW~*I4%x@Do4Fg@z9Jps_y>s&jDKX_BxM2&0me% z+FMn0^unf-9JS{(R>0r=%6Q`_!M`oT1HlqbP}i$^H+0Mc|2kzy_@q1!>wTdb z-Bz$oN8G?>US3`{Mm-oJ{mNf+MqsjHO=a6){-_BKsA{O$Df_;ktRcZjU#7=lR){q1 ziPbh3s~V~6f<;9UThb=>9xhkFhVdITK@fQTcYC=}Y1cw$z1Y4Fn`A95ElL^u$*HM) zD&Bz8)q-L4q_jp#A_*m4=rLyK=B^{1=qsLh+<^+{5X(GD6#MPF*xYim%)c>jV?-Kw z-5)0vxyW`sSZ!MAFTxH;&}~z%k8PVA=69pM?fK64UzZj2fi-eE+hn%=>4&$JxgQRS zyY&i&W-iksaXA@Lg^zM+>&0%b9a=meyQ$RBobN8J-+Hr{_D38qH@LgI=VH`XWuZ$_ zNp^=tYaj*JC)%yG!&Mmvm^crQ4$4ed*J}%K{_sQ)TK>-ei7ob2UD?mmKE( zHbp0e$kxqX<_*p0$e6%I-0HF>>Ft)d-0p12F{3LzMS<>S@kKp@lby?!w&;kAdShU5 zx}f*xE`K;_GHI$l`BG9Y?J@GqS}*W zNFN%pIqa^&B~+Hq+QL<%1Jmm!s@&%ppPtPzU91%z8Y>ah5;D9_cs@me<0LF1;ujZi zyG~7_VL-%0KFIU8lT<%`jI5|syQkVNxEgWA*!4JTDQu-LC#UM z(#vdL=@TZ^-Uthvh1c6GDdG;j?hv!CckO3W?w)hxEErC|5_Mb39qgr)(Xd(~N@GeK zLa|A0nWIAEUQgB3Syu44{PS})dwtj`!` zI8%7Yt);VG+|)anZTpEEETxT&H%@(@?``MHU-P*!fHiCcsyOD}q!hZ|I$|)k^weEG z&U(zc5uy2+VT^lK)?@gnQg|Hsc_=Ia*{lAO0Q@ff{3#nwz`BOQTu*R>8J~}^*5g>$$6{gLx zO~clVz?~DCaR>og#O%j2{x&6|$^KNH)ne)1-rn=m>9fyXcJRqcld871=kEAxoH81` zaPThh8F#}*N~#(dl+Pc=_!et1Xwc$-$?k6EOWpb$aSdkq6*_fc#Pro#49CaEl*wCk zovxH0Jg6n1QA9Ax%E}D9a=*^B{l$$DpJKj(H3?mAn$=^%8VHe8HOhgZh}q-nxK*f> zV?`A=8Om}LqY5RIuR?lx9;QTv5n>uth;K3^Tyu!h8w+6qF2QN~aapxM@v-9hjyX@I z$$SLw-i6d--EX!;)AxGOvg3aB^yo$@jobO^V79KV4qSz`YtQ|}j#+4=QM+q0=sma< zz0z8&Zfel*?8OVU*4QE#{G^T#f6tg(|3Cu_y7ltp7%NRK2!K`sZg?NK(IEq^59cEs z3WuLGTAH;O4C?I&0S5i%%ahd>-t?1~+6z<#0=)Q=FrZ3cQ9&g$Cs>gBhgQ8^a+@;% z^hXjm*v!&tZbGye+=$h*_NO|(lVA^n3L@d*-p^7TO;Pi% z<4$()H1GoPhtJ1o=y93oh31u9KWOS}6Wvc0pt z{SGJ0Z(M}lGP@%DzF&09)KnXfaixD2tyVsD(T+4SjxZ2UPj}3Rkn@zTzgWGb*QCmE z6RW$y!Q)&#h#R~XQcsd9h7lJia|j;nP5oBJ)b#WPsGA7gAJu^R+#h!XzgFgxI<)Wj zpX*i(UnQ7}iO^@6Wc_xogI-k&@x9Ik?gz#H zU2lt^Jm*ZYjV49jA(KeA#!`i5@XUWd%W?Qi$@J#Sp(HsqBokEDKnXU>Q~9SCE+VY- ztP`>j3%X*F8gyq2r4%%VY3K<(OR>Y?@Ia90qZ$fXfyrG@_+vh_^I&Cfhcstc!08yxQD=?UW1w|8wJ=t!K1u8Dc;>1uIQPnSQD-_meEE zxvQGtfDiers9>gJmDZ>Qdtj?K`HILfQh6VQF4Wz%hs+siLzm0I`$|1j{QN}~6Ndg9 z8Z(2Yl$(g;FMN*Tim#O*(S-c9yRfhj6UWEu6`A0u{qt3YuY%&Wk@FZP1XLn#;ND+} z#cq*%I>R7k=c8k+Br3&H(NXC%y<6BO!sbpk7cDjsUYLsn-$I#XGj86sM>W1PIW)R> zR}ESw)<@rV$cp0$e9LX0x!GC!wf5ICDnfp0(3unHokS`bTjoNruWi=&5o`jS#I&qx zkv27dPVexZQ4$(l(;I7YIjprmE?Q=`T~5hu@NG^@9|TF!K`mx`yeIQyBCgafZDnXg zAQAlX7fg9U`L)5p8%#*U@tLm;zongD9C~|Z;BzG%UE+x%kVaWnX*HgpGyn|!72G`d zA5}WTe>~tM0vp;~pzc*^JxvqPRcYK4WR%z^2TrvhV{YhF#7)VhuIKR-gjXa^OEtdF zPl*PfhkSX0zGKsAl8)z1tVx`|QdD-%L$h)2$5UMEzz1iOALY>jyiUO0csk$4Vc_tF z#Ofal8nyCCH;eZZpiERq%EEwL zVRaWez^Xt8lK;|ub99gF^SjdzraVEaX7S6Pb&+RtA|`u6)PBvCcJF&7-@CZBuXyYh zNIX5Y0{7R)#B)BV@SAX8gfTWS_ytB9f+PPx*e7CbBotA1r1XS@gzIa!hTs{SE1{>e zC~&^{{Nm6^X!FoOLR%6`-IxrjmDF;qy!OX@NBB{|m591mbxTobmY4rexi%B;y zO4xu2!o#lbQ-L&zN&tLh73N|ekl!6HEQw}j46cYGqUH&>1i0Ct*x!7s3=XN zvz`*Q|81#GU2%2w$Jt`_E+%PdmX{Yedk}u5bh-n8lcrr#K)B|^o3cu$jqaCmy}bO( zEDXg?mCX~-O#mg}nYrKygOLb9!UvV#4R9nWVnU`7j8u^}`y<7KVl>EQrYfM2linD! zia-P4D$+T_V2!=u?l0RV@DiPLQq$DbG&G#phiUkcpYQW@y9*}D$XZ1#Nzu?{?jtOy z1;kp8UUsG{pHF%T$h5)RFqtQp_!4%zuArcs-qbZTfO_%YO2ET|5F76&#~2GLmosk) zyx#~KG88mv^~0KI@mv3qnf2%dS0FXGeVDObU0s3k zGRPQQ<(s1h3;YA6R}c569hyaIihKw}+R8<0YrfCkSz&k_m9m{i-B_SU!;660lf@Z% zY*|KzXZoJW`0jH5>({S}I$g(uVX}FjFUGhElrl+wp2NYEVzDGu!oGtk_l4lCZtAH8 z_i1I!T7szx3O>`PWBP?$l_ESQy`TF9O)4m*-bzCgHUtNQ%R z5NwOtQ&x=wj0gs7cB9p$h)tS4v3*1@k}JaiwV9DQJRe{G?kt1l)Vo0d3uU}6P@l{33s+ZDkV|4k&@$sy@q(>d4jgc6yLaWt7Z1W03 zoi<2U69CrpyYR8!FE#WBm7p#yEgeb84t&%TwX?I+(IJvhPSa@gx?#G(--ijynVOn1 zF*Oa)n}a~qyBEIx%N60_xdpe)7Eo*ZFpOdR$jn?JprxVn{cWO-JMH}LQ zeL=NO(Te9@IQe0dA7-wvS#))W^JYIdClb@rzHIiRd1k|svS#lZk+8X=*fP>`e~ z0!1>X-3Yi!S%T?7vugJ>@0;U>wU=ZM97Qcn&H4Fx{J@Wc_!WB9Usm(WaHZOhZD>XA z)xO5}uvN-?+ORH3#|mzZRI|>fcCSRw&d-C>wgFra!K9z}Uf$?t)!m#;yAlOgl>hnR z0xJ~OPGNTH^lfuH zURqdK7#$tGyZfB|!2|R{O3~B6;$5r#3(rzM?EzRu08ZyyGC$A(qucXs(QFp0Z4`z# z_-!Pg`q%$d|D)(j*;9bl+l#p8bv>HI`r=N3))WhkT8l;F*>#!U1p9S;n&7nC<||+Y zn_eM3lWL=wCHMI61`%2(e=GszK}XL2Wk9$q6M$l-rb1ad5rCl>qL9Wz&&mX^uTy2B z;=>7iaep%LLjB1hE)Yw=e9dppQs0o~@U&BmL_yQv_te<2)KkDJ3QB;=`uc5-Ywe(b z`)!$!kWkyu@Kl2=VzCkSTUuHgc&(@(IUwdp?+qsU{(`0t5deCy?l^c$dXAS!z&-4(f-2% z;C=X`1>KK)K+kOr7v6`37!Z3NFpJz5h8u2)6?1W3rm*kNSfN8Q5zW2`SBO=;!VGQJOxkNsBUVSl-x~$0L$b^ocPlv|N=x>2wED@J`He)Bjyj zyv-qVvfhaS-`^0&jz>2zu7kCQ_w9BfC{3MkoOY8x!t`o=lUpY!q-UvbMxA_Yi-#XD6J&WGivy=JqILgBgFPS zTFYJxqdyv(i$(~0wUrs)>;xfxbS9LDUtOs)lFddI)|r~Ec7|4fi8iTv`;IuuVHLs= z#L@Eb$3UW$07&XTmQz7Nm|-{gQ{nq~*c*y1n|J=QuW!|YwaFc5)4963f*(0NGEyJ( zPye26f)ny_Bbe-?fg~tRTXmp^;~RjX6dweOZ4rR@AD&hhmT`uNXSBqJM-URCs>u_m25QKxs^>Pidh>0WuIsh?Uej?DHe+k zB`&e0@;%kOu1!}<8fYWcHmR!x#gX9Q9NH9fFU9zUsrky3nmGpZJb?gwB?AY?eL`OI z^s?FyGuuvYu$bCeN!q}fMztTwXKQXwJyH$MCWo6Sb5JZz%aDFqD%H3VJjhicUGHp&S2leJjWPTd9L=c@*pKkS|8t@0-uzwmB)`7v; zGMD?Ur}PICtd1^rCvJWuviLqdyp(?p4ft1BKV<<>`<*?!x^4?(Z4m{e6crV{z1yZU z$m6N4jN&om`=iKSDp=SSoJVk<0yVo90je131ZKmGxVVd6Y^A?~rmsH$6e6RsWdrfi z3~TxDkWp)D{UZ%3m3OO*CHgX;!t349QwJZgv4Nm>z?#=&ex)0`yUk+&1f>QIDMMrR zssNmwKfENyHPQQjzHe z8h(8wl0&R(#z$t*sg8ObhhVX7lV8zId^C;6Wju|C&+X{%^4e29m`G#4Ra{u^Rfe5g zryL~!K&J}~IlHaO18UsR2-n=*K;tw5=;AC?nS$Qr4Y(C0fW~>JBc+3>YkZyB;l;O{ zqHh$rAH4L`lXRy~$RDo$kxF znEk*O9WVLoDDwknK$q||M+)^aY3`(!u5M~fOxNy3ZcYw-sCG{!Lkl?Wz{?G(MyC$Sd3>j>F2_rC5aJL3=pE!7aHWA${@wDvN;lnbDhCci(1)oY))a@D zi2HrkjaD;M9}56vszs;gK5P+C)5PJ=ymv2?!GZxout3U!XFH9?tUw?P`uaDXJ)f>a z1?~^)D8)-!bBsKDha+CE%1(udlm+@V0_Q6XYDsa7E+Qsx0AF&sU%OyP)Ch8Y5D8ylW%cqbT?X(Q(Wu<6%#86Us zB?0~CmnT0d@wmQyX5R`d%-oz_zy|S0Fx8KE6=A4$B&9n^RX*E=z{wM!A6A7Zf&l_u zPX&h@Apww0ES6lrG@W9K_Y}iy;&ZQeIB5VOWs*FNU?w^MD?*MrW{-;GChBS-kH#E@ zCthTWo@2Z+rJ5INY&Fzn^aW92nkFtZ-3PaXE?ne4p<)C#0` zcBmF=|6&s zKfPhz0plTumJ!FqFB}=|wLXcl?8?lZRga51Wv4SzQcPzxLl4W~W@HX+SPrPbMZ>w^ zpp;_xRemLRmW7raxsjd*;jY5t#7zwl9k)rzkTUw9PRBexcJ>9AfAkL+?=}TiAh<+>Sjb;tMOaXKb}yu~T{t;5&OE4O zK)uON7}7c}Kq88YFV6u-4h>-R;kRn)@Rwi!mz4D-fwcae>mm|`U>3%TuzMY9Q4 z#o&cY(Bhome%ZQ&|4VpB$PtRB(hq81T0fNM=*Yg3ujeKTm z3JG%+->0*JWyoA%mNn5}VQ_(bC?>k#F_Ozw_oBls?s2M<)C;felP!ZY10zbZPUU&SFW1f}LPs6y{yG{=vE zP6W?>8Sl9=gy@13ZyXG~H+&jz19Xah2Y#L`zP%=uddZR*@SBPm4$lILZ!!6+E}M6`accJ4Ns@^Dn`?q2Lz{Yy{m|BC zl8WD-)~G%BmSujEQqLgGSYL!%BrkZCpt7$rZ1fToD8FLM4Ep;$nLMD~)G9OkO=EPG zziJmRD=jZAt)E7KD-)nTb34{L{u)&pmop-_%mLCnwUYWEQSf2M_ooS&IXR>C;r{-~ ziG!^J?U3a3PBFXT$}FGooTvG)!|SnXwL_6ZklVUSoD6yrjZ`3$9#O1QW{^`Qx>}@b zy7Y;K1&*a0b*@CL#fZnM8RQz?$pL_{wu%cBkW}J&QFih?V|yQ5 zrJpn!^yaQJd0nRhSXn`^Ls43B`OEsJCK3Rc`5Mg3D^(D)NmgdFSE$usRjmbpTX!>b zItu38#@fhR^z6u~nz!?LR3QK?h0O1jG|Dv%s!$+8lPFq1#>Yut2bv`!#xGE!q?C8# z=d%sejI1r!4`ENW7_6vzIP4SepDhJjs+Ir5tRv1`1|wwbPs1hgVdBoGea+@m^0+|Z zoRW%sK3&3soq+s}`k|4_KS}N3vAze1WZu7N38+qSK0f*I-_sv|Ljkq(%ew8{I_=No zv42bsMa%CTpUR(mfy)h|F0K;|d5iH((wefbZ`vVYP5NR55 zk#k-e=b^J#=I0zuL;xMT99wfelW6Ss7hGZd`|kGYsYlsHzVXKy$hp0fuhPzExwDkT zWfFua`|*k`7}Y$$CW&{bY#J-C#k|f%X4|voHHtY40jZBL0C?{;sMrQZhbYy+ym%hi z2O+=lIXS-bCmEmu%Ug%rDU?H40LELY>?%`FWo?OSuLhNy8oYfkFZj{YhO=)kqpU%;)kYx#`&$iUq}*vDEF;dnL9?gP`Hsg6c&O$7%Mwo)*ZA+2 z_^CJ_Xo-ioI25iu;oEet-T89Wg2;khKv}rcjg4gi9{E`xgBt4Wd(Tf{IXmL2a&o2$ zeF-@J3+~G3{;(2Fbsw~+b8(k#Q$X1(YR*pihq#j57_MPBu=Msw&QMRECwE zb<@v}DqqEBMKNEt&_LR_=~wF83KM0pkgJ;c$CeY}SSn9V7tbpY*#un89h$`|AtAMi zj>9XT3I?m8ue`$bsMmX?$Y4G|7rNwO3r1g03>51LDK!~<*0?!dNviD`&aplRS?c0p z26f;3aBFxV7RQ&tv2a`y8c@UIg=dkEzyOmzTzA^kf+2PAG*NZhzLE`tms`guJ$0~x zy)k8>Fz7jdAcQ>I@z}u#kpE*RhizSt7nA=x_ak!JdtXsopZY`|!}pCX;u`>Itj!6+ zvL&_Q+=^f5CIHOfh_QNse;d_2=Eze=Qg3sd4*y9kJ!3YF!LV*0{1JCp6{n+6dEU9Q zw(|@O1gxl1|JmuS=yr?}O&CNm zU{f3t?n9xISd%bcnj)|h{*~~#q1Z1~G=@6U@Gih1V*k)hm*KDZ(DCCrW@Zx))61K*IYWI$>}wzW~v?a3=LvEnjN?9ZQNcX<w+&?NDLccSHF`maoP}fqe@TP9FCd ze}2bbPu7M;UOT>-YG>8z+$=7G(%N!0gFjPg1Z{Vl-8R&Ko~O-mY_D17_n%N~Ga7Y7 z)a3WLu?mQaipKHljz?sC!NF0l!Oza|U;O1Q3wS5r;dgh_^f)t$_bP z`d8O-3d;*!Sn?{d?RppQ#6c^ub;ZXb<*-0VvZjAz#4sEmz`ifU5k`xSb;{Idn@?@e z*%^%-nB_97;xY%5e;gqYP>&t~%{%g0xmc>tJB1r3#srj4`DuhrtW2%ZLuLctUXOqj z+&>s%qBIpKC`=3udHxQ4+p5S8219F~IwGUpgo$4|)kVJDEXSIB?!~Va%a{Zn2ez%< zEWa3h8Hx`m7hNBos8A|j2@eJM zOs^q7TmcU`9XGU#f=UT0l)}2_qnK2Vkw5L*G_1F|6Xt&NM7X#z#PqobY{s}7*(v#~ zD&E_>;N?^5Cb;BzTd*vw_?@QTul~_PtOouhhNgg~Pws_>7w|e*L2tODpfD1BU|3uc zX9ZZ6+^%q8gw>8Hk=$-smr4%k8wStN-}Wz$?m8SiV`Y$ytC#I#hg-imlC9 zbN_%H;VzSIbcx1dym;}El{U`A6-z{9%UnS@nH_G)2w6o&odI0*>d!Q7LEUl2-gy0A z5BH4;*87LAl_qTG)TmINn(XH6I00c9^p-`M@nlLz#i3GIh#jXZM7N=B``Kaw z7Rd%G(%TKt0P;A$;qsa4*dXTj1z)|qBBzn5WUyfUKEY_f`*jVO?KWlgD;5&aOVf)> zN-mw&YB9W6cge|BRaGFz^azqh0`dy64`9-fC1N1}dF=cs(nW#<@lf=0l_*Nj^qxfl zI%}WvFoyba%vX}wWdsocfCB3PCryxmpbi<>@`S68uberzrq;CIIm~B7xx4aHqe*OG zvW7E*9j@eERU`w1Z;o}Zmgig240!IxcyqaL1F#4I0LS->h^@esms>bz$w9{#=h^0I z59fwsQp0pF!%MY8hj?URx`~klZC|_sNB$+AnX({+FM?#+EPLtZ|=pHjR}4)&2BWWN4`8-F^W`UG9JG{(~la9WbgHm(c4BGqO!@ z26hzs9o2DGvXcSG^c{L!?oCg2j9A%=+ZBzU^PxL`vxU*MG}(527sZ9t{wOiugiV1b z?=z`HksK79y(;+5joGRD?7+#Y-!37NM(|I4&@Ml9t{RN{?hNSEbNq7Mr54|E1Y|wf z%@@DT?YR44W>9W?O6)R`20-}p?#kdoo#h?nCLb30W`X$Gwe|+HUnRC#TA<72J`7jP#o2un>?o@=W*N#lgpi=>#<|Y)C7p$b0*? z6)KC1i}!-WyYZj9X%G-cOpL$T(w2W&TQW<83J>nh&NMUYvgTc|7|g$LNadU?KocLxn%?)< zkA`$#VS$*$Zhc~>@tT}gjm4NzXg|OCYcq}Qi9|W&IGzd?mygecaf$dlxR&bBgE+|0w zL~+hbd^5o^Mlc#zz0R68H8hlXFzMkS0s8&|e3cA^^Jjx1F}lUC6aB{4QAo<*w)Q_M z^S|w-T~_GdPxAwI9>>=B+O!@!b!aP5M|3wZBMu=!8~sUrf?;~<@s6hswIgerW=Z35 zpyCuApJua?5=V|1gIOS@+bb2yyt5P(Eys?vx?n3FI+3sxlT8+ZV)((ERN0*ub)-cRQJ z&TQdZt~i(+v#Ufi2`H6!h@1@fsvFLK_k&vQVGa$XWnP_tCOJsjgMk12-JPTfIZ;GX z!TVh(0LRY98e+UT#GK83J~!&(9<*sUZ?b5su_^Do)4D(9dCRB1nt?}M-Y6Ez|EwPW z_55-M%nZidUI`oycv`3_Uy1|32TcnFato|299syKT7hEfd+%rSOUnItSLrTXd!6o~ zC)it^AGFBtJ8Za`U(qbXv(G4^(y$oCv*d$72MB9`zVbNOg&=7`P6VrbV4DY=<4&M8 zLOVRTR15*bI7JQ$M}?M{#>DoKy0yo4O>IL4Dc5`Av9;Gi6oXG3(y8Wed54?-cd5fE zu0Ud6_Y{q(3;<5P-)m&vl^2RxA3_(3XnauV)ebdNpLptSCS-S%BL&Plc-IvF%Eiv( zLJ42nq8y`{{vfy&=J6o$BUl{{FyUW^Ao0T<+HVb(RJ4Cy@AP{i6Sbx zyLXFysO(EV>gtmFFn8suW^_EZsovApdb3N)D9c1=fEKWPf2$~_L7IvhlbNsccO z1|{a8HG@c^w4X;|O7%?)KB8SyiTCsp&z~H$v%y~GFywC$5fNcwVId*pGFW5IJ8^m} zrWpUumMJF@L?o%cVZxc`!Nl|`mZE^7dOcGNRloW=ZVw;V@d zZe0)6C@e330vrC`DyDJ&_BRIAYnq=PKd{6pV&rM$WMr!5k;_eyK=Mqh>7zM7F%KSx z-$dtsZD7#!aeFM4%bbm{02dV=<_6#H&ggeH&uu@tOVC$6XHJyXb;=%sD=T5SvB3S%9Ki`Z81jpXxQbbjx;lAX(T_e^xnvP1i_Sc zS}Ynn;bDlmwx6(3l~$nWo6Ly@Ee3FaDvt*zz#0V*9!{c?A&mkp4QFO3cF~{$u%%!F zu1c$P{!kxX0AwXVb0{-P_A3%GcNwUhh+s%_8JS}cq{+K!5gJL3|4|b)Gux^*A9;G% z6>1^v*2t|wwaNV0ljZ91Ca>2y!VrogShB6W;G4#o_WCbDZ|GDO+h;J zm*wF9a$xQ0cuhq`r7^Rqsi~d*-#Y^Yh2)1HC=|;X-I5-=5vH%3cXAnSOylFS%!r1y{?qiF$ zY9fIcAtMu$Bz76Nn!q!KQ3=%pbGHHzQwaSl`+SYxev)s5Y)fK@DE)F}G*cqr-6EJ! z!eBu32c>|$$eb)HPy^V2P9W}r9zwg%T-k!ofLLZDT7#Wz+IR|Ny$V4Qb)c|B2pcyP z*b9fhcH)`E2Y!h{Bw`*ts`a3g1;Lyy5Rk=i9m|4?k5t_jiMXdq~(c;!=_)%~?14Ro=putMLBhh@#Gu+*3cepB-@OgI3#E2^#c-s=ktg z9b!C_#78->#13aJwSK7Mqy~p;2L1*W@Ic*?XNOLih6X6{Nna4XYD-KYCv_NBSl%xB zN_SEaL+bbO4Cddgo*z7c2ttroj20R=Ryk$MpehU$AFDH3r^b3GR91Q4A8Pjtlji0~>I!S?al7`?we+{I5FBJRGWpkKF5)qQ@Yh$mmri^Ns36aW{EwV>+WgCP@ma@EOy7#?r?|q(o z{yEQcmOsvUp0oUZpYP`fpl3hVnO2XauJ0C7v?sO~y&E4;r=sAiFJ+~HmZf@DKabGJ zZbhZ)&d<0RJAKG(NI!NUuXZ)hB_Scql=T5bPrt^ydFBu!__J^EY4p1n+AMg25b>;m z3$4s=A~&GGdOT766QD0_clO+VcpfGia~^oWwjfK`v7obAWinOg>lchJ(7P6SDo-Zt z>{!Ih!VKpX&n`si2upi~8b+ukeRLI#`xHvcaK}7i1xau2?XnwUoPMxx1XA6U%ySBEl~Xh-Wb8;Cv&^*;QOq zy>1OWGU78>##cde^3*nvk=B6d-BqXFpuJw)gIggkKU@@|Tn?Psn{3|VyQ4UWy&AE~ zuFfkY3I-v5iwG{lE?p1^lvF$83iAIIrpsJ}oS*kBr<9>kV~%6P_@^4PrpDLZ7+c5{ zl^?c2Z*u~o?B0-NJE`}GMIWHu2DRg70N>vxXN?TOm4}I3?>@JlB2^`87?9tQUKduk zHl(>6D*3l&?>~>x)ouH}I83o3y>jzkyLG%-C&NrB<0k)vRqc0mD?hGJTVcR3R=ha49z`gVs zfCD*4+}^>H{ulug5+@LulE2W0t}`j!L(t%IPl!97M~&Rxne%|Am%^MYo1WD_k`pMI zSG5MEg!!yYsSEH+|tL*y>+XV*CB{2Z; z65ou%_{%>3%!Zuv2N>fO;z>8V>(+ohU0rG&_Eb+U33il#<{rdRIQ0zcBn`^?=l$E# zZPkvYn^$PLE`1DTZc(SnhuT#@KqiOa;EFTgN=Nh3*)-MWV}i$` zR^R#*yHQ`NTUyEhsX6O?(r>9bqAM$|`}jTF;LHcmt882hp2Y=QUR&Wd@V&^2)CMyd z_hv6VXJ9$(p1!MN8>lj4dSM0Rsrn}Rq-e^CrU-ZB+q+~8E(%j_Dt#iu>^e29FGg^z zJg3UsIjN$$EzC*zIy@)?tGtaGiaUh%*Ge7aKn*=|wj8~p7&&@4uEZ0p`M-eQGFNT_ zo`T!v=gXdy+|m-8+0KU}fZ}KW7XKr$L^xGPv@QxmNb0O`>+GR-oQZMwT1tQ!`*s~KH z@tx<<#~`?J5qc26Dl)r}EUCwnVVSCZuan~V$6Y?pOrKp^jFct3 zbsv8)u^s1aiw9}{7JW;e$PeBk1jinfT4aElyq@aPwE~3b&fNWKKXIe} zkHTp##w)>64HgGbwyWDK()T2Ks|D}o?0YR?#Kh~2dYzls3QwUb@9cdDF(9YIL9l|g zVtx%4Sf_O5NQNTWCQ?fyhEOCbk{@&ond^=zETIZU?s)nh?=zli(W6MyjpKtc6r-OT zl$u=0o_Iqw7g|Qk5g|qp$ZV2&@kN5q!{d-C`>c13(}gr4%ZWahR6Q}OmRMRbNm@gE zzoTLo%g~&x<`%%yVH;kJM-AVn5$A}hV)9bYzR7kWYeG+r#wA=3(fSp*ONoD3^{lWI zUOnrC*VQnM^b2plw`9%X?S-naP)m=^Q%?TYpC)LE^{ui5+8;3x`~dQFk*oAZ{#AE3 z_lge``0Xr&yvk;m$+d}+qrYxl8$H&hlKtb4s|O% zXKV7=T-T~{NsNtS8!8)-fLv@A_jtO$@GppIG5|nK4jFfTm+1ei{GrpLira%HsXoka z&DFfwJbA?=D=Og&74uY^q`$dm!1wS&=hTihZUoY-=j47gaayABDl`7srM00C`a7)x zJR3z*>MiHC;UA0%>&|$t6auAgqKW>#A4GlT%5rM44HRUgLosTC#evI}Tu~H({Axx|MncF_P}gR`z1Y{K#8seb=@@Dmx^QD&29}{U z*z6<)($i#x9Vq8+I1D_<>FsO=9VX>3=37ba>G_H4X)d=*NyN7b(}v>m551PH(#0SV zlB=c}YV)gb7j15!lOZ%yYNA*8vOsmT`PB>$mxt@I+_8iz; zNQ80d+pwQ`&3A+1f2m8uui(80S}rw}A?+9_&`*m#HRa8p(+_%PF6#Z%rc0@abFuX` zVl*jdK&li;Yd*B25D%o{daS;I(Ot0l2n|`5WO&dQmc3|R`UE%@PP+X5#?x) zMK9?nWjkI7=gEG0@UO!8bL1Fb9?=Y(qkWl9;8h{ z9WCj4QxC74(vX}4@LKirXhhF9vTXm#HP^(I$w7Cdrl8NsOxDG^Rw)1FhKVp+`^i#V z(95fNiP6F6*dxt#3j&E~`@?*>O*}2%+`PP{k25wm+CmG$z2xubhpwwIE^ypZ*YFb8 zRY45#RTggA9U1aJ+FG;ywVLbmz%%xW6deI6-oBfs2<9qJ7Zmy!b*9qiiol2rIVO<4 i7$`*>{O_xqpf3x=q-)GRcEEf@kiL$wcI5?!$o~K`%#W)8 literal 0 HcmV?d00001 diff --git a/EIPS/eip-1/process.png b/EIPS/eip-1/process.png index 51eb2b25826c3f97b38a4fa17425a86d27c0d962..d259bb9b3b8c60f650574b430ab17355a10f932f 100644 GIT binary patch literal 27422 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 My(^b1F5Z0j9~Fw!>i_@% literal 20813 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 From b4ab822fe20295ae83e25796b2c24e7a66a6cc42 Mon Sep 17 00:00:00 2001 From: Hudson Jameson Date: Wed, 1 Feb 2017 16:44:19 -0800 Subject: [PATCH 0023/1085] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cb687a5644903..7b3e445328446 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ # EIP [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ethereum/EIPs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) Ethereum Improvement Proposal. EIPs propose and describe changes made to Ethereum Protocol. -People wishing to submit EIPs first should propose their idea an issue or document as pull request. After discussion it will be published here. We are fairly liberal with approving EIPs and try not to be too involved in decision making on behalf of the community. Having an EIP here does not make it a formally accepted standard until its status becomes Active. For a EIP to become Active requires the mutual consent of the community. Those proposing changes should consider that ultimately consent may rest with the consensus of the Ethereum users. +People wishing to submit EIPs first should propose their idea as an issue and then formalize it using a PR. After discussion it will be published here. Having an EIP here does not make it a formally accepted standard until its status becomes Active. For a EIP to become Active requires the mutual consent of the community. An EIP is not finalized until it has been implemented and is in use. Those proposing changes should consider that ultimately consent may rest with the consensus of the Ethereum users. # Contributing -First review [EIP-1](EIPS/eip-1.mediawiki). Then clone the repository and add your EIP to it. There is a [template EIP here](eip-X.mediawiki). Then submit a Pull Request to Ethereum's [EIPs repository](https://github.com/ethereum/EIPs). +First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP to it. There is a [template EIP here](eip-X.mediawiki). Then submit a Pull Request to Ethereum's [EIPs repository](https://github.com/ethereum/EIPs). # Current EIPS | Number |Title | Author | Type | Layer | Status / Discussion | | ------------- | ------------ | ------ | ----- | -------------| ------------------- | -| [1](EIPS/eip-1.mediawiki) | EIP Purpose and Guidelines | Martin Becze | Meta | | Active | +| [1](EIPS/eip-1.md) | EIP Purpose and Guidelines | Martin Becze/Hudson Jameson | Meta | | Active | | [2](EIPS/eip-2.mediawiki) | Homestead Hard-fork Changes | Vitalik Buterin | Standard | homestead (hard-fork) | Accepted | | [3](EIPS/eip-3.mediawiki) | Addition of CALLDEPTH opcode | Martin Holst Swende | Standard | Consensus (hard-fork) | [Draft](https://github.com/ethereum/EIPs/issues/25) | | [4](EIPS/eip-4.mediawiki) | EIP Classification | Joseph Chow | Meta | | Draft | From d1195b28a83ce32a582a03225e419bb2fa0d61da Mon Sep 17 00:00:00 2001 From: Hudson Jameson Date: Wed, 1 Feb 2017 16:54:40 -0800 Subject: [PATCH 0024/1085] Update eip-1.md --- EIPS/eip-1.md | 51 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index 4c30291a4c51c..332b9a3afc879 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -3,12 +3,12 @@ Status: Draft Type: Meta Author: Martin Becze , Hudson Jameson - Created: 2015-10-27, 2017-02-xx + Created: 2015-10-27, 2017-02-01 What is a EIP? -------------- -EIP stands for Ethereum Improvement Proposal. A EIP is a design document providing information to the Ethereum community, or describing a new feature for Ethereum or its processes or environment. The EIP shousld provide a concise technical specification of the feature and a rationale for the feature. The EIP author is responsible for building consensus within the community and documenting dissenting opinions. +EIP stands for Ethereum Improvement Proposal. A EIP is a design document providing information to the Ethereum community, or describing a new feature for Ethereum or its processes or environment. The EIP should provide a concise technical specification of the feature and a rationale for the feature. The EIP author is responsible for building consensus within the community and documenting dissenting opinions. EIP Rational ------------ @@ -38,7 +38,7 @@ The EIP repository Collaborators change the EIPs status. Please send all EIP-rel The EIP process begins with a new idea for Ethereum. It is highly recommended that a single EIP contain a single key proposal or new idea. The more focused the EIP, the more successful it tends to be. A change to one client doesn't require an EIP; a change that affects multiple clients, or defines a standard for multiple apps to use, does. The EIP editor reserves the right to reject EIP proposals if they appear too unfocused or too broad. If in doubt, split your EIP into several well-focused ones. -Each EIP must have a champion -- someone who writes the EIP using the style and format described below, shepherds the discussions in the appropriate forums, and attempts to build community consensus around the idea. +Each EIP must have a champion - someone who writes the EIP using the style and format described below, shepherds the discussions in the appropriate forums, and attempts to build community consensus around the idea. Vetting an idea publicly before going as far as writing a EIP is meant to save the potential author time. Asking the Ethereum community first if an idea is original helps prevent too much time being spent on something that is guaranteed to be rejected based on prior discussions (searching the Internet does not always do the trick). It also helps to make sure the idea is applicable to the entire community and not just the author. Just because an idea sounds good to the author does not mean it will work for most people in most areas where Ethereum is used. Examples of appropriate public forums to gauge interest around your EIP include [the Ethereum subreddit], [the Issues section of this repository], and [one of the Ethereum Gitter chat rooms]. In particular, [the Issues section of this repository] is an excellent place to discuss your proposal with the community and start creating more formalized language around your EIP. @@ -69,43 +69,43 @@ What belongs in a successful EIP? Each EIP should have the following parts: -- Preamble -- RFC 822 style headers containing metadata about the EIP, including the EIP number, a short descriptive title (limited to a maximum of 44 characters), the names, and optionally the contact info for each author, etc. +- Preamble - RFC 822 style headers containing metadata about the EIP, including the EIP number, a short descriptive title (limited to a maximum of 44 characters), the names, and optionally the contact info for each author, etc. -- Simple Summary -- “If you can’t explain it simply, you don’t understand it well enough.” Provide a simplified and layman-accessible explanation of the EIP. +- Simple Summary - “If you can’t explain it simply, you don’t understand it well enough.” Provide a simplified and layman-accessible explanation of the EIP. -- Abstract -- a short (~200 word) description of the technical issue being addressed. +- Abstract - a short (~200 word) description of the technical issue being addressed. -- Motivation -- The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright. +- Motivation - The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright. -- Specification -- The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (cpp-ethereum, go-ethereum, parity, ethereumJ, ethereumjs-lib, …). +- Specification - The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (cpp-ethereum, go-ethereum, parity, ethereumJ, ethereumjs-lib, …). -- Rationale -- The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion. +- Rationale - The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion. -- Backwards Compatibility -- All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright. +- Backwards Compatibility - All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright. -- Backwards Compatibility -- All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright. +- Backwards Compatibility - All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright. -- Test Cases -- Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable. +- Test Cases - Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable. -- Implementations -- The implementations must be completed before any EIP is given status “Final”, but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of “rough consensus and running code” is still useful when it comes to resolving many discussions of API details. +- Implementations - The implementations must be completed before any EIP is given status “Final”, but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of “rough consensus and running code” is still useful when it comes to resolving many discussions of API details. EIP Formats and Templates ------------------------- @@ -115,13 +115,13 @@ EIPs should be written in [markdown] format. Image files should be included in a EIP Header Preamble ------------------- -Each EIP must begin with an RFC 822 style header preamble. The headers must appear in the following order. Headers marked with "\*" are optional and are described below. All other headers are required. +Each EIP must begin with an RFC 822 style header preamble. The headers must appear in the following order. Headers marked with "*" are optional and are described below. All other headers are required. ` EIP: ` (this is determined by the EIP editor) ` Title: ` -` Author: ` +` Author: ` ` * Discussions-To: ` @@ -167,9 +167,9 @@ EIPs may include auxiliary files such as diagrams. Such files must be named EIP- Transferring EIP Ownership -------------------------- -It occasionally becomes necessary to transfer ownership of EIPs to a new champion. In general, we\'d like to retain the original author as a co-author of the transferred EIP, but that\'s really up to the original author. A good reason to transfer ownership is because the original author no longer has the time or interest in updating it or following through with the EIP process, or has fallen off the face of the 'net (i.e. is unreachable or not responding to email). A bad reason to transfer ownership is because you don't agree with the direction of the EIP. We try to build consensus around a EIP, but if that\'s not possible, you can always submit a competing EIP. +It occasionally becomes necessary to transfer ownership of EIPs to a new champion. In general, we'd like to retain the original author as a co-author of the transferred EIP, but that\'s really up to the original author. A good reason to transfer ownership is because the original author no longer has the time or interest in updating it or following through with the EIP process, or has fallen off the face of the 'net (i.e. is unreachable or not responding to email). A bad reason to transfer ownership is because you don't agree with the direction of the EIP. We try to build consensus around a EIP, but if that\'s not possible, you can always submit a competing EIP. -If you are interested in assuming ownership of a EIP, send a message asking to take over, addressed to both the original author and the EIP editor. If the original author doesn\'t respond to email in a timely manner, the EIP editor will make a unilateral decision (it\'s not like such decisions can\'t be reversed :). +If you are interested in assuming ownership of a EIP, send a message asking to take over, addressed to both the original author and the EIP editor. If the original author doesn't respond to email in a timely manner, the EIP editor will make a unilateral decision (it's not like such decisions can't be reversed :). EIP Editors ----------- @@ -177,13 +177,21 @@ EIP Editors The current EIP editors are ` * Casey Detrio (@cdetrio)` + ` * Fabian Vogelsteller (@frozeman)` + ` * Gavin Wood (@gavofyork)` + ` * Hudson Jameson (@Souptacular)` + ` * Jeffrey Wilcke (@obscuren)` + ` * Martin Becze (@wanderer)` + ` * Nick Johnson (@arachnid)` + ` * Roman Mandeleil (@romanman)` + ` * Vitalik Buterin (@vbuterin)` EIP Editor Responsibilities and Workflow @@ -215,15 +223,16 @@ Once the EIP is ready for the repository, the EIP editor will: Many EIPs are written and maintained by developers with write access to the Ethereum codebase. The EIP editors monitor EIP changes, and correct any structure, grammar, spelling, or markup mistakes we see. -The editors don\'t pass judgment on EIPs. We merely do the administrative & editorial part. +The editors don't pass judgment on EIPs. We merely do the administrative & editorial part. History ------- -This document was derived heavily from [Bitcoin\'s BIP-0001] written by Amir Taaki which in turn was derived from [Python\'s PEP-0001]. In many places text was simply copied and modified. Although the PEP-0001 text was written by Barry Warsaw, Jeremy Hylton, and David Goodger, they are not responsible for its use in the Ethereum Improvement Process, and should not be bothered with technical questions specific to Ethereum or the EIP. Please direct all comments to the EIP editors. +This document was derived heavily from [Bitcoin's BIP-0001] written by Amir Taaki which in turn was derived from [Python's PEP-0001]. In many places text was simply copied and modified. Although the PEP-0001 text was written by Barry Warsaw, Jeremy Hylton, and David Goodger, they are not responsible for its use in the Ethereum Improvement Process, and should not be bothered with technical questions specific to Ethereum or the EIP. Please direct all comments to the EIP editors. December 7, 2016: EIP 1 has been improved and will be placed as a PR. -February XX, 2016: EIP 1 has added editors, made draft improvements to process, and has merged with Master stream. + +February 1, 2016: EIP 1 has added editors, made draft improvements to process, and has merged with Master stream. [EIP5]: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-5.md [EIP101]: https://github.com/ethereum/EIPs/issues/28 @@ -254,4 +263,4 @@ February XX, 2016: EIP 1 has added editors, made draft improvements to process, [markdown]: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet [README.md]: README.md "wikilink" [Bitcoin's BIP-0001]: https://github.com/bitcoin/bips - [Python's PEP-0001]: https://www.python.org/dev/peps/ \ No newline at end of file + [Python's PEP-0001]: https://www.python.org/dev/peps/ From 83991ef5c3c912bc123a4c5aa79f3035a576d7f4 Mon Sep 17 00:00:00 2001 From: Souptacular Date: Wed, 1 Feb 2017 19:12:07 -0600 Subject: [PATCH 0025/1085] Updated templates --- ISSUE_TEMPLATE.md | 12 +++++++++++ PULL_REQUEST_TEMPLATE.md | 45 ++++++++++++++++++++++++++++++++++++++++ eip-X.md | 45 ++++++++++++++++++++++++++++++++++++++++ eip-X.mediawiki | 23 -------------------- 4 files changed, 102 insertions(+), 23 deletions(-) create mode 100644 ISSUE_TEMPLATE.md create mode 100644 PULL_REQUEST_TEMPLATE.md create mode 100644 eip-X.md delete mode 100644 eip-X.mediawiki diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000000..965ebcb18f74a --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,12 @@ + +ATTENTION! If you would like to submit an EIP and it has already been written as a draft (see the [template](https://github.com/ethereum/EIPs/blob/master/eip-X.md) for an example), please submit it as a [Pull Request](https://github.com/ethereum/EIPs/pulls). + +If you are considering a proposal but would like to get some feedback on the idea before submitting a draft, then continue opening an Issue as a thread for discussion. Note that the more clearly and completely you state your idea the higher the quality of the feedback you are likely to receive. + +Keep in mind the following guidelines from [EIP-1](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1.md): + +> Each EIP must have a champion - someone who writes the EIP using the style and format described below, shepherds the discussions in the appropriate forums, and attempts to build community consensus around the idea. The EIP champion (a.k.a. Author) should first attempt to ascertain whether the idea is EIP-able. Posting to the the Protocol Discussion forum or opening an Issue is the best way to go about this. + +> Vetting an idea publicly before going as far as writing a EIP is meant to save the potential author time. Asking the Ethereum community first if an idea is original helps prevent too much time being spent on something that is guaranteed to be rejected based on prior discussions (searching the Internet does not always do the trick). It also helps to make sure the idea is applicable to the entire community and not just the author. Just because an idea sounds good to the author does not mean it will work for most people in most areas where Ethereum is used. + +> Once the champion has asked the Ethereum community as to whether an idea has any chance of acceptance, a draft EIP should be presented as a Pull Request. This gives the author a chance to flesh out the draft EIP to make properly formatted, of high quality, and to address initial concerns about the proposal. \ No newline at end of file diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000000..b19e3814115f6 --- /dev/null +++ b/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,45 @@ +This is the suggested template for creating new EIPs. + +Note that an EIP number will be assigned by an editor. When opening a pull request to submit your EIP, use an abbreviated title in the filename, eip-draft_title_abbrev.md. + +## Preamble +
+  EIP: 
+  Title: 
+  Author: 
+  Type: 
+  Category(*only required for Standard Track):  
+  Status: Draft
+  Created: 
+  Requires (*optional): 
+  Replaces (*optional): 
+
+ +## Simple Summary +"If you can't explain it simply, you don't understand it well enough." Provide a simplified and layman-accessible explanation of the EIP. + +## Abstract +A short (~200 word) description of the technical issue being addressed. + +## Motivation +The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright. + +## Specification +The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (cpp-ethereum, go-ethereum, parity, ethereumj, ethereumjs, ...). + +## Rationale +The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion. + +## Backwards Compatibility +All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright. + +## Test Cases +Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable. + +## Implementation +The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details. + + +## Copyright +License: Apache 2.0 +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file diff --git a/eip-X.md b/eip-X.md new file mode 100644 index 0000000000000..b19e3814115f6 --- /dev/null +++ b/eip-X.md @@ -0,0 +1,45 @@ +This is the suggested template for creating new EIPs. + +Note that an EIP number will be assigned by an editor. When opening a pull request to submit your EIP, use an abbreviated title in the filename, eip-draft_title_abbrev.md. + +## Preamble +
+  EIP: 
+  Title: 
+  Author: 
+  Type: 
+  Category(*only required for Standard Track):  
+  Status: Draft
+  Created: 
+  Requires (*optional): 
+  Replaces (*optional): 
+
+ +## Simple Summary +"If you can't explain it simply, you don't understand it well enough." Provide a simplified and layman-accessible explanation of the EIP. + +## Abstract +A short (~200 word) description of the technical issue being addressed. + +## Motivation +The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright. + +## Specification +The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (cpp-ethereum, go-ethereum, parity, ethereumj, ethereumjs, ...). + +## Rationale +The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion. + +## Backwards Compatibility +All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright. + +## Test Cases +Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable. + +## Implementation +The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details. + + +## Copyright +License: Apache 2.0 +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file diff --git a/eip-X.mediawiki b/eip-X.mediawiki deleted file mode 100644 index 43d6ab37ddf64..0000000000000 --- a/eip-X.mediawiki +++ /dev/null @@ -1,23 +0,0 @@ -
-  EIP: 
-  Title: 
-  Author: 
-  Discussions-To: 
-  Status: 
-  Type: 
-  Created: 
-  Replaces: 
-  Superseded-By: 
-  Resolution: 
-
- -==Abstract== - -==Motivation== - -==Specification== - -==Rationale== - -==Implementation== - From cba98f1e3d7f417dec52879b18450f04fb75e9e9 Mon Sep 17 00:00:00 2001 From: Hudson Jameson Date: Wed, 1 Feb 2017 19:15:11 -0600 Subject: [PATCH 0026/1085] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7b3e445328446..651165ec570f4 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Ethereum Improvement Proposal. EIPs propose and describe changes made to Ethereu People wishing to submit EIPs first should propose their idea as an issue and then formalize it using a PR. After discussion it will be published here. Having an EIP here does not make it a formally accepted standard until its status becomes Active. For a EIP to become Active requires the mutual consent of the community. An EIP is not finalized until it has been implemented and is in use. Those proposing changes should consider that ultimately consent may rest with the consensus of the Ethereum users. # Contributing -First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP to it. There is a [template EIP here](eip-X.mediawiki). Then submit a Pull Request to Ethereum's [EIPs repository](https://github.com/ethereum/EIPs). +First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP to it. There is a [template EIP here](eip-X.md). Then submit a Pull Request to Ethereum's [EIPs repository](https://github.com/ethereum/EIPs). # Current EIPS | Number |Title | Author | Type | Layer | Status / Discussion | From 0edb65891fdda7988a009346295eeb9ff5a70bb7 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Thu, 2 Feb 2017 10:59:18 +0100 Subject: [PATCH 0027/1085] template touch-up --- eip-X.md | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/eip-X.md b/eip-X.md index b19e3814115f6..3ab783216dd8c 100644 --- a/eip-X.md +++ b/eip-X.md @@ -1,19 +1,19 @@ -This is the suggested template for creating new EIPs. +This is the suggested template for new EIPs. -Note that an EIP number will be assigned by an editor. When opening a pull request to submit your EIP, use an abbreviated title in the filename, eip-draft_title_abbrev.md. +Note that an EIP number will be assigned by an editor. When opening a pull request to submit your EIP, please use an abbreviated title in the filename, `eip-draft_title_abbrev.md`. ## Preamble -
-  EIP: 
-  Title: 
-  Author: 
-  Type: 
-  Category(*only required for Standard Track):  
-  Status: Draft
-  Created: 
-  Requires (*optional): 
-  Replaces (*optional): 
-
+ + EIP: + Title: + Author: + Type: + Category (*only required for Standard Track): + Status: Draft + Created: + Requires (*optional): + Replaces (*optional): + ## Simple Summary "If you can't explain it simply, you don't understand it well enough." Provide a simplified and layman-accessible explanation of the EIP. @@ -39,7 +39,5 @@ Test cases for an implementation are mandatory for EIPs that are affecting conse ## Implementation The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details. - ## Copyright -License: Apache 2.0 -Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From a8b8bb058aa6d931b9627d652cf72b19eb884887 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Thu, 2 Feb 2017 21:40:02 +0100 Subject: [PATCH 0028/1085] touch up template --- PULL_REQUEST_TEMPLATE.md | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index b19e3814115f6..3ab783216dd8c 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -1,19 +1,19 @@ -This is the suggested template for creating new EIPs. +This is the suggested template for new EIPs. -Note that an EIP number will be assigned by an editor. When opening a pull request to submit your EIP, use an abbreviated title in the filename, eip-draft_title_abbrev.md. +Note that an EIP number will be assigned by an editor. When opening a pull request to submit your EIP, please use an abbreviated title in the filename, `eip-draft_title_abbrev.md`. ## Preamble -
-  EIP: 
-  Title: 
-  Author: 
-  Type: 
-  Category(*only required for Standard Track):  
-  Status: Draft
-  Created: 
-  Requires (*optional): 
-  Replaces (*optional): 
-
+ + EIP: + Title: + Author: + Type: + Category (*only required for Standard Track): + Status: Draft + Created: + Requires (*optional): + Replaces (*optional): + ## Simple Summary "If you can't explain it simply, you don't understand it well enough." Provide a simplified and layman-accessible explanation of the EIP. @@ -39,7 +39,5 @@ Test cases for an implementation are mandatory for EIPs that are affecting conse ## Implementation The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details. - ## Copyright -License: Apache 2.0 -Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 69f8ef20c6079bdbd97d64d96709d0ab16448829 Mon Sep 17 00:00:00 2001 From: Nick Savers Date: Thu, 2 Feb 2017 22:40:34 +0100 Subject: [PATCH 0029/1085] Remove some redundant slashes --- EIPS/eip-1.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index 332b9a3afc879..ffe1b5c05d1c6 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -167,7 +167,7 @@ EIPs may include auxiliary files such as diagrams. Such files must be named EIP- Transferring EIP Ownership -------------------------- -It occasionally becomes necessary to transfer ownership of EIPs to a new champion. In general, we'd like to retain the original author as a co-author of the transferred EIP, but that\'s really up to the original author. A good reason to transfer ownership is because the original author no longer has the time or interest in updating it or following through with the EIP process, or has fallen off the face of the 'net (i.e. is unreachable or not responding to email). A bad reason to transfer ownership is because you don't agree with the direction of the EIP. We try to build consensus around a EIP, but if that\'s not possible, you can always submit a competing EIP. +It occasionally becomes necessary to transfer ownership of EIPs to a new champion. In general, we'd like to retain the original author as a co-author of the transferred EIP, but that's really up to the original author. A good reason to transfer ownership is because the original author no longer has the time or interest in updating it or following through with the EIP process, or has fallen off the face of the 'net (i.e. is unreachable or not responding to email). A bad reason to transfer ownership is because you don't agree with the direction of the EIP. We try to build consensus around a EIP, but if that's not possible, you can always submit a competing EIP. If you are interested in assuming ownership of a EIP, send a message asking to take over, addressed to both the original author and the EIP editor. If the original author doesn't respond to email in a timely manner, the EIP editor will make a unilateral decision (it's not like such decisions can't be reversed :). @@ -199,11 +199,11 @@ EIP Editor Responsibilities and Workflow For each new EIP that comes in, an editor does the following: -- Read the EIP to check if it is ready: sound and complete. The ideas must make technical sense, even if they don\'t seem likely to be accepted. +- Read the EIP to check if it is ready: sound and complete. The ideas must make technical sense, even if they don't seem likely to be accepted. - The title should accurately describe the content. - Edit the EIP for language (spelling, grammar, sentence structure, etc.), markup (Github flavored Markdown), code style -If the EIP isn\'t ready, the editor will send it back to the author for revision, with specific instructions. +If the EIP isn't ready, the editor will send it back to the author for revision, with specific instructions. Once the EIP is ready for the repository, the EIP editor will: From 4149e6de8d2b3107336677f0120cc7e354ca2ada Mon Sep 17 00:00:00 2001 From: Piper Merriam Date: Thu, 2 Feb 2017 15:02:12 -0700 Subject: [PATCH 0030/1085] Add EIP190 for ERC190 Smart Contract Packaging Standard --- EIPS/eip-190.md | 102 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 EIPS/eip-190.md diff --git a/EIPS/eip-190.md b/EIPS/eip-190.md new file mode 100644 index 0000000000000..45a2263ecfd07 --- /dev/null +++ b/EIPS/eip-190.md @@ -0,0 +1,102 @@ +``` +EIP: Draft +Title: Ethereum Smart Contract Packaging Standard +Authors: Piper Merriam, Tim Coulter, Denis Erfurt (mhhf), RJ Catalano (VoR0220), Iuri Matias (iurimatias) +Status: Draft +Type: Standards Track - ERC +Created: 2017-01-10 +``` + +# Abstract + +This ERC proposes a specification for Ethereum smart contract packages. + +The specification was collaboratively developed by the following Ethereum development framework maintainers. + +* Tim Coulter (Truffle) +* Denis Erfurt (Dapple) +* Piper Merriam (Populus) +* RJ Catalano (Eris PM) +* Iuri Matias (Embark) + +# Motivation + +Packaging is a core piece of modern software development which is missing from the Ethereum ecosystem. The lack of packaging limits the ability for developers to reuse code which negatively affects productivity and security. + +A key example of this is the ERC20 standard. There are a few well audited reusable token contracts available but most developers end up writing their own because of the difficulty in finding and reusing existing code. + +A packaging standard should have the following positive effects on the ecosystem: + +* Greater overall productivity caused by the ability to reuse existing code. +* Increased security caused by the ability to reuse existing well audited implementations of common patterns (ERC20, crowdfunding, etc). + +Smart contract packaging should also have a direct positive effect on the end user. Wallet software will be able to consume a released package and generate an interface for interacting with any deployed contracts included within that package. With the advent of [ENS](https://github.com/ethereum/EIPs/issues/137) all of the pieces will be in place for a wallet to take a human readable name and present the user with an interface for interacting with the underlying application. + + +# Specification + +The full specification for this standard is maintained separately in the repository [epm/epm-spec](https://github.com/ethpm/epm-spec). + +This EIP refers to the `1.0.0` version of the specification: [https://github.com/ethpm/epm-spec/tree/v1.0.0](https://github.com/ethpm/epm-spec/tree/v1.0.0) + +The specification contains details for a single document referred to as a *"Release Lockfile"*. + +* Release Lockfile Specification: [https://github.com/ethpm/epm-spec/blob/v1.0.0/release-lockfile.spec.md](https://github.com/ethpm/epm-spec/blob/v1.0.0/release-lockfile.spec.md). +* JSON Schema for Release Lockfile: [https://github.com/ethpm/epm-spec/blob/v1.0.0/spec/release-lockfile.spec.json](https://github.com/ethpm/epm-spec/blob/v1.0.0/spec/release-lockfile.spec.json) + +> These documents have not been inlined into this ERC to ensure that there is a single source of truth for the specification. + + +# Rationale + +## Use Cases + +This specification covers the following types of smart contract packages. + +1. Packages with contracts intended to be used as base contract such as the common `owned` pattern. +2. Packages with contracts that are ready to use as-is such as an ERC20 token contract. +3. Packages with deployed contracts such as libraries or services. + +Full explanations and examples of these use cases can be found in the [`README.md`](https://github.com/ethpm/epm-spec/blob/v1.0.0/README.md#use-cases) from the `epm/epm-spec` repository. + + +## Package Managers + +The *Release Lockfile* is intended for consumption by package management software. Specific care was made to ensure that all of the following functionality can be implemented by package managers. + + +### Deterministic builds + +Ensures that a package will always resolve to the same set of dependencies and source files. Both source files and dependencies are content addressed to ensure that the referenced resources cannot change. + + +### Bytecode verification + +Contains the appropriate information for a package manager to inspect a deployed contract and verify that it's bytecode matches the bytecode that results from compilation and linking of the package source code. + + +### Multi-chain deploys + +Supports deployments across multiple chains, allowing a package to define addresses on both the public mainnet and testnet. + + +### Trusted packages + +Allows for packages which exclude source code or other elements which would be needed for verification of the contract bytecode. This allows for minimalistic packages to be created for special situations where the package manager will not be performing verification. + + +# Implementation + +Implementations are implemented in the following frameworks. + +* [Truffle](http://truffleframework.com/) +* [Populus](http://populus.readthedocs.io/en/latest/) + +Implementations are underway for the following frameworks. + +* [Dapple](http://dapple.readthedocs.io/en/master/) +* [Eris PM](https://github.com/eris-ltd/eris-cli) + +Implementation has not yet begun in the following frameworks but is on the roadmap. + +* [Embark](https://github.com/iurimatias/embark-framework) From 837d368dec6b5e8b6465c3c0e5b60cf273b39a25 Mon Sep 17 00:00:00 2001 From: Piper Merriam Date: Thu, 2 Feb 2017 15:10:07 -0700 Subject: [PATCH 0031/1085] Rename file to include name of EIP --- EIPS/{eip-190.md => eip-190-smart-contract-packaging-standard.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename EIPS/{eip-190.md => eip-190-smart-contract-packaging-standard.md} (100%) diff --git a/EIPS/eip-190.md b/EIPS/eip-190-smart-contract-packaging-standard.md similarity index 100% rename from EIPS/eip-190.md rename to EIPS/eip-190-smart-contract-packaging-standard.md From f89902afa00b995f19d7e7b4e2e8f01927851039 Mon Sep 17 00:00:00 2001 From: Phistr90 Date: Sun, 5 Feb 2017 23:52:29 +0100 Subject: [PATCH 0032/1085] Update eip-1.md remove duplicate section --- EIPS/eip-1.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index ffe1b5c05d1c6..07cd72ec68200 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -97,10 +97,6 @@ Each EIP should have the following parts: -- Backwards Compatibility - All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright. - - - - Test Cases - Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable. From d626ba0f07d0c542007198556ac30c8bd4c8312c Mon Sep 17 00:00:00 2001 From: Hudson Jameson Date: Sun, 5 Feb 2017 23:16:03 -0600 Subject: [PATCH 0033/1085] Made Motivation Optional --- PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 3ab783216dd8c..3fd989dc3cdd7 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -21,7 +21,7 @@ Note that an EIP number will be assigned by an editor. When opening a pull reque ## Abstract A short (~200 word) description of the technical issue being addressed. -## Motivation +## Motivation (*optional) The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright. ## Specification From 74630002987f84695140306ba49b709d90852adf Mon Sep 17 00:00:00 2001 From: Hudson Jameson Date: Sun, 5 Feb 2017 23:18:19 -0600 Subject: [PATCH 0034/1085] Added optional to motivation --- EIPS/eip-1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index 07cd72ec68200..3661248aa4cb1 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -81,7 +81,7 @@ Each EIP should have the following parts: -- Motivation - The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright. +- Motivation (*optional) - The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright. From 92529c516ab15f7bb988308d8e360013be0ee837 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Mon, 6 Feb 2017 09:27:10 -0800 Subject: [PATCH 0035/1085] pull request template not EIP template --- PULL_REQUEST_TEMPLATE.md | 44 +--------------------------------------- 1 file changed, 1 insertion(+), 43 deletions(-) diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 3fd989dc3cdd7..bd8aea3067bab 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -1,43 +1 @@ -This is the suggested template for new EIPs. - -Note that an EIP number will be assigned by an editor. When opening a pull request to submit your EIP, please use an abbreviated title in the filename, `eip-draft_title_abbrev.md`. - -## Preamble - - EIP: - Title: - Author: - Type: - Category (*only required for Standard Track): - Status: Draft - Created: - Requires (*optional): - Replaces (*optional): - - -## Simple Summary -"If you can't explain it simply, you don't understand it well enough." Provide a simplified and layman-accessible explanation of the EIP. - -## Abstract -A short (~200 word) description of the technical issue being addressed. - -## Motivation (*optional) -The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright. - -## Specification -The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (cpp-ethereum, go-ethereum, parity, ethereumj, ethereumjs, ...). - -## Rationale -The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion. - -## Backwards Compatibility -All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright. - -## Test Cases -Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable. - -## Implementation -The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details. - -## Copyright -Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). +When opening a pull request to submit a new EIP, please use the suggested template: https://github.com/ethereum/EIPs/blob/master/eip-X.md From 237f16343f55ecc9ad4061278192236d83b949c6 Mon Sep 17 00:00:00 2001 From: vbuterin Date: Sat, 11 Feb 2017 05:35:33 -0500 Subject: [PATCH 0036/1085] Blockhash refactoring light client protocol Provides a description and benchmarks for an improved light client protocol post-blockhash refactoring. --- EIPS/new_light_client_protocol.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 EIPS/new_light_client_protocol.md diff --git a/EIPS/new_light_client_protocol.md b/EIPS/new_light_client_protocol.md new file mode 100644 index 0000000000000..81d1f7aab51bb --- /dev/null +++ b/EIPS/new_light_client_protocol.md @@ -0,0 +1,28 @@ + +### Summary + +The [blockhash refactoring EIP](http://github.com/ethereum/EIPs/pull/210) allows blocks to directly link to blocks much older than themselves, making all blocks in the chain relatively tightly connected to each other. This allows for very efficient light client proofs that do not require light clients to verify an entire header chain; instead, light clients can verify a subchain containing "key blocks" whose ethash mining result hits an especially low target, and gain a probabilistic assurance that the longest chain contains these key blocks. + +### Proof format + +We can define a "probabilistic total-difficulty proof" as an RLP list as follows: + + [header1, proof1, header2, proof2, ...] + +Where each header is a block header, and each proof[i] is a Merkle branch from header[i] to the hash of header[i + 1]. More formally, the proof is an RLP list where each element contains as a substring the hash of the next element, and the last element is the hash of the next header; the elements are taken from the branch of the state tree in header[i] that points to the hash of header[i + 1] that is available in the storage of the BLOCKHASH_CONTRACT_ADDR. + +The proof serves to verify that the headers are linked to each other in the given order, and that the given chain has an approximate total difficulty equal to `sum(2 ** 256 / mining_result[i])` where `mining_result[i]` is the result of running the ethash verification function on the given header. A node producing a proof will take case to create a proof that contains as many low-mining-result blocks as possible; a specific algorithm would be to look for all "key blocks" whose mining result is less than 1/50000 of maximum for a valid block allowed by the most recent block difficulty, and then if these blocks do not have a direct connection because they are not an even multiple of 256 or 65536 apart, it would find "glue blocks" to link between them; for example, linking 3904322 to 3712498 might go through 3735552 (multiple of 65536, directly linked in 3904322) and 3712512 (multiple of 256, directly linked in 3735552), and finally 3712512 links directly to 3712498. + +### Light client algorithm + +Suppose that a light client receives a proof as above. The light client can try to answer this question: suppose that there is an attacker with the same amount of hashpower as the main chain. Given some probability threshold p (say, 1 in 1 million), how many blocks would the main chain be able to grow with probability 1-p in the same amount of time that the attacker makes their proof? + +For example, let's suppose that we have a proof 8 blocks long, with mining results `[8937, 3047, 2601, 1612, 273, 3278, 1220, 1942]` (in a real-world example, all of these numbers would of course be very large values somewhere around 2**200). We can set up a thought experiment where an attacker and the "main chain" create blocks in parallel; the question asked is, what is the number TD such that while the main chain creates a number of blocks with the given total difficulty TD, the attacker can come up with at least 8 blocks with mining result less than or equal to 8937? The answer comes from the Poisson distribution's cumulative distribution function formula; the answer is, enough TD to create 81 blocks of mining result less than 1 million. Note that this carries high inefficiency: the simulation that actually gave that output involved 800 blocks of mining result less than 1 million. We can alleviate this problem by choosing a higher proof length, say 56; this would get us to the point where we cross the threshold at N = 400. + +Now, we can get to our algorithm. A light client starts off knowing the genesis, and asks for probabilistic total-difficulty proofs. It stores a map `height_diffs: {(block_hash_from, block_hash_to): min length}`, which starts off as `{genesis: 0}`. When it receives a proof, it sets `height_diffs[(LAST_BLOCK, FIRST_BLOCK)] = max(height_diffs[(LAST_BLOCK, FIRST_BLOCK)], min_length(PROOF))`, where `min_length` is a function that computes the min length as above. Then, at any point the algorithm can find a min-height of any given block by applying any pathfinding algorithm ([Bellman-Ford](https://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm) is ideal) to get the total min-length from the genesis to that block. The block with the highest min-height is taken to be the head. + +Note that it is expected that proofs for the portion of the chain further back in the tail will be more "rarefied", including only perhaps one block per 20000 heights, but closer to the head the proofs will become "tighter", as there will be fewer blocks between the start of the proof and the head, and so the distance between successive blocks would need to be smaller for the proof to still contain enough blocks to have a reasonably high min-length. Once a client asks for proofs starting from a header that is less than ~250 blocks from the head, it may become reasonable to simply give it the entire sub-chain, ie. `[header[n], header[n+1], ... , header[n + 250]]`; the light client can interpret a sub-chain as a proof with a min-length that is simply equal to the total difficulty of the sub-chain. + +### Estimated complexity + +Suppose that there are 1 million blocks between the genesis (actually, we can use the Metropolis hardfork block as a "genesis", as this algorithm does not work before the hard fork anyway) and the head. Suppose that a client wants to be secure against attackers with up to half the hashpower of the main network with p = 0.999999. Then, the client would want to ensure that *any* subchain from the genesis to the head has a min-length of at least half its claimed length. We already roughly know from above that it takes 64 headers to get to that level. As an approximation, the client can ask for such a subchain for blocks 0....500000, then 500000...750000, and so forth. At 999750, it can stop, and simply take 250 block headers. In total, this would entail 12 proofs (768 headers), plus 768 Merkle branches, plus another 250 headers. A branch on average takes ~1000 bytes, a header takes ~500 bytes, so this would be ~1.27 MB, and would require 1018 ethash verifications from 30 epochs (so an additional 30 cache generations). From c1f45f8b4caa4e12716863943a473dc4bdd6ec23 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 13 Feb 2017 12:07:09 +0100 Subject: [PATCH 0037/1085] Propose RETURNDATACOPY and RETURNDATASIZE. --- EIPS/returndatacopy.md | 61 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 EIPS/returndatacopy.md diff --git a/EIPS/returndatacopy.md b/EIPS/returndatacopy.md new file mode 100644 index 0000000000000..2d4c7e8d0d55a --- /dev/null +++ b/EIPS/returndatacopy.md @@ -0,0 +1,61 @@ +## Preamble + + EIP: + Title: New opcodes: RETURNDATASIZE and RETURNDATACOPY + Author: Christian Reitwiessner + Type: Standard Track + Category Core + Status: Draft + Created: 2017-02-13 + Requires: + Replaces: 5/8 + + +## Simple Summary + +A mechanism to allow returning arbitrary-length data inside the EVM has been requested for quite a while now. Existing proposals always had very intricate problems associated with charging gas. This proposal solves the same problem while at the same time, it has a very simple gas charging mechanism and reqires minimal changes to the call opcodes. Its workings are very similar to the way calldata is handled already: After a call, return data is kept inside a virtual buffer from which the caller can copy it (or parts thereof) into memory. At the next call, the buffer is overwritten. This mechanism is 100% backwards compatible. + +## Abstract + +Please see summary. + +## Motivation + +In some situations, it is vital for a function to be able to return data whose length cannot be anticipated before the call. In principle, this can be solved without alterations to the EVM, for example by splitting the call into two calls where the first is used to compute only the size. All of these mechanisms, though, are very expensive in at least some situations. A very useful example of such a worst-case situation is a generic forwarding contract: A contract that takes call data, potentially makes some checks and then forwards it as is to another contract. The return data should of course be transferred in a similar way to the original caller. Since the contract is generic and does not know about the contract it calls, there is no way to determine the size of the output without adapting the called contract accordingly or trying a logarithmic number of calls. + +Compiler implementors are advised to reserve a zero-length area for return data if the size of the return data is unknown before the call and then use `RETURNDATACOPY` in conjunction with `RETURNDATASIZE` to actually retrieve the data. + +Note that this proposal also makes the EIP that proposes to allow to return data in case of an intentional state reversion (EIP [206](https://github.com/ethereum/EIPs/pull/206)) much more useful. Since the size of the failure data might be larger than the regular return data (or even unknown), it is possible to retrieve the failure data after the CALL opcode has signalled a failure, even if the regular output area is not large enough to hold the data. + +## Specification + +Add two new opcodes: + +`RETURNDATASIZE`: `0xd` + +Pushes the size of the return data (or the failure return data, see EIP [206](https://github.com/ethereum/EIPs/pull/206)) of the previous call onto the stack. If there was no previous call, pushes zero. +Gas costs: 2 (same as `CALLDATASIZE`) + +`RETURNDATACOPY`: `0xe` + +This opcode has similar semantics to `CALLDATACOPY`, but instead of copying data from the call data, it copies data from the return data of the previous call. If the return data is accessed beyond its length, it is considered to be filled with zeros. If there was no previous call, copies zeros. +Gas costs: `3 + 3 * ceil(amount / 32)` (same as `CALLDATACOPY`) + +## Rationale + +Other solutions that would allow returning dynamic data were considered, but they all had to deduct the gas from the call opcode and thus were both complicated to implement and specify ([5/8](https://github.com/ethereum/EIPs/issues/8)). Since this proposal is very similar to the way calldata is handled, it fits nicely into the concept. Furthermore, the eWASM architecture already handles return data in exactly the same way. + +Note that the EVM implementation needs to keep the return data until the next call or the return from the current call. Since this resource was already paid for as part of the memory of the callee, it should not be a problem. Implementations may either choose to keep the full memory of the callee alive until the next call or copy only the return data to a special memory area. + +The number values of the opcodes were allocated in the same nibble block that also contains `CALLDATASIZE` and `CALLDATACOPY`. + +## Backwards Compatibility + +This proposal introduces two new opcodes and stays fully backwards compatible apart from that. + +## Test Cases + +## Implementation + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 7eb99d236dfff497794b2f5b94e32c8928e4dbfc Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 13 Feb 2017 14:34:52 +0100 Subject: [PATCH 0038/1085] Precompiled contract for pairing check. --- EIPS/pairings.md | 130 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 EIPS/pairings.md diff --git a/EIPS/pairings.md b/EIPS/pairings.md new file mode 100644 index 0000000000000..4b85c06a7f987 --- /dev/null +++ b/EIPS/pairings.md @@ -0,0 +1,130 @@ +## Preamble +
+  EIP: to be assigned
+  Title: Precompiled contracts for optimal ate pairing check
+         on the elliptic curve alt_bn128
+  Author: Vitalik Buterin <vitalik@ethereum.org>, Christian Reitwiessner <chris@ethereum.org>
+  Type: Standard Track
+  Category(*only required for Standard Track): Core
+  Status: Draft
+  Created: 2017-02-06
+
+ +## Simple Summary + +Precompiled contracts for elliptic curve pairing operations are required in order to perform zkSNARK verification within the block gas limit. + +## Abstract + +This EIP suggests to add precompiled contracts for a pairing function on a specific pairing-friendly elliptic curve. This can in turn be combined with https://github.com/ethereum/EIPs/issues/196 to verify zkSNARKs in Ethereum smart contracts. The general benefit of zkSNARKs for Ethereum is that it will increase the privacy for users (because of the Zero-Knowledge property) and might also be a scalability solution (because of the succinctness and efficient verifiability property). + +## Motivation + +Current smart contract executions on Ethereum are fully transparent, which makes them unsuitable for several use-cases that involve private information like the location, identity or history of past transactions. The technology of zkSNARKs could be a solution to this problem. While the Ethereum Virtual Machine can make use of zkSNARKs in theory, they are currently too expensive +to fit the block gas limit. Because of that, this EIP proposes to specify certain parameters for some elementary primitives that enable zkSNARKs so that they can be implemented more efficiently and the gas cost be reduced. + +Note that fixing these parameters will in no way limit the use-cases for zkSNARKs, it will even allow for incorporating some advances in zkSNARK research without the need for a further hard fork. + +Pairing functions can be used to perform a limited form of multiplicatively homomorphic operations, which are necessary for current zkSNARKs. This precompile can be used to run such computations within the block gas limit. This precompiled contract only specifies a certain check, and not an evaluation of a pairing function. The reason is that the codomain of a pairing function is a rather complex field which could provide encoding problems and all known uses of pairing function in zkSNARKs only require the specified check. + +## Specification + +Add a precompiled contracts for a bilinear function on groups on the elliptic curve "alt_bn128". We will define the precompiled contract in terms of a discrete logarithm. The discrete logarithm is of course assumed to be hard to compute, but we will give an equivalent specification that makes use of elliptic curve pairing functions which can be efficiently computed below. + +Address: 0x8 + +For a cyclic group `G` (written additively) of prime order q let `log_P: G -> F_q` be the discrete logarithm on this group with respect to a generator `P`, i.e. `log_P(x)` is the integer `n` such that `n * P = x`. + +The precompiled contract is defined as follows, where the two groups `G_1` and `G_2` and their generators `P_1` and `P_2` are defined below: + +``` +Input: (a1, b1, a2, b2, ..., ak, bk) from (G_1 x G_2)^k +Output: If the length of the input is incorrect or any of the inputs are not elements of + the respective group or are not encoded correctly, the call fails. + Otherwise, return one if + log_P1(a1) * log_P2(b1) + ... + log_P1(ak) * log_P2(bk) = 0 + and zero else. +``` + +### Definition of the groups + +The groups `G_1` and `G_1` are cyclic groups on the elliptic curve `alt_bn128` defined by the curve equation +`Y^2 = X^3 + 3`. + +The group `G_1` is a cyclic group of prime order on the above curve over the field `F_p` with `p = 21888242871839275222246405745257275088696311157297823662689037894645226208583` with generator `P1 = (1, 2)`. + +The group `G_2` is a cyclic group of prime order in the same elliptic curve over a different field `F_p^2 = F_p[X] / (X^2 + 1)` (p is the same as above) with generator +``` +P2 = ( + 11559732032986387107991004021392285783925812861821192530917403151452391805634 * i + + 10857046999023057135944570762232829481370756359578518086990519993285655852781, + 4082367875863433681332203403145435568316851327593401208105741076214120093531 * i + + 8495653923123431417604973247489272438418190587263600148770280649306958101930 +) +``` + + +### Encoding + +Elements of `F_p` are encoded as 32 byte big-endian numbers. An encoding value of `p` or larger is invalid. + +Elements `a * i + b` of `F_p^2` are encoded as two elements of `F_p`, `(a, b)`. + +Elliptic curve points are encoded as a Jacobian pair `(X, Y)` where the point at infinity is encoded as `(0, 0)`. + +Note that the number `k` is derived from the input length. + +The length of the returned data is always exactly 32 bytes and encoded as a 32 byte big-endian number. + +### Gas costs + +To be determined. + +## Rationale + +The specific curve `alt_bn128` was chosen because it is particularly well-suited for zkSNARKs, or, more specifically their verification building block of pairing functions. Furthermore, by choosing this curve, we can use synergy effects with ZCash and re-use some of their components and artifacts. + +The feature of adding curve and field parameters to the inputs was considered but ultimately rejected since it complicates the specification: The gas costs are much harder to determine and it would be possible to call the contracts on something which is not an actual elliptic curve or does not admit an efficient pairing implementation. + +A non-compact point encoding was chosen since it still allows to perform some operations in the smart contract itself (inclusion of the full y coordinate) and two encoded points can be compared for equality (no third projective coordinate). + +The encoding of field elements in `F_p^2` was chosen in this order to be in line with the big endian encoding of the elements themselves. + +## Backwards Compatibility + +As with the introduction of any precompiled contract, contracts that already use the given addresses will change their semantics. Because of that, the addresses are taken from the "reserved range" below 256. + +## Test Cases + +To be written. + +## Implementation + +The precompiled contract can be implemented using elliptic curve pairing functions, more specifically, an optimal ate pairing on the alt_bn128 curve, which can be implemented efficiently. In order to see that, first note that a pairing function `e: G_1 x G_2 -> G_T` fulfills the following properties (`G_1` and `G_2` are written additively, `G_T` is written multiplicatively): + +(1) `e(m * P1, n * P2) = e(P1, P2)^(m * n)` +(2) `e` is non-degenerate + +Now observe that +``` +log_P1(a1) * log_P2(b1) + ... + log_P1(ak) * log_P2(bk) = 0 +``` +if and only if +``` +e(P1, P2)^(log_P1(a1) * log_P2(b1) + ... + log_P1(ak) * log_P2(bk)) = e(P1, P2) +``` + +Furthermore, the left hand side of this equation is equal to +``` +e(log_P1(a1) * P1, log_P2(b1) * P2) * ... * e(log_P1(ak) * P1, log_P2(bk) * P2) += e(a1, b1) * ... * e(ak, bk) +``` + +And thus, the precompiled contract can be implemented by verifying that +`e(a1, b1) * ... * e(ak, bk) = e(P1, P2)` + +Implementations are available here: + + - [libsnark](https://github.com/scipr-lab/libsnark/blob/master/src/algebra/curves/alt_bn128/alt_bn128_g1.hpp) (C++) + - [bn](https://github.com/zcash/bn/blob/master/src/groups/mod.rs) (Rust) + - [Python](https://github.com/ethereum/research/blob/master/zksnark/bn128_pairing.py) \ No newline at end of file From d8992d14840f8a521aadc21b563d3d539c1fa286 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 13 Feb 2017 14:37:55 +0100 Subject: [PATCH 0039/1085] Precompiled contracts for elliptic curve operations. --- EIPS/ecopts.md | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 EIPS/ecopts.md diff --git a/EIPS/ecopts.md b/EIPS/ecopts.md new file mode 100644 index 0000000000000..09884637fb29d --- /dev/null +++ b/EIPS/ecopts.md @@ -0,0 +1,91 @@ +## Preamble +
+  EIP: 
+  Title: Precompiled contracts for addition and scalar multiplication
+         on the elliptic curve alt_bn128
+  Author: Christian Reitwiessner
+  Type: Standard Track
+  Category: Core
+  Status: Draft
+  Created: 2017-02-02
+
+ +## Simple Summary + +Precompiled contracts for elliptic curve operations are required in order to perform zkSNARK verification within the block gas limit. + +## Abstract + +This EIP suggests to add precompiled contracts for addition and scalar multiplication on a specific pairing-friendly elliptic curve. This can in turn be combined with https://github.com/ethereum/EIPs/pull/212 to verify zkSNARKs in Ethereum smart contracts. The general benefit of zkSNARKs for Ethereum is that it will increase the privacy for users (because of the Zero-Knowledge property) and might also be a scalability solution (because of the succinctness and efficient verifiability property). + +## Motivation + +Current smart contract executions on Ethereum are fully transparent, which makes them unsuitable for several use-cases that involve private information like the location, identity or history of past transactions. The technology of zkSNARKs could be a solution to this problem. While the Ethereum Virtual Machine can make use of zkSNARKs in theory, they are currently too expensive +to fit the block gas limit. Because of that, this EIP proposes to specify certain parameters for some elementary primitives that enable zkSNARKs so that they can be implemented more efficiently and the gas cost be reduced. + +Note that fixing these parameters will in no way limit the use-cases for zkSNARKs, it will even allow for incorporating some advances in zkSNARK research without the need for a further hard fork. + +## Specification + +Add precompiled contracts for point addition (ADD) and scalar multiplication (MUL) on the elliptic curve "alt_bn128". + +Address of ADD: 0x6 +Address for MUL: 0x7 + +The curve is defined by: +``` +Y^2 = X^3 + 3 +over the field F_p with +p = 21888242871839275222246405745257275088696311157297823662689037894645226208583 +``` + +### Encoding + +Field elements are encoded as 32 byte big-endian numbers. Curve points are encoded as two field elements `(x, y)`, where the point at infinity is encoded as `(0, 0)`. + +For both precompiled contracts, if the input is shorter than expected, it is padded with zeros at the end. + +The length of the returned data is always as specified (i.e. it is not "unpadded"). + +### Exact semantics + +Invalid input: For both contracts, if any input point does not lie on the curve or any of the field elements (point coordinates or scalar) is equal or larger than the field modulus p, the contract fails. + +ADD: Input: two curve points `(x, y)`. Fail on invalid input. Otherwise, return the curve point `x + y` where `+` is point addition on the elliptic curve `alt_bn128` specified above. + +MUL: Input: curve point and scalar `(x, s)`. Fail on invalid input. Otherwise, return the cureve point `x * s`, where `*` is the scalar multiplication on the elliptic curve `alt_bn128` specified above. + +### Gas costs + +To be determined. + +## Rationale + +The specific curve `alt_bn128` was chosen because it is particularly well-suited for zkSNARKs, or, more specifically their verification building block of pairing functions. Furthermore, by choosing this curve, we can use synergy effects with ZCash and re-use some of their components and artifacts. + +The feature of adding curve and field parameters to the inputs was considered but ultimately rejected since it complicates the specification: The gas costs are much harder to determine and it would be possible to call the contracts on something which is not an actual elliptic curve. + +A non-compact point encoding was chosen since it still allows to perform some operations in the smart contract itself (inclusion of the full y coordinate) and two encoded points can be compared for equality (no third projective coordinate). + +## Backwards Compatibility + +As with the introduction of any precompiled contract, contracts that already use the given addresses will change their semantics. Because of that, the addresses are taken from the "reserved range" below 256. + +## Test Cases + +To be written. + +## Implementation + +Implementation of these primitives are available here: + + - [libsnark](https://github.com/scipr-lab/libsnark/blob/master/src/algebra/curves/alt_bn128/alt_bn128_g1.hpp) (C++) + - [bn](https://github.com/zcash/bn/blob/master/src/groups/mod.rs) (Rust) + +In both codebases, a specific group on the curve alt_bn128 is used and is called G1. + + - [Python](https://github.com/ethereum/research/blob/master/zksnark/bn128_curve.py) - probably most self-contained and best readable. + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file From d4a9172c7907f1788d61a58110be113650e258a3 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 13 Feb 2017 14:50:04 +0100 Subject: [PATCH 0040/1085] Add STATIC_CALL opcode. --- EIPS/static_call.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 EIPS/static_call.md diff --git a/EIPS/static_call.md b/EIPS/static_call.md new file mode 100644 index 0000000000000..7dd99bb8d4c4f --- /dev/null +++ b/EIPS/static_call.md @@ -0,0 +1,41 @@ +## Preamble +
+  EIP: to be assigned
+  Title: New opcode STATIC_CALL
+  Author: Vitalik Buterin <vitalik@ethereum.org>, Christian Reitwiessner <chris@ethereum.org>
+  Type: Standard Track
+  Category(*only required for Standard Track): Core
+  Status: Draft
+  Created: 2017-02-13
+
+ +## Simple Summary + +To increase smart contract security, this proposal adds a new opcode that can be used to call another contract (or itself) while disallowing any modifications to the state during the call (and its subcalls, if present). + +## Abstract + + +## Motivation + + +## Specification + +Opcode: `0xfa`. + +`STATIC_CALL` functions equivalently to a `CALL`, except it takes 6 arguments not including value, and calls the child with a `STATIC` flag on. Any calls, static or otherwise, made by an execution instance with a `STATIC` flag on will also have a `STATIC` flag on. Any attempts to make state-changing operations inside an execution instance with a `STATIC` flag on will instead throw an exception. These operations include nonzero-value calls, creates, `LOG` calls, `SSTORE`, `SSTOREBYTES` and `SUICIDE`. + +## Rationale + +This allows contracts to make calls that are clearly non-state-changing, reassuring developers and reviewers that re-entrancy bugs or other problems cannot possibly arise from that particular call; it is a pure function that returns an output and does nothing else. This may also make purely functional HLLs easier to implement. + +## Backwards Compatibility + +This proposal adds a new opcode but does not modify the behaviour of other opcodes and thus is backwards compatible for old contracts that do not use the new opcode. + +## Test Cases + +To be written. + +## Implementation + From 4bab8793ed119e445b6c9e69d9250bdede176bc7 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 13 Feb 2017 16:05:22 +0000 Subject: [PATCH 0041/1085] Draft of bitwise shifting opcodes --- EIPS/eip-draft_bitwise_shifts.md | 108 +++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 EIPS/eip-draft_bitwise_shifts.md diff --git a/EIPS/eip-draft_bitwise_shifts.md b/EIPS/eip-draft_bitwise_shifts.md new file mode 100644 index 0000000000000..0f42f9fc0a2c8 --- /dev/null +++ b/EIPS/eip-draft_bitwise_shifts.md @@ -0,0 +1,108 @@ +## Preamble + + EIP: + Title: Bitwise shifting instructions in EVM + Author: Alex Beregszaszi, Paweł Bylica + Type: Standard Track + Category Core + Status: Draft + Created: 2017-02-13 + + +## Simple Summary + +To provide native bitwise shifting with cost on par with other arithmetic operations. + +## Abstract + +Native bitwise shifting instructions are introduced, which are more efficient processing wise on the host and are cheaper to user by a contract. + +## Motivation + +EVM is lacking bitwise shifting operators, but supports other logical and arithmetic operators. Shift operations can be implemented via arithmetic operators, but that has a higher cost and requires more processing time from the host. Implementing `SHL` and `SHR` using arithmetics cost each 35 gas, while the proposed instructions take 3 gas. + +## Specification + +The following instructions are introduced: + +### `0x1b`: `SHL` (shift left) + +The `SHL` instruction (shift left) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the second popped value `arg2` shifted to the left by the number of bits in the first popped value `arg1`. The result is equal to + +``` +(arg2 * 2^arg1) mod 2^256 +``` + +Notes: +- If the shift amount is greater or equal 256 the result is 0. + +### `0x1c`: `SHR` (logical shift right) + +The `SHR` instruction (logical shift right) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the second popped value `arg2` shifted to the right by the number of bits in the first popped value `arg1` with zero fill. The result is equal to + +``` +arg2 udiv 2^arg1 +``` + +Notes: +- If the shift amount is greater or equal 256 the result is 0. + +### `0x1d`: `SAR` (arithmetic shift right) + +The `SAR` instruction (arithmetic shift right) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the second popped value `arg2` shifted to the right by the number of bits in the first popped value `arg1` with sign extension. The result is equal to + +``` +arg2 sdiv 2^arg1 +``` + +Notes: +- `arg1` is interpreted as unsigned number. +- If the shift amount is greater or equal 256 the result is 0 if `arg2` is non-negative or -1 if `arg2` is negative. + +### `0x1e`: `ROL` (rotate left) + +The `ROL` instruction (rotate left) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the second popped value `arg2` circular shifted to the left by the number of bits in the first popped value `arg1`. + +``` +(arg1 shl arg2) or (arg1 shr (256 - arg2) +``` + +Notes: +- `arg2 rol arg1` is equivalent of `arg2 rol (arg1 mod 2^256)` + +### `0x1f`: `ROR` (rotate right) + +The `ROL` instruction (rotate right) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the second popped value `arg2` circular shifted to the right by the number of bits in the first popped value `arg1`. + +``` +(arg1 shr arg2) or (arg1 shl (256 - arg2) +``` + +Notes: +- `arg2 ror arg1` is equivalent of `arg2 ror (arg1 mod 2^256)` + +The cost of the shift instructions is set at `verylow` tier (3 gas), while the rotations are 12 gas each. + +## Rationale + +Instruction operands were chosen to match the other logical and arithmetic instructions. + +## Backwards Compatibility + +The newly introduced instructions have no effect on bytecode created in the past. + +## Test Cases + +TBA + +## Implementation + +Client support: +TBA + +Compiler support: +- Solidity: https://github.com/ethereum/solidity/tree/asm-bitshift + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From bc6de05307869f9a49707bda500658d37ef94f30 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 14 Feb 2017 13:02:04 +0100 Subject: [PATCH 0042/1085] Update ecopts.md --- EIPS/ecopts.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/EIPS/ecopts.md b/EIPS/ecopts.md index 09884637fb29d..8a00763b445a1 100644 --- a/EIPS/ecopts.md +++ b/EIPS/ecopts.md @@ -41,7 +41,7 @@ p = 2188824287183927522224640574525727508869631115729782366268903789464522620858 ### Encoding -Field elements are encoded as 32 byte big-endian numbers. Curve points are encoded as two field elements `(x, y)`, where the point at infinity is encoded as `(0, 0)`. +Field elements and scalars are encoded as 32 byte big-endian numbers. Curve points are encoded as two field elements `(x, y)`, where the point at infinity is encoded as `(0, 0)`. For both precompiled contracts, if the input is shorter than expected, it is padded with zeros at the end. @@ -51,9 +51,15 @@ The length of the returned data is always as specified (i.e. it is not "unpadded Invalid input: For both contracts, if any input point does not lie on the curve or any of the field elements (point coordinates or scalar) is equal or larger than the field modulus p, the contract fails. -ADD: Input: two curve points `(x, y)`. Fail on invalid input. Otherwise, return the curve point `x + y` where `+` is point addition on the elliptic curve `alt_bn128` specified above. +#### ADD +Input: two curve points `(x, y)`. +Output: curve point `x + y`, where `+` is point addition on the elliptic curve `alt_bn128` specified above. +Fails on invalid input and consumes all gas provided. -MUL: Input: curve point and scalar `(x, s)`. Fail on invalid input. Otherwise, return the cureve point `x * s`, where `*` is the scalar multiplication on the elliptic curve `alt_bn128` specified above. +#### MUL +Input: curve point and scalar `(x, s)`. +Output: curve point `s * x`, where `*` is the scalar multiplication on the elliptic curve `alt_bn128` specified above. +Fails on invalid input and consumes all gas. ### Gas costs @@ -88,4 +94,4 @@ In both codebases, a specific group on the curve alt_bn128 is used and is called ## Copyright -Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 110f140cb8a7d589089ff08a242e2c56901f70af Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 14 Feb 2017 16:50:23 +0100 Subject: [PATCH 0043/1085] Typos and clarification. --- EIPS/pairings.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/EIPS/pairings.md b/EIPS/pairings.md index 4b85c06a7f987..af9dd05c20243 100644 --- a/EIPS/pairings.md +++ b/EIPS/pairings.md @@ -35,7 +35,7 @@ Address: 0x8 For a cyclic group `G` (written additively) of prime order q let `log_P: G -> F_q` be the discrete logarithm on this group with respect to a generator `P`, i.e. `log_P(x)` is the integer `n` such that `n * P = x`. -The precompiled contract is defined as follows, where the two groups `G_1` and `G_2` and their generators `P_1` and `P_2` are defined below: +The precompiled contract is defined as follows, where the two groups `G_1` and `G_2` and their generators `P_1` and `P_2` are defined below (they have the same order `q`): ``` Input: (a1, b1, a2, b2, ..., ak, bk) from (G_1 x G_2)^k @@ -43,17 +43,17 @@ Output: If the length of the input is incorrect or any of the inputs are not ele the respective group or are not encoded correctly, the call fails. Otherwise, return one if log_P1(a1) * log_P2(b1) + ... + log_P1(ak) * log_P2(bk) = 0 - and zero else. + (in F_q) and zero else. ``` ### Definition of the groups -The groups `G_1` and `G_1` are cyclic groups on the elliptic curve `alt_bn128` defined by the curve equation +The groups `G_1` and `G_2` are cyclic groups of prime order `q` on the elliptic curve `alt_bn128` defined by the curve equation `Y^2 = X^3 + 3`. -The group `G_1` is a cyclic group of prime order on the above curve over the field `F_p` with `p = 21888242871839275222246405745257275088696311157297823662689037894645226208583` with generator `P1 = (1, 2)`. +The group `G_1` is a cyclic group on the above curve over the field `F_p` with `p = 21888242871839275222246405745257275088696311157297823662689037894645226208583` with generator `P1 = (1, 2)`. -The group `G_2` is a cyclic group of prime order in the same elliptic curve over a different field `F_p^2 = F_p[X] / (X^2 + 1)` (p is the same as above) with generator +The group `G_2` is a cyclic group on the same elliptic curve over a different field `F_p^2 = F_p[X] / (X^2 + 1)` (p is the same as above) with generator ``` P2 = ( 11559732032986387107991004021392285783925812861821192530917403151452391805634 * i + @@ -127,4 +127,4 @@ Implementations are available here: - [libsnark](https://github.com/scipr-lab/libsnark/blob/master/src/algebra/curves/alt_bn128/alt_bn128_g1.hpp) (C++) - [bn](https://github.com/zcash/bn/blob/master/src/groups/mod.rs) (Rust) - - [Python](https://github.com/ethereum/research/blob/master/zksnark/bn128_pairing.py) \ No newline at end of file + - [Python](https://github.com/ethereum/research/blob/master/zksnark/bn128_pairing.py) From a4aa9806519ea24fc9b1ac2d04ba339fff7946ee Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 14 Feb 2017 16:52:24 +0100 Subject: [PATCH 0044/1085] Replace X by i. --- EIPS/pairings.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/pairings.md b/EIPS/pairings.md index af9dd05c20243..aa5f4541107a7 100644 --- a/EIPS/pairings.md +++ b/EIPS/pairings.md @@ -53,7 +53,7 @@ The groups `G_1` and `G_2` are cyclic groups of prime order `q` on the elliptic The group `G_1` is a cyclic group on the above curve over the field `F_p` with `p = 21888242871839275222246405745257275088696311157297823662689037894645226208583` with generator `P1 = (1, 2)`. -The group `G_2` is a cyclic group on the same elliptic curve over a different field `F_p^2 = F_p[X] / (X^2 + 1)` (p is the same as above) with generator +The group `G_2` is a cyclic group on the same elliptic curve over a different field `F_p^2 = F_p[i] / (i^2 + 1)` (p is the same as above) with generator ``` P2 = ( 11559732032986387107991004021392285783925812861821192530917403151452391805634 * i + From fdbf2abfea05e1809fff37bbb7d928786c500117 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 14 Feb 2017 17:00:01 +0100 Subject: [PATCH 0045/1085] Clarifications. --- EIPS/ecopts.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/EIPS/ecopts.md b/EIPS/ecopts.md index 8a00763b445a1..2433d5e28d656 100644 --- a/EIPS/ecopts.md +++ b/EIPS/ecopts.md @@ -23,7 +23,7 @@ This EIP suggests to add precompiled contracts for addition and scalar multiplic Current smart contract executions on Ethereum are fully transparent, which makes them unsuitable for several use-cases that involve private information like the location, identity or history of past transactions. The technology of zkSNARKs could be a solution to this problem. While the Ethereum Virtual Machine can make use of zkSNARKs in theory, they are currently too expensive to fit the block gas limit. Because of that, this EIP proposes to specify certain parameters for some elementary primitives that enable zkSNARKs so that they can be implemented more efficiently and the gas cost be reduced. -Note that fixing these parameters will in no way limit the use-cases for zkSNARKs, it will even allow for incorporating some advances in zkSNARK research without the need for a further hard fork. +Note that while fixing these parameters might look like limiting the use-cases for zkSNARKs, the primitives are so basic that they can be combined in ways that are flexible enough so that it should even be possible to allow future advances in zkSNARK research without the need for a further hard fork. ## Specification @@ -43,7 +43,9 @@ p = 2188824287183927522224640574525727508869631115729782366268903789464522620858 Field elements and scalars are encoded as 32 byte big-endian numbers. Curve points are encoded as two field elements `(x, y)`, where the point at infinity is encoded as `(0, 0)`. -For both precompiled contracts, if the input is shorter than expected, it is padded with zeros at the end. +Tuples of objects are encoded as their concatenation. + +For both precompiled contracts, if the input is shorter than expected, it is assumed to be virtually padded with zeros at the end (i.e. compatible with the semantics of the `CALLDATALOAD` opcode). The length of the returned data is always as specified (i.e. it is not "unpadded"). From 9ce36b3b65360515d29938cc3047f03fdf3a01b0 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 14 Feb 2017 17:06:41 +0100 Subject: [PATCH 0046/1085] Clarify k == 0 --- EIPS/pairings.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/EIPS/pairings.md b/EIPS/pairings.md index aa5f4541107a7..302ee245b5b0e 100644 --- a/EIPS/pairings.md +++ b/EIPS/pairings.md @@ -5,7 +5,7 @@ on the elliptic curve alt_bn128 Author: Vitalik Buterin <vitalik@ethereum.org>, Christian Reitwiessner <chris@ethereum.org> Type: Standard Track - Category(*only required for Standard Track): Core + Category: Core Status: Draft Created: 2017-02-06 @@ -46,6 +46,8 @@ Output: If the length of the input is incorrect or any of the inputs are not ele (in F_q) and zero else. ``` +Note that k is determined from the length of the input. k == 0 is valid and results in returning one. + ### Definition of the groups The groups `G_1` and `G_2` are cyclic groups of prime order `q` on the elliptic curve `alt_bn128` defined by the curve equation From 888bb039ee6ae12bd389350941985c3b7dd4091e Mon Sep 17 00:00:00 2001 From: Piper Merriam Date: Tue, 14 Feb 2017 09:30:26 -0700 Subject: [PATCH 0047/1085] update PR for feedback --- ...p-190-smart-contract-packaging-standard.md | 27 +++++++------------ 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/EIPS/eip-190-smart-contract-packaging-standard.md b/EIPS/eip-190-smart-contract-packaging-standard.md index 45a2263ecfd07..7abdc30d669b0 100644 --- a/EIPS/eip-190-smart-contract-packaging-standard.md +++ b/EIPS/eip-190-smart-contract-packaging-standard.md @@ -47,9 +47,7 @@ The specification contains details for a single document referred to as a *"Rele > These documents have not been inlined into this ERC to ensure that there is a single source of truth for the specification. -# Rationale - -## Use Cases +# Use Cases This specification covers the following types of smart contract packages. @@ -60,43 +58,38 @@ This specification covers the following types of smart contract packages. Full explanations and examples of these use cases can be found in the [`README.md`](https://github.com/ethpm/epm-spec/blob/v1.0.0/README.md#use-cases) from the `epm/epm-spec` repository. -## Package Managers +# Package Managers The *Release Lockfile* is intended for consumption by package management software. Specific care was made to ensure that all of the following functionality can be implemented by package managers. -### Deterministic builds +## Deterministic builds Ensures that a package will always resolve to the same set of dependencies and source files. Both source files and dependencies are content addressed to ensure that the referenced resources cannot change. -### Bytecode verification +## Bytecode verification -Contains the appropriate information for a package manager to inspect a deployed contract and verify that it's bytecode matches the bytecode that results from compilation and linking of the package source code. +Contains the appropriate information for a package manager to inspect a deployed contract and verify that its bytecode matches the bytecode that results from compilation and linking of the package source code. -### Multi-chain deploys +## Multi-chain deploys Supports deployments across multiple chains, allowing a package to define addresses on both the public mainnet and testnet. -### Trusted packages +## Trusted packages Allows for packages which exclude source code or other elements which would be needed for verification of the contract bytecode. This allows for minimalistic packages to be created for special situations where the package manager will not be performing verification. -# Implementation +# Framework support and integration -Implementations are implemented in the following frameworks. +Support for ERC190 is either implemented or in progress for the following: * [Truffle](http://truffleframework.com/) * [Populus](http://populus.readthedocs.io/en/latest/) - -Implementations are underway for the following frameworks. - * [Dapple](http://dapple.readthedocs.io/en/master/) * [Eris PM](https://github.com/eris-ltd/eris-cli) - -Implementation has not yet begun in the following frameworks but is on the roadmap. - * [Embark](https://github.com/iurimatias/embark-framework) +* [Browser Solidity](https://github.com/ethereum/browser-solidity/issues/386) From 0ed49ac9b4376541d0d37a13ef47c8e013af818d Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 14 Feb 2017 17:58:36 +0100 Subject: [PATCH 0048/1085] Updated preamble. --- EIPS/ecopts.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/EIPS/ecopts.md b/EIPS/ecopts.md index 2433d5e28d656..3ecd46a8153c4 100644 --- a/EIPS/ecopts.md +++ b/EIPS/ecopts.md @@ -1,14 +1,13 @@ ## Preamble -
-  EIP: 
-  Title: Precompiled contracts for addition and scalar multiplication
-         on the elliptic curve alt_bn128
-  Author: Christian Reitwiessner
-  Type: Standard Track
-  Category: Core
-  Status: Draft
-  Created: 2017-02-02
-
+ + EIP: + Title: Precompiled contracts for addition and scalar multiplication + on the elliptic curve alt_bn128 + Author: Christian Reitwiessner + Type: Standard Track + Category: Core + Status: Draft + Created: 2017-02-02 ## Simple Summary From 3ea17dce51056a88a882edaadd3a9cdbd3be3d53 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 14 Feb 2017 17:59:39 +0100 Subject: [PATCH 0049/1085] Updated preamble. --- EIPS/static_call.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/EIPS/static_call.md b/EIPS/static_call.md index 7dd99bb8d4c4f..677f85ee79c51 100644 --- a/EIPS/static_call.md +++ b/EIPS/static_call.md @@ -1,13 +1,12 @@ ## Preamble -
-  EIP: to be assigned
-  Title: New opcode STATIC_CALL
-  Author: Vitalik Buterin <vitalik@ethereum.org>, Christian Reitwiessner <chris@ethereum.org>
-  Type: Standard Track
-  Category(*only required for Standard Track): Core
-  Status: Draft
-  Created: 2017-02-13
-
+ + EIP: to be assigned + Title: New opcode STATIC_CALL + Author: Vitalik Buterin , Christian Reitwiessner ; + Type: Standard Track + Category: Core + Status: Draft + Created: 2017-02-13 ## Simple Summary From cf9f0e4133712e7c91a1312e87e1c5b3f01f638a Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 14 Feb 2017 18:00:22 +0100 Subject: [PATCH 0050/1085] Updated preamble. --- EIPS/pairings.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/EIPS/pairings.md b/EIPS/pairings.md index 302ee245b5b0e..9f8941168082c 100644 --- a/EIPS/pairings.md +++ b/EIPS/pairings.md @@ -1,14 +1,13 @@ ## Preamble -
-  EIP: to be assigned
-  Title: Precompiled contracts for optimal ate pairing check
-         on the elliptic curve alt_bn128
-  Author: Vitalik Buterin <vitalik@ethereum.org>, Christian Reitwiessner <chris@ethereum.org>
-  Type: Standard Track
-  Category: Core
-  Status: Draft
-  Created: 2017-02-06
-
+ + EIP: to be assigned + Title: Precompiled contracts for optimal ate pairing check + on the elliptic curve alt_bn128 + Author: Vitalik Buterin , Christian Reitwiessner + Type: Standard Track + Category: Core + Status: Draft + Created: 2017-02-06 ## Simple Summary From 8e09b0657a2bd78b7c6728e417759d049359c277 Mon Sep 17 00:00:00 2001 From: Greg Colvin Date: Tue, 21 Feb 2017 09:51:50 -0700 Subject: [PATCH 0051/1085] Update eip-184.md --- EIPS/eip-184.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-184.md b/EIPS/eip-184.md index 2e84e122e41ff..138338bce1b76 100644 --- a/EIPS/eip-184.md +++ b/EIPS/eip-184.md @@ -1,7 +1,7 @@ ``` EIP: 184 Title: Subroutines and Static Jumps for the EVM -Status: +Status: Draft Type: Core Author: Greg Colvin, Paweł Bylica, Christian Reitwiessner Created: 2016-12-10 From 70be22f5ecb40d0303906613e07b91ab895b9058 Mon Sep 17 00:00:00 2001 From: Souptacular Date: Tue, 21 Feb 2017 10:53:06 -0600 Subject: [PATCH 0052/1085] Deleted preEIPs folder. --- preEIPS/README.md | 1 - preEIPS/poc1.md | 406 --------------------------- preEIPS/poc3.md | 424 ----------------------------- preEIPS/poc4.md | 679 ---------------------------------------------- preEIPS/poc5.md | 125 --------- preEIPS/poc6.md | 92 ------- 6 files changed, 1727 deletions(-) delete mode 100644 preEIPS/README.md delete mode 100644 preEIPS/poc1.md delete mode 100644 preEIPS/poc3.md delete mode 100644 preEIPS/poc4.md delete mode 100644 preEIPS/poc5.md delete mode 100644 preEIPS/poc6.md diff --git a/preEIPS/README.md b/preEIPS/README.md deleted file mode 100644 index 6b45da17eaee0..0000000000000 --- a/preEIPS/README.md +++ /dev/null @@ -1 +0,0 @@ -This folder contains the early Proof of Concept iteration. It is incompelete. PoC 2, 7, 8 and 9 are missing. diff --git a/preEIPS/poc1.md b/preEIPS/poc1.md deleted file mode 100644 index 8922ba4bb075c..0000000000000 --- a/preEIPS/poc1.md +++ /dev/null @@ -1,406 +0,0 @@ -Testnet simplifications: - -1. Difficulty formula - -D(genesisblock) = 2^22 -D(block) = D(block.parent) + D(block.parent) / 1024 * (1 if block.timestamp < block.parent.timestamp + 42 else -1) - - -2. Fees - -All fees are burned - -{ poc-2: -txFee = 100x -x = 100000000000000 = 10^14 -blockReward = 1500000000000000000 = 1.5 * 10^18; -} - -{ poc-3: -stepFee = 1x  -dataFee = 20x -memoryFee = 5x -extroFee = 40x -cryptoFee = 20x -newContractFee = 100x -txFee = 100x -x = 100000000000000 = 10^14 -blockReward = 1500000000000000000 = 1.5 * 10^18; -} - - -3. Premine - -We should all put our ethereum addresses made with the pyethtool.py script at https://github.com/ethereum/website/blob/master/pyethtool/pyethtool.py below: - -Each address gets 2^200 units premined - -{ poc-2: -8a40bfaa73256b60764c1bf40675a99083efb075 (G) -93658b04240e4bd4046fd2d6d417d20f146f4b43 (J) -1e12515ce3e0f817a4ddef9ca55788a1d66bd2df (V) -80c01a26338f0d905e295fccb71fa9ea849ffa12 (A) -} -{ poc-3: -8a40bfaa73256b60764c1bf40675a99083efb075 (G) -e6716f9544a56c530d868e4bfbacb172315bdead (J) -1e12515ce3e0f817a4ddef9ca55788a1d66bd2df (V) -1a26338f0d905e295fccb71fa9ea849ffa12aaf4 (A) -} - - -4. PoW - -sha(sha(blockheader_without_nonce) ++ nonce) <= 2^256 / difficulty - -where: -nonce and all outputs from sha are byte arrays of length 32; -++ is the concatenation operator; -<= operands are treated as bytearrays in BE format. - - -5. Uncles - -Nodes should NOT attempt to collect any uncles, although uncles should be included in the reward calculation. - - -6. Block & transactions formats: - -Though RLP is data-agnostic, it does specify a canonical representation for integer quantities. It is big-endian with no leading zero-bytes. Thus for elements than feasibly can be stored as integers, it becomes important to specify whether they should adhere to this canonical representation or be left in some other (perhaps more 'native') format. - -In the case of counts, balances, fees and amounts of wei, the canon-integer form must be used when storing in RLP. We call these INTs. - -In the case of hashes (256-bit or 160-bit), user-visible strings and specialised byte-arrays (e.g. hex-prefix notation from the trie), they should be stored as unformatted byte-array data and not altered into some other form. We call these BINs. - -When interpreting RLP data, clients are required to consider non-canonical INT fields in the same way as otherwise invalid RLP data and dismiss it completely. - -Specifically: - -for the Block header: -[ -    parentHash: BIN, -    unclesHash: BIN, -    coinbase: BIN, -    stateRoot: BIN, -    transactionsHash: BIN, -    difficulty: INT, -    timestamp: INT, -    extraData: BIN, -    nonce: BIN -] - -(note: 'nonce', the last element, refers to a hash here and so is binary) - -for entries in the State trie for normal addresses: -[ -    balance: INT, -    nonce: INT -] - -and for contract addresses: -[ -    balance: INT, -    nonce: INT, -    contractRoot: BIN -] - -(note: 'nonce', the second element, refers to a tx-count here and so is integer) - -for transactions: -[ -    nonce: INT, -    recvAddr: BIN, -    value: INT, -    data: [...], -    v: INT, -    r: INT, -    s: INT -] - -(note: 'nonce', the first element, refers to a tx-count here and so is integer) - -The nonce in the transaction refers to the total amount of transactions send from the address up until that moment in time. Not the total amount (ie. equal to the sender's nonce specified in the address) - -for blocks, there are no immediate data field, but lists: -[ -    blockHeader: [...] -    uncleList: [uncleHash1: BIN, uncleHash2: BIN, ...] -    txList: [...] -] - -Uncle-blocks contain only the uncle's header. - - -8. Block hashes - -When mining a block we use the header of the block without the nonce. This hash is also used during nonce validation [prevHash, uncleHash, coinbase, stateRoot, transactionsHash, difficulty, timestamp, extraData] - -When saving and refering to blocks (e.g. broadcasting, fetching, etc) we use the hash of the entire block ie [header (with nonce), uncle list, tx list] - - -9. Genesis Block - -The header of the genesis block is 8 items, and is specified thus: - -[zeroHash256, sha3(rlp([])), zeroHash160, state_root, sha3(rlp([])), 2**22, 0, "", 42] - -zeroHash256 refers to the parent hash, a 256-bit hash which is all zeroes. -zeroHash160 refers to the coinbase address, a 160-bit hash which is all zeroes. -2^22 refers to the difficulty. -0 refers to the timestamp (the Unix epoch). -"" refers to the extradata. -sha3(rlp([])) values refer to the hashes of the transaction and uncle lists, both empty. - -The SHA-3 hash of the RLP of this block (in its entirety) is: - -ab6b9a5613970faa771b12d449b2e9bb925ab7a369f0a4b86b286e9d540099cf - - -10. VM - -When a contract address receives a transaction, a virtual machine is initiated with the contract's state. - -10. a. Terms - -There exists a stack of variable size that stores 256-bit values at each location. (Note: most instructions operate solely on the stack altering its state in some way.) - -S'[i] is the ith item counting down from the top of the pre-stack (i.e. the stack immediately after instruction execution), with the top of the stack corresponding to i == 0. - -S[i] is the ith item counting down from the top of the post-stack (i.e. the stack immediately prior to instruction execution), with the top of the stack corresponding to i == 0. - - -The exists a permanent store addressable by a 256-bit value that stores 256-bit values at each location. - -P'[i] is the permanent store (sometimes refered to as 'state' or 'store') of the VM at index i counting from zero PRIOR to instruction execution. - -P[i] is the permanent store (sometimes refered to as 'state' or 'store') of the VM at index i counting from zero AFTER to instruction execution. - - -The exists a temporary store addressable by a 256-bit value that stores 256-bit values at each location. - -T'[i] is the temporary store (sometimes refered to as 'memory') of the VM at index i counting from zero PRIOR to instruction execution. - -T[i] is the temporary store (sometimes refered to as 'memory') of the VM at index i counting from zero AFTER instruction execution. - - -PC' is the program counter PRIOR to instruction execution. - -PC is the program counter AFTER instruction execution. - - -FEE(I, S', P', D) is the fee associated with the execution of instruction I with a machine of stack S', permanent store P' and which has already completed D operations. - -It is defined as F where: - -IF I == SSTORE AND P[ S'[0] ] != 0 AND S'[1] == 0 THEN -    F = S + dataFee - memoryFee -IF I == SSTORE AND P[ S'[0] ] == 0 AND S'[1] != 0 THEN -    F = S + dataFee + memoryFee -IF I == SLOAD -    F = S + dataFee -IF I == EXTRO OR I == BALANCE -    F = S + extroFee -IF I == MKTX -    F = S + txFee -IF I == SHA256 OR I == SHA3 OR I == RIPEMD160 OR I == ECMUL OR I == ECADD -    OR I == ECSIGN OR I == ECRECOVER OR I == ECVALID THEN -    F = S + cryptoFee  - -Where: - -S = D >= 16 ? stepFee : 0 - -Notably, MLOAD and MSTORE have no associated 'memory' cost. SLOAD and SSTORE both have a per-time fee (dataFee). There is also a usage 'fee' (not really a fee as it is all ultimately returned to the contract) that is owed to the contract for all non-zero permanent storage elements. This 'fee', memoryFee, is paid by the contract when a permanent storage address is set to a non-zero value and recovered when that address is set to a zero value. On SUICIDE, all permanent storage is dissolved and so all outstanding memoryFees are recovered. -     -     -B[ A ] is the balance of the address given by A, with A interpreted as an address. - -ADDRESS is the address of the present contract. - - -10. b. Initial Operation - -STEPSDONE := 0 -PC' := 0 -FOR ALL i: T'[i] := 0 -S' is initialised such that its cardinality is zero (i.e. the stack starts empty). -P' must be equal to the value of P when the previous execution halted. - -10. c. General Operation - -The given steps are looped: -1. Execution halts if B[ ADDRESS ] < F( P'[PC'], S', P', STEPSDONE ) -2. B[ ADDRESS ] := B[ ADDRESS ] - F( P'[PC'], S', P', STEPSDONE ) -3. The operation given by P'[PC'] determines PC, P, T, S. -4. PC' := PC; P' := P; T' := T; S' := S; STEPSDONE := STEPSDONE + 1 - -10. d. VM Operations - -Summary line: -: - +
- -If PC is not defined explicitly, then it must be assumed PC := PC' + 1. Exceptions are PUSH, JMP and JMPI. - -The cardinality of S (i.e. size of the stack) is altered by A - R between S & S', by adding or removing items as necessary from the front. - -Where: -R: The minimal cardinality of the stack for this instruction to proceed. If this is not achieved then the machine halts with an stack underflow exception. (Note: In some cases of some implementations, this is also the number of values "popped" from the implementation's stack during the course of instruction execution.) -(A - R): The net change in cardinality of the stack over the course of instruction execution. - -FOR ALL i: if S[i] is not defined explicitly, then it must be assumed S[i] := S'[i + R - A] where i + R >= A. -FOR ALL i: if T[i] is not defined explicitly, then it must be assumed T[i] := T'[i]. -FOR ALL i: if P[i] is not defined explicitly, then it must be assumed P[i] := P'[i]. - -The expression (COND ? ONE : ZERO), where COND is an expression and ONE and ZERO are both value placeholders, evaluates to ONE if COND is true, and ZERO if COND is false. This is similar to the C-style ternary operator. - -When a 32-byte machine datum is interpreted as a 160-bit address or hash, the rightwards 20 bytes are taken (i.e. the low-order bytes when interpreting the data as Big-Endian). - -++ is the concatenation operator; all operands are byte arrays (mostly 32-byte arrays here, since that's the size of the VM's data & address types). - -LEFT_BYTES(A, n) returns the array bytes comprising the first (leftmost) n bytes of the 32 byte array A, which can be considered equivalent to a single value in the VM. - -10. e. VM Op-code Set - - • 0x00: STOP -0 +0 - ◦ Halts execution. - • 0x01: ADD -2 +1 - ◦ S[0] := S'[0] + S'[1] - • 0x02: MUL -2 +1 - ◦ S[0] := S'[0] * S'[1] - • 0x03: SUB -2 +1 - ◦ S[0] := S'[0] + S'[1] - • 0x04: DIV -2 +1 - ◦ S[0] := S'[0] / S'[1] - • 0x05: SDIV -2 +1 - ◦ S[0] := S'[0] / S'[1] - ◦ S'[0] & S'[1] are interpreted as signed 256-bit values for the purposes of this operation. - • 0x06: MOD -2 +1 - ◦ S[0] := S'[0] % S'[1] - • 0x07: SMOD -2 +1 - ◦ S[0] := S'[0] % S'[1] - ◦ S'[0] & S'[1] are interpreted as signed 256-bit values for the purposes of this operation. - • 0x08: EXP -2 +1 - ◦ S[0] := S'[0] + S'[1] - • 0x09: NEG -1 +1 - ◦ S[0] := -S'[0] - • 0x0a: LT -2 +1 - ◦ S[0] := S'[0] < S'[1] ? 1 : 0 - • 0x0b: LE -2 +1 - ◦ S[0] := S'[0] <= S'[1] ? 1 : 0 - • 0x0c: GT -2 +1 - ◦ S[0] := S'[0] > S'[1] ? 1 : 0 - • 0x0d: GE -2 +1 - ◦ S[0] := S'[0] >= S'[1] ? 1 : 0 - • 0x0e: EQ -2 +1 - ◦ S[0] := S'[0] == S'[1] ? 1 : 0 - • 0x0f: NOT -1 +1 - ◦ S[0] := S'[0] == 0 ? 1 : 0 - • 0x10: MYADDRESS -0 +1 - ◦ S[0] := ADDRESS - • 0x11: TXSENDER -0 +1 - ◦ S[0] := A - ◦ Where A is the address of the sender of the transaction that initiated this instance. - • 0x12: TXVALUE -0 +1 - ◦ S[0] := V - ◦ Where V is the value of the transaction that initiated this instance. - • 0x13: TXDATAN -0 +1 - ◦ S[0] := N - ◦ Where N is the number of data items of the transaction that initiated this instance. - • 0x14: TXDATA -1 +1 - ◦ S[0] := D[ S'[0] ] - ◦ Where D[i] is the ith data item, counting from zero, of the transaction that initiated this instance. - • 0x15: BLK_PREVHASH -0 +1 - ◦ S[0] := H - ◦ Where H is the SHA3 hash of the previous block. - • 0x16: BLK_COINBASE -0 +1 - ◦ S[0] := A - ◦ Where A is the coinbase address of the current block. - • 0x17: BLK_TIMESTAMP -0 +1 - ◦ S[0] := T - ◦ Where T is the timestamp of the current block (given as the Unix time_t when this block began its existence). - • 0x18: BLK_NUMBER -0 +1 - ◦ S[0] := N - ◦ Where N is the block number of the current block (counting upwards from genesis block which has N == 0). - • 0x19: BLK_DIFFICULTY -0 +1 - ◦ S[0] := D - ◦ Where D is the difficulty of the current block. - • 0x1a: BLK_NONCE -0 +1 - ◦ S[0] := H - ◦ Where H is the none of the previous block. - • 0x1b: BASEFEE -0 +1 - ◦ S[0] := V - ◦ Where V is the value of the current base fee (i.e. the fee multiplier). - •  0x20: SHA256 -(minimum: 1) +1 - ◦ S[0] := SHA256( S'[1] ++ S'[2] ++ ... S'[N] ++ LEFT_BYTES(S'[N], R) ) - ◦ Where: - ◦ N = FLOOR(S'[0] / 32) - ◦ R = S'[0] % 32 - •  0x21: RIPEMD160 -(minimum: 1) +1 - ◦ S[0] := RIPEMD160( S'[1] ++ S'[2] ++ ... S'[N] ++ LEFT_BYTES(S'[N], R) ) - ◦ Where all entities are as in SHA256 (0x20), above. - • 0x22: ECMUL -3 +1 - • 0x23: ECADD -4 +1 - • 0x24: ECSIGN -2 +1 - • 0x25: ECRECOVER -4 +1 - • 0x26: ECVALID -2 +1 - • 0x27: SHA3 -(minimum: 1) +1 - ◦ S[0] := SHA3( S'[1] ++ S'[2] ++ ... S'[N] ++ LEFT_BYTES(S'[N], R) ) - ◦ Where all entities are as in SHA256 (0x20), above. - • 0x30: PUSH X -0 +1 - ◦ PC := PC' + 2 - ◦ S[0] := P[PC' + 1] - • 0x31: POP -1 +0 - • 0x32: DUP -1 +2 - ◦ S[0] := S'[0] - • 0x33: SWAP -2 +2 - ◦ S[0] := S'[1] - ◦ S[1] := S'[0] - • 0x34: MLOAD -1 +1 - ◦ S[0] := T'[ S'[0] ] - • 0x35: MSTORE -2 +0 - ◦ T[ S'[0] ] := S'[1] - • 0x36: SLOAD -1 +1 - ◦ S[0] := P'[ S'[0] ] - • 0x37: SSTORE -2 +0 - ◦ P[ S'[0] ] := S'[1] - • 0x38: JMP -1 +0 - ◦ PC := S'[0] - • 0x39: JMPI -2 +0 - ◦ PC := S'[0] == 0 ? PC' : S'[1] - • 0x3a: IND -0 +1 - ◦ S[0] := PC - • 0x3b: EXTRO -2 +1 - ◦ S[0] := CONTRACT[ S'[0] ].P[ S'[1] ] - ◦ Where CONTRACT[ A ].P is the permanent store of the contract A, with A interpreted as an address. - • 0x3c: BALANCE -1 +1 - ◦ S[0] := B[ S'[0] ] - • 0x3d: MKTX -(minimum: 3) +0 - ◦ Executes a transaction where: - ◦ The recipient is given by S'[0], when interpreted as an address. - ◦ The value is given by S'[1] - ◦ The data of the transaction is given by S'[3], S'[4], ... S'[ 2 + S'[2] ] - ◦ (Thus the number of data items of the transaction is given by S'[2].) - • 0x3f: SUICIDE -1 +0 - ◦ Halts execution. - ◦ FOR ALL i: IF P[i] NOT EQUAL TO 0 THEN B[ S'[0] ] := B[ S'[0] ] + memoryFee - ◦ B[ S'[0] ] := B[ S'[0] ] + B[ ADDRESS ] - ◦ Removes all contract-related information from the Ethereum system. - - -11. VM Memory State - -The memory state of the contract (which forms contractRoot) is formed by a secondary trie which may exist within the same database as the rest of the state. The root of this secondary trie defines the contractRoot. - -Whereas the main state trie has keys of length 160-bit (pertaining to an address in ethereum), the secondary contract state trie has keys of length 256-bit (pertaining to a point in memory of the virtual machine). In both cases, the key is a fixed length number of bytes. Leftly zeroes are not removed. - -Both tries have values encoded as RLP, whereby the value is interpreted as a single RLP element that is a 256-bit binary block (i.e. a 32 byte array). - -11. a. No Zeroes Stored in Trie - -Nodes in the memory trie may have any value EXCEPT zero (which is encoded in RLP as the empty byte array). We are able to do this because we assume that the value of a memory location, if not specified in the trie, defaults to zero. - -If a location in memory ever becomes zero, no value is stored in the trie for that location (requiring the removal of an entry from the trie if the previous value at that location is non-zero). If a memory lookup (i.e. SLOAD) ever happens for an undefined key, then the value returned is zero. - - -12. VM Tests - diff --git a/preEIPS/poc3.md b/preEIPS/poc3.md deleted file mode 100644 index 37901237cb728..0000000000000 --- a/preEIPS/poc3.md +++ /dev/null @@ -1,424 +0,0 @@ -Testnet simplifications: - -1. Difficulty formula - -D(genesisblock) = 2^22 -D(block) = D(block.parent) + D(block.parent) / 1024 * (1 if block.timestamp < block.parent.timestamp + 42 else -1) - - -2. Fees - -All fees are burned - -{ poc-2: -txFee = 100x -x = 100000000000000 = 10^14 -blockReward = 1500000000000000000 = 1.5 * 10^18; -} - -{ poc-3: -stepFee = 1x  -dataFee = 20x -memoryFee = 5x -extroFee = 40x -cryptoFee = 20x -newContractFee = 100x -txFee = 100x -x = 100000000000000 = 10^14 -blockReward = 1500000000000000000 = 1.5 * 10^18; -} - - -3. Premine - -We should all put our ethereum addresses made with the pyethtool.py script at https://github.com/ethereum/website/blob/master/pyethtool/pyethtool.py below: - -Each address gets 2^200 units premined - -{ poc-2: -8a40bfaa73256b60764c1bf40675a99083efb075 (G) -93658b04240e4bd4046fd2d6d417d20f146f4b43 (J) -1e12515ce3e0f817a4ddef9ca55788a1d66bd2df (V) -80c01a26338f0d905e295fccb71fa9ea849ffa12 (A) -} -{ poc-3 & above: -8a40bfaa73256b60764c1bf40675a99083efb075 (G) -e6716f9544a56c530d868e4bfbacb172315bdead (J) -1e12515ce3e0f817a4ddef9ca55788a1d66bd2df (V) -1a26338f0d905e295fccb71fa9ea849ffa12aaf4 (A) -} - - -4. PoW - -sha(sha(blockheader_without_nonce) ++ nonce) <= 2^256 / difficulty - -where: -nonce and all outputs from sha are byte arrays of length 32; -++ is the concatenation operator; -<= operands are treated as bytearrays in BE format. - - -5. Uncles - -Nodes should NOT attempt to collect any uncles, although uncles should be included in the reward calculation. - - -6. Block & transactions formats: - -Though RLP is data-agnostic, it does specify a canonical representation for integer quantities. It is big-endian with no leading zero-bytes. Thus for elements than feasibly can be stored as integers, it becomes important to specify whether they should adhere to this canonical representation or be left in some other (perhaps more 'native') format. - -In the case of counts, balances, fees and amounts of wei, the canon-integer form must be used when storing in RLP. We call these INTs. - -In the case of hashes (256-bit or 160-bit), user-visible strings and specialised byte-arrays (e.g. hex-prefix notation from the trie), they should be stored as unformatted byte-array data and not altered into some other form. We call these BINs. - -When interpreting RLP data, clients are required to consider non-canonical INT fields in the same way as otherwise invalid RLP data and dismiss it completely. - -Specifically: - -for the Block header: -[ -    parentHash: BIN, -    unclesHash: BIN, -    coinbase: BIN, -    stateRoot: BIN, -    transactionsHash: BIN, -    difficulty: INT, -    timestamp: INT, -    extraData: BIN, -    nonce: BIN -] - -(note: 'nonce', the last element, refers to a hash here and so is binary) - -for entries in the State trie for normal addresses: -[ -    balance: INT, -    nonce: INT -] - -and for contract addresses: -[ -    balance: INT, -    nonce: INT, -    contractRoot: BIN -] - -(note: 'nonce', the second element, refers to a tx-count here and so is integer) - -for transactions: -[ -    nonce: INT, -    recvAddr: BIN, -    value: INT, -    data:  -    v: INT, -    r: INT, -    s: INT -] - -(note: 'nonce', the first element, refers to a tx-count here and so is integer) - -The nonce in the transaction refers to the total amount of transactions sent from the address up until that moment in time. - -for blocks, there are no immediate data field, but lists: -[ -    blockHeader: [...] -    uncleList: [ [...], [...], ... ] -    txList: [ [...], [...], ... ] -] - -Uncle-blocks contain only the uncle's header. - - -7. Network - -As specified on https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Wire-Protocol - - -8. Block hashes - -When mining a block we use the header of the block without the nonce. This hash is also used during nonce validation. This header-without-nonce therefore contains [prevHash, uncleHash, coinbase, stateRoot, transactionsHash, difficulty, timestamp, extraData]. - -When saving and refering to blocks (e.g. broadcasting, fetching, etc) we use the hash of the entire block ie [header (with nonce), uncle list, tx list] - - -9. Genesis Block - -The header of the genesis block is 9 items, and is specified thus: - -[zeroHash256, sha3(rlp([])), zeroHash160, state_root, sha3(rlp([])), 2**22, 0, "", 42] - -zeroHash256 refers to the parent hash, a 256-bit hash which is all zeroes. -zeroHash160 refers to the coinbase address, a 160-bit hash which is all zeroes. -2^22 refers to the difficulty. -0 refers to the timestamp (the Unix epoch). -"" refers to the extradata. -sha3(rlp([])) values refer to the hashes of the transaction and uncle lists, both empty. - -The SHA-3 hash of the RLP of this block (in its entirety) is: - -ab6b9a5613970faa771b12d449b2e9bb925ab7a369f0a4b86b286e9d540099cf - - -10. VM - -When a contract address receives a transaction, a virtual machine is initiated with the contract's state. - -10. a. Terms - -There exists a stack of variable size that stores 256-bit values at each location. (Note: most instructions operate solely on the stack altering its state in some way.) - -S'[i] is the ith item counting down from the top of the pre-stack (i.e. the stack immediately after instruction execution), with the top of the stack corresponding to i == 0. - -S[i] is the ith item counting down from the top of the post-stack (i.e. the stack immediately prior to instruction execution), with the top of the stack corresponding to i == 0. - - -The exists a permanent store addressable by a 256-bit value that stores 256-bit values at each location. - -P'[i] is the permanent store (sometimes refered to as 'state' or 'store') of the VM at index i counting from zero PRIOR to instruction execution. - -P[i] is the permanent store (sometimes refered to as 'state' or 'store') of the VM at index i counting from zero AFTER to instruction execution. - - -The exists a temporary store addressable by a 256-bit value that stores 256-bit values at each location. - -T'[i] is the temporary store (sometimes refered to as 'memory') of the VM at index i counting from zero PRIOR to instruction execution. - -T[i] is the temporary store (sometimes refered to as 'memory') of the VM at index i counting from zero AFTER instruction execution. - - -PC' is the program counter PRIOR to instruction execution. - -PC is the program counter AFTER instruction execution. - - -FEE(I, S', P', D) is the fee associated with the execution of instruction I with a machine of stack S', permanent store P' and which has already completed D operations. - -It is defined as F where: - -IF I == SSTORE AND P[ S'[0] ] != 0 AND S'[1] == 0 THEN -    F = S + dataFee - memoryFee -IF I == SSTORE AND P[ S'[0] ] == 0 AND S'[1] != 0 THEN -    F = S + dataFee + memoryFee -IF I == SLOAD -    F = S + dataFee -IF I == EXTRO OR I == BALANCE -    F = S + extroFee -IF I == MKTX -    F = S + txFee -IF I == SHA256 OR I == SHA3 OR I == RIPEMD160 OR I == ECMUL OR I == ECADD -    OR I == ECSIGN OR I == ECRECOVER OR I == ECVALID THEN -    F = S + cryptoFee  - -Where: - -S = D >= 16 ? stepFee : 0 - -Notably, MLOAD and MSTORE have no associated 'memory' cost. SLOAD and SSTORE both have a per-time fee (dataFee). There is also a usage 'fee' (not really a fee as it is all ultimately returned to the contract) that is owed to the contract for all non-zero permanent storage elements. This 'fee', memoryFee, is paid by the contract when a permanent storage address is set to a non-zero value and recovered when that address is set to a zero value. On SUICIDE, all permanent storage is dissolved and so all outstanding memoryFees are recovered. -     -     -B[ A ] is the balance of the address given by A, with A interpreted as an address. - -ADDRESS is the address of the present contract. - - -10. b. Initial Operation - -STEPSDONE := 0 -PC' := 0 -FOR ALL i: T'[i] := 0 -S' is initialised such that its cardinality is zero (i.e. the stack starts empty). -P' must be equal to the value of P when the previous execution halted. - - -10. c. General Operation - -The given steps are looped: -1. Execution halts if B[ ADDRESS ] < F( P'[PC'], S', P', STEPSDONE ) -2. B[ ADDRESS ] := B[ ADDRESS ] - F( P'[PC'], S', P', STEPSDONE ) -3. The operation given by P'[PC'] determines PC, P, T, S. -4. PC' := PC; P' := P; T' := T; S' := S; STEPSDONE := STEPSDONE + 1 - - -10. d. VM Operations - -Summary line: -: - + - -If PC is not defined explicitly, then it must be assumed PC := PC' + 1. Exceptions are PUSH, JMP and JMPI. - -The cardinality of S (i.e. size of the stack) is altered by A - R between S & S', by adding or removing items as necessary from the front. - -Where: -R: The minimal cardinality of the stack for this instruction to proceed. If this is not achieved then the machine halts with a stack underflow exception. (Note: In some cases of some implementations, this is also the number of values "popped" from the implementation's stack during the course of instruction execution.) -(A - R): The net change in cardinality of the stack over the course of instruction execution. - -FOR ALL i: if S[i] is not defined explicitly, then it must be assumed S[i] := S'[i + R - A] where i + R >= A. -FOR ALL i: if T[i] is not defined explicitly, then it must be assumed T[i] := T'[i]. -FOR ALL i: if P[i] is not defined explicitly, then it must be assumed P[i] := P'[i]. - -The expression (COND ? ONE : ZERO), where COND is an expression and ONE and ZERO are both value placeholders, evaluates to ONE if COND is true, and ZERO if COND is false. This is similar to the C-style ternary operator. - -When a 32-byte machine datum is interpreted as a 160-bit address or hash, the rightwards 20 bytes are taken (i.e. the low-order bytes when interpreting the data as Big-Endian). - -++ is the concatenation operator; all operands are byte arrays (mostly 32-byte arrays here, since that's the size of the VM's data & address types). - -LEFT_BYTES(A, n) returns the array bytes comprising the first (leftmost) n bytes of the 32 byte array A, which can be considered equivalent to a single value in the VM. - -10. e. VM Op-code Set - - • 0x00: STOP -0 +0 - ◦ Halts execution. - • 0x01: ADD -2 +1 - ◦ S[0] := S'[0] + S'[1] - • 0x02: MUL -2 +1 - ◦ S[0] := S'[0] * S'[1] - • 0x03: SUB -2 +1 - ◦ S[0] := S'[0] + S'[1] - • 0x04: DIV -2 +1 - ◦ S[0] := S'[0] / S'[1] - • 0x05: SDIV -2 +1 - ◦ S[0] := S'[0] / S'[1] - ◦ S'[0] & S'[1] are interpreted as signed 256-bit values for the purposes of this operation. - • 0x06: MOD -2 +1 - ◦ S[0] := S'[0] % S'[1] - • 0x07: SMOD -2 +1 - ◦ S[0] := S'[0] % S'[1] - ◦ S'[0] & S'[1] are interpreted as signed 256-bit values for the purposes of this operation. - • 0x08: EXP -2 +1 - ◦ S[0] := S'[0] + S'[1] - • 0x09: NEG -1 +1 - ◦ S[0] := -S'[0] - • 0x0a: LT -2 +1 - ◦ S[0] := S'[0] < S'[1] ? 1 : 0 - • 0x0b: LE -2 +1 - ◦ S[0] := S'[0] <= S'[1] ? 1 : 0 - • 0x0c: GT -2 +1 - ◦ S[0] := S'[0] > S'[1] ? 1 : 0 - • 0x0d: GE -2 +1 - ◦ S[0] := S'[0] >= S'[1] ? 1 : 0 - • 0x0e: EQ -2 +1 - ◦ S[0] := S'[0] == S'[1] ? 1 : 0 - • 0x0f: NOT -1 +1 - ◦ S[0] := S'[0] == 0 ? 1 : 0 - • 0x10: MYADDRESS -0 +1 - ◦ S[0] := ADDRESS - • 0x11: TXSENDER -0 +1 - ◦ S[0] := A - ◦ Where A is the address of the sender of the transaction that initiated this instance. - • 0x12: TXVALUE -0 +1 - ◦ S[0] := V - ◦ Where V is the value of the transaction that initiated this instance. - • 0x13: TXDATAN -0 +1 - ◦ S[0] := N - ◦ Where N is the number of data items of the transaction that initiated this instance. - • 0x14: TXDATA -1 +1 - ◦ S[0] := D[ S'[0] ] - ◦ Where D[i] is the ith data item, counting from zero, of the transaction that initiated this instance. - • 0x15: BLK_PREVHASH -0 +1 - ◦ S[0] := H - ◦ Where H is the SHA3 hash of the previous block. - • 0x16: BLK_COINBASE -0 +1 - ◦ S[0] := A - ◦ Where A is the coinbase address of the current block. - • 0x17: BLK_TIMESTAMP -0 +1 - ◦ S[0] := T - ◦ Where T is the timestamp of the current block (given as the Unix time_t when this block began its existence). - • 0x18: BLK_NUMBER -0 +1 - ◦ S[0] := N - ◦ Where N is the block number of the current block (counting upwards from genesis block which has N == 0). - • 0x19: BLK_DIFFICULTY -0 +1 - ◦ S[0] := D - ◦ Where D is the difficulty of the current block. - • 0x1a: BLK_NONCE -0 +1 - ◦ S[0] := H - ◦ Where H is the none of the previous block. - • 0x1b: BASEFEE -0 +1 - ◦ S[0] := V - ◦ Where V is the value of the current base fee (i.e. the fee multiplier). - •  0x20: SHA256 -(minimum: 1) +1 - ◦ S[0] := SHA256( S'[1] ++ S'[2] ++ ... S'[N] ++ LEFT_BYTES(S'[N], R) ) - ◦ Where: - ◦ N = FLOOR(S'[0] / 32) - ◦ R = S'[0] % 32 - •  0x21: RIPEMD160 -(minimum: 1) +1 - ◦ S[0] := RIPEMD160( S'[1] ++ S'[2] ++ ... S'[N] ++ LEFT_BYTES(S'[N], R) ) - ◦ Where all entities are as in SHA256 (0x20), above. - • 0x22: ECMUL -3 +1 - • 0x23: ECADD -4 +1 - • 0x24: ECSIGN -2 +1 - • 0x25: ECRECOVER -4 +1 - • 0x26: ECVALID -2 +1 - • 0x27: SHA3 -(minimum: 1) +1 - ◦ S[0] := SHA3( S'[1] ++ S'[2] ++ ... S'[N] ++ LEFT_BYTES(S'[N], R) ) - ◦ Where all entities are as in SHA256 (0x20), above. - • 0x30: PUSH X -0 +1 - ◦ PC := PC' + 2 - ◦ S[0] := P[PC' + 1] - • 0x31: POP -1 +0 - • 0x32: DUP -1 +2 - ◦ S[0] := S'[0] - • 0x33: SWAP -2 +2 - ◦ S[0] := S'[1] - ◦ S[1] := S'[0] - • 0x34: MLOAD -1 +1 - ◦ S[0] := T'[ S'[0] ] - • 0x35: MSTORE -2 +0 - ◦ T[ S'[0] ] := S'[1] - • 0x36: SLOAD -1 +1 - ◦ S[0] := P'[ S'[0] ] - • 0x37: SSTORE -2 +0 - ◦ P[ S'[0] ] := S'[1] - • 0x38: JMP -1 +0 - ◦ PC := S'[0] - • 0x39: JMPI -2 +0 - ◦ PC := S'[0] == 0 ? PC' : S'[1] - • 0x3a: IND -0 +1 - ◦ S[0] := PC - • 0x3b: EXTRO -2 +1 - ◦ S[0] := CONTRACT[ S'[0] ].P[ S'[1] ] - ◦ Where CONTRACT[ A ].P is the permanent store of the contract A, with A interpreted as an address. - • 0x3c: BALANCE -1 +1 - ◦ S[0] := B[ S'[0] ] - • 0x3d: MKTX -(minimum: 3) +0 - ◦ Immediately executes a transaction where: - ◦ The recipient is given by S'[0], when interpreted as an address. - ◦ The value is given by S'[1] - ◦ The data of the transaction is given by S'[3], S'[4], ... S'[ 2 + S'[2] ] - ◦ (Thus the number of data items of the transaction is given by S'[2].) - ◦ NOTE: This transaction is not queued; full ramifications take effect immediately, including balance transfers and any contract invokations. - • 0x3f: SUICIDE -1 +0 - ◦ Halts execution. - ◦ FOR ALL i: IF P[i] NOT EQUAL TO 0 THEN B[ S'[0] ] := B[ S'[0] ] + memoryFee - ◦ B[ S'[0] ] := B[ S'[0] ] + B[ ADDRESS ] - ◦ Removes all contract-related information from the Ethereum system. - - -11. VM Memory State - -The memory state of the contract (which forms contractRoot) is formed by a secondary trie which may exist within the same database as the rest of the state. The root of this secondary trie defines the contractRoot. - -Whereas the main state trie has keys of length 160-bit (pertaining to an address in ethereum), the secondary contract state trie has keys of length 256-bit (pertaining to a point in memory of the virtual machine). In both cases, the key is a fixed length number of bytes. Leftly zeroes are not removed. - -Both tries have values encoded as RLP, whereby the value is interpreted as a single RLP element that is a 256-bit binary block (i.e. a 32 byte array). - - -11. a. No Zeroes Stored in Trie - -Nodes in the memory trie may have any value EXCEPT zero (which is encoded in RLP as the empty byte array). We are able to do this because we assume that the value of a memory location, if not specified in the trie, defaults to zero. - -If a location in memory ever becomes zero, no value is stored in the trie for that location (requiring the removal of an entry from the trie if the previous value at that location is non-zero). If a memory lookup (i.e. SLOAD) ever happens for an undefined key, then the value returned is zero. - - -12. Transaction Execution - -Transactions should be executed once the validity of the transaction is ascertained. Validity is defined as: - - • Sender address balance at least transaction value + fee. - • Sender address nonce equal to transaction nonce. - • Only when the transaction creates a contract: There is no address collision. - -Once validity is ascertained, the balance may be transfered and the nonce incremented. If the transaction creates a contract then the memory should be initialised according to the transaction data. If the transaction invokes a contract, then that contract should be executed, by restarting an Ethereum Virtual Machine with the contract's state. - - diff --git a/preEIPS/poc4.md b/preEIPS/poc4.md deleted file mode 100644 index 08e8b5d8a2f00..0000000000000 --- a/preEIPS/poc4.md +++ /dev/null @@ -1,679 +0,0 @@ -PoC 4 - -### Big Changes - -We now make a distinction between state and code. Code is stored as an immutable byte array node in the state tree. Accounts have both a state and code hash. When creating contracts, two byte arrays containing EVM code are given: an initialiser (run once then discarded) and the body (stored in the state tree as mentioned). - -Transaction types are distinguished between  - -(i) A message call transaction now contains the following fields: - -    [ NONCE, VALUE, GASPRICE, GAS, TO, DATA, V, R, S ] - -(i) b. Whereas a contract creation transaction contains: - -    [ NONCE, VALUE, GASPRICE, GAS, 0, CODE, INIT, V, R, S ] (do we need the 0? take it out and it becomes ambiguous with the message call transaction above - How so, there's INIT which takes out the ambiguousity?) - both INIT and DATA are bytearrays hence the ambiguity. - -INIT gets run on creation. If this means that  - -### VM Execution Model - -The current operation is no longer taken from the (256-bit int) storage (P), but instead from a separate immutable byte array of code (C). All operations are bytes, and so are mostly the same as before. The only difference is for PUSH, which must now be split into 32 different opcodes, one for each length of data you wish to push onto the stack. This will mostly be PUSH32 or PUSH1. - -So, given C is the list of bytes of the currently executing code (which, could be CODE or INIT). So the operation to be done is O: - -O = C[ PC' ] - -### Addresses & Words - -Addresses are now formed from words by taking the left 160-bits. Words are formed from addresses conversely, through left-alignment. - -### VM Opcode Set - -# 0s: arithmetic operations - - • 0x00: STOP -0 +0 - ◦ Halts execution. - ◦ Any gas left over gets returned to caller (or in the case of the top-level call, the sender converted back to ETH). - • 0x01: ADD -2 +1 - ◦ S[0] := S'[0] + S'[1] - • 0x02: MUL -2 +1 - ◦ S[0] := S'[0] * S'[1] - • 0x03: SUB -2 +1 - ◦ S[0] := S'[0] - S'[1] - • 0x04: DIV -2 +1 - ◦ S[0] := S'[0] / S'[1] - • 0x05: SDIV -2 +1 - ◦ S[0] := S'[0] / S'[1] - ◦ S'[0] & S'[1] are interpreted as signed 256-bit values for the purposes of this operation. - • 0x06: MOD -2 +1 - ◦ S[0] := S'[0] % S'[1] - • 0x07: SMOD -2 +1 - ◦ S[0] := S'[0] % S'[1] - ◦ S'[0] & S'[1] are interpreted as signed 256-bit values for the purposes of this operation. - • 0x08: EXP -2 +1 - ◦ S[0] := S'[0] + S'[1] - • 0x09: NEG -1 +1 - ◦ S[0] := -S'[0] - • 0x0a: LT -2 +1 - ◦ S[0] := S'[0] < S'[1] ? 1 : 0 - • 0x0b: GT -2 +1 - ◦ S[0] := S'[0] > S'[1] ? 1 : 0 - • 0x0c: EQ -2 +1 - ◦ S[0] := S'[0] == S'[1] ? 1 : 0 - • 0x0d: NOT -1 +1 - ◦ S[0] := S'[0] == 0 ? 1 : 0 - -# 10s: bit operations - - • 0x10: AND -2 +1 - ◦ S[0] := S'[0] AND S'[1] - • 0x11: OR -2 +1 - ◦ S[0] := S'[0] OR S'[1] - • 0x12: XOR -2 +1 - ◦ S[0] := S'[0] XOR S'[1] - • 0x13: BYTE -2 +1 - ◦ S[0] := S'[0]th byte of S'[1] - ▪ if S'[0] < 32 - ◦ S[0] := 0 - ▪ otherwise - ◦ for Xth byte, we count from left - 0th is therefore the leftmost (most significant in BE) byte. - -# 20s: crypto opcodes - - • 0x20: SHA3 -2 +1 - ◦ S[0] := SHA3( T'[ S'[0] ++ ... ++ (S'[0] + S'[1]) ]) - -# 30s: closure state opcodes - - • 0x30: ADDRESS -0 +1 - ◦ S[0] := ADDRESS - ◦ i.e. the address of this closure. - • 0x31: BALANCE -1 +1 - ◦ S[0] := B[ S'[0] ] - ◦ i.e. the balance of this closure. - • 0x32: ORIGIN -0 +1 - ◦ S[0] := A - ◦ Where A is the address of the account that made the original transaction leading to the current closure and is paying the fees - • 0x33: CALLER -0 +1 - ◦ S[0] := A - ◦ Where A is the address of the object that made this call. - • 0x34: CALLVALUE -0 +1 - ◦ S[0] := V - ◦ Where V is the value attached to this call. - • 0x35: CALLDATALOAD -1 +0 - ◦ S[0] := D[ S'[0] ... (S'[0] + 31) ] - ◦ Where D is the data attached to this call (as a byte array). - ◦ Any bytes that are out of bounds of the data are defined as zero. - • 0x36: CALLDATASIZE -0 +1 - ◦ S[0] := DS - ◦ Where DS is the number of bytes of data attached to this call. - • 0x37: GASPRICE -0 +1 - ◦ S[0] := V - ◦ Where V is the current gas price (né fee multiplier). - -# 40s: block operations - - • 0x40: PREVHASH -0 +1 - ◦ S[0] := H - ◦ Where H is the SHA3 hash of the previous block. - • 0x41: COINBASE -0 +1 - ◦ S[0] := A - ◦ Where A is the coinbase address of the current block. - • 0x42: TIMESTAMP -0 +1 - ◦ S[0] := T - ◦ Where T is the timestamp of the current block (given as the Unix time_t when this block began its existence). - • 0x43: NUMBER -0 +1 - ◦ S[0] := N - ◦ Where N is the block number of the current block (counting upwards from genesis block which has N == 0). - • 0x44: DIFFICULTY -0 +1 - ◦ S[0] := D - ◦ Where D is the difficulty of the current block. - • 0x45: GASLIMIT -0 +1 - ◦ S[0] := L - ◦ Where L is the total gas limit of the current block. Always 10^6. - -# 50s: stack, memory, storage and execution path operations - - • 0x51: POP -1 +0 - • 0x52: DUP -1 +2 - ◦ S[0] := S'[0] - • 0x53: SWAP -2 +2 - ◦ S[0] := S'[1] - ◦ S[1] := S'[0] - • 0x54: MLOAD -1 +1 - ◦ S[0] := T'[ S'[0] ... S'[0] + 31 ] - • 0x55: MSTORE -2 +0 - ◦ T[ S'[0] ... S'[0] + 31 ] := S'[1] - • 0x56: MSTORE8 -2 +0 - ◦ T[ S'[0] ... S'[0] + 31 ] := S'[1] & 0xff - • 0x57: SLOAD -1 +1 - ◦ S[0] := P'[ S'[0] ] - • 0x58: SSTORE -2 +0 - ◦ P[ S'[0] ] := S'[1] - • 0x59: JUMP -1 +0 - ◦ PC := S'[0] - • 0x5a: JUMPI -2 +0 - ◦ PC := S'[1] == 0 ? PC' : S'[0] - • 0x:5b PC -0 +1 - ◦ S[0] := PC - • 0x5c: MSIZE -0 +1 - ◦ S[0] = sizeof(T) - • 0x5d: GAS - ◦ S[0] := G - ◦ Where G is the amount of gas remaining after executing the opcode. - -# 60s & 70s: push - • 0x60: PUSH1 0 +1 - ◦ S[0] := C[ PC' + 1 ] - ◦ PC := PC' + 2 - • 0x61: PUSH2 0 +1 - ◦ S[0] := C[ PC' + 1 ] ++ C[ PC' + 2 ] - ◦ PC := PC' + 3 -... - • 0x7f: PUSH32 0 +1 - ◦ S[0] := C[ PC' + 1 ] ++ C[ PC' + 2 ] ++ ... ++ C[ PC' + 32 ] - ◦ PC := PC' + 33 - -# f0s: closure-level operations - - • 0xf0: CREATE -5 +1 - ◦ Immediately creates a contract where: - ◦ The endowment is given by S'[0] - ◦ The body code of the eventual closure is given by T'[ S'[1] ... ( S'[1] + S'[2] - 1 ) ] - ◦ The initialisation code of the eventual closure is given by T'[ S'[3] ... ( S'[3] + S'[4] - 1 ) ] - ◦ (Thus the total number of bytes of the transaction data is given by S'[2] + S'[4].) - ◦ S[0] = A - ◦ where A is the address of the created contract or 0 if the creation failed. - ◦ Fees are deducted from the sender balance to pay for enough gas to complete the operation (i.e. contract creation fee + initial storage fee). If there was not enough gas to complete the operation, then all gas will be deducted and the operation fails. - • 0xf1: CALL -7 +1 - ◦ Immediately executes a call where: - ◦ The recipient is given by S'[0], when interpreted as an address. - ◦ The value is given by S'[1] - ◦ The gas is given by S'[2] - ◦ The input data of the call is given by T'[ S'[3] ... ( S'[3] + S'[4] - 1 ) ] - ◦ (Thus the number of bytes of the transaction is given by S'[4].) - ◦ The output data of the call is given by T[ S'[5] ... ( S'[5] + MIN( S'[6], S[0] ) - 1 ) ] - ◦ If 0 gas is specified, transfer all gas from the caller to callee gas balance, otherwise transfer only the amount given. If there isn't enough gas in the caller balance, operation fails. - ◦ If the value is less than the amount in the caller's balance then nothing is executed and the S'[2] gas gets refunded to the caller. - ◦ See Appendix A for execution. - ◦ Add any remaining callee gas to the caller's gas. - ◦ S[0] = R - ◦ where R = 1 when the instrinsic return code of the call is true, R = 0 otherwise. - • NOT YET: POST -5 +1 - ◦ Registers for delayed execution a call where: - ◦ The recipient is given by S'[0], when interpreted as an address. - ◦ The value is given by S'[1] - ◦ The gas to supply the transaction with is given by S'[2] (paid for from the current gas balance) - ◦ The input data of the call is given by T'[ S'[3] ... ( S'[3] + S'[4] - 1 ) ] - ◦ (Thus the number of bytes of the transaction is given by S'[4].) - ◦ Contract pays for itself to run at a defered time from its own GAS supply. The miner has no choice but to execute. - • NOT YET: ALARM -6 +1 - ◦ Registers for delayed execution a call where: - ◦ The recipient is given by S'[0], when interpreted as an address. - ◦ The value is given by S'[1] - ◦ The gas (to convert from ETH at the later time) is given by S'[2] - ◦ The number of blocks to wait before executing is S'[3] - ◦ The input data of the call is given by T'[ S'[4] ... ( S'[4] + S'[5] - 1 ) ] - ◦ (Thus the number of bytes of the transaction is given by S'[5].) - ◦ Total gas used now is S'[3] * S'[5] * deferFee. - ◦ Contract pays for itself to run at the defered time converting given amount of gas from its ETH balance; if it cannot pay it terminates as a bad transaction. TODO: include baseFee and allow miner freedom to determine whether to execute or not. If not, the next miner will have the chance. - • 0xf2: RETURN -2 +0 - ◦ Halts execution. - ◦ R := T[ S'[0] ... ( S'[0] + S'[1] - 1 ) ] - ◦ Where the output data of the call is specified as R. - ◦ Any gas left over gets returned to caller (or in the case of the top-level call, the sender converted back to ETH). - • 0xff: SUICIDE -1 +0 - ◦ Halts execution. - ◦ FOR ALL i: IF P[i] NOT EQUAL TO 0 THEN B[ S'[0] ] := B[ S'[0] ] + memoryFee - ◦ B[ S'[0] ] := B[ S'[0] ] + B[ ADDRESS ] - ◦ Removes all contract-related information from the Ethereum system. - - - -## Appendix A:  - -CALL has intrinsic parameters: - -TO, VALUE, GAS, INOFFSET, INSIZE, OUTOFFSET, OUTSIZE - -It also finishes an intrinsic boolean value relating to the success of the operation. - -The process for evaluating CALL is as follows: - -1. Let ROLLBACK := S where S is the current state. -2. Let program counter (PC) = 0. -Let it be known that all storage operations operate on TO's state. -Note that the memory is empty, thus (last used index + 1) = 0. -3. Set TXDATA to the first INSIZE bytes of memory starting from INOFFSET in the caller memory. -4. Repeat -    * Calculate the cost of the current instruction (see below), set to C -        * If the instruction is invalid or STOP, goto step 6. -    * If GAS < C then GAS := 0; S := ROLLBACK and evaluation finishes, returning false.  -    * GAS := GAS - C -    * Apply the instruction. -    Until an operation execution error has occured or the instruction is STOP, RETURN or SUICIDE. -5. If the output data of the call (R) is specified (through RETURN), then let the OUTSIZE bytes of caller memory beginning at OUTOFFSET. -6. Returns true. - - -## Appendix B - -Creation of a contract requires than an address be made: this is now defined as the left 160 bits of the SHA3 hash of the RLP encoded structure: - -[ SENDER, NONCE ] - -Should this address already be in use (i.e. have a node in the state tree) then, the address is incremented (as a bigendian int) and retried until it succeeds. - - -## Examples in HLL - -A few new contracts: - -### Namecoin - -    if tx.data[0] > 1000 and !contract.storage[tx.data[0]]: -         contract.storage[tx.data[0]] = tx.data[1] - -### Currency - -    if !contract.storage[1000]: -        contract.storage[1000] = 1 -                contract.storage[tx.sender] = 10^18 -    else: -        fbal = contract.storage[tx.sender] -        tbal = contract.storage[tx.data[0]] -        if fbal >= tx.data[1]: -            contract.storage[tx.sender] = fbal - tx.data[1] -            contract.storage[tx.data[0]] = tbal + tx.data[1] -                 -### Proprietary data feed - -    if tx.sender = : -        contract.storage[tx.data[0]] = tx.data[1] -    else: -        a = bytes(32) -        a[0] = contract.storage[tx.data[0]] -        return(a,32) - -### Stdlib (callable namecoin) - -Idea: [ 0, key, value ] to register, [ 1, key, returnsize, data... ] to use - -        if tx.data[0] == 0: -                if tx.data[1] > 1000 and !contract.storage[tx.data[1]]: -                        contract.storage[tx.data[1]] = tx.data[2] -        else: -                a = bytes(tx.data[2]) -                call(contract.storage[tx.data[1]],tx.value,tx.data+96,tx.datan-96,a,tx.data[2]) -                return(a,tx.data[2]) - -### Compilation tricks - -* Compile `bytes(expr)` as MSIZE DUP < EXPR > 1 SUB 0 PUSH SWAP MSTORE8 -* At the start of every compiled program, if `tx.data` is used more than zero times put `<(n+1)*32> CALLDATA PUSH (n+1) DUP MSTORE` where `n` represents the number of variables in the program (known at compile-time). - - -PoC 4 (was PoC 3.5) - -EVM: - -'Contracts' become 'Closures'. -'Transactions' become the things that are signed in some way and go in the transaction block. A transaction is enacted with a Message Call. -'Message Calls' encode a transfer of value (ETH) and invoke any code associated with the receiving object. - -The original caller (i.e. the original transaction's txsender) pre-pays for a specific amount of 'GAS'. What was baseFee now describes the ETH -> GAS price. Gas is the internal currency of the transaction. Execution operations deplete the GAS supply, as per the original ratios. Once the transaction is finished, any remaining GAS is reconverted back to ETH and refunded. - -Storage remains 256-bit address, 256-bit data. - -Word size: 256-bit (i.e. stack item size 256-bit). - -Memory is byte array (256-bit address, 8-bit data); memoryFee is proportional to greatest index that has ever been referenced in this instance and thus it's highly unlikely addresses will ever go above 32-bit. Whenever a higher memory index is used, the fee difference to take it to the higher usage from the original (lower) usage is charged. MEMSIZE is initially just the size of the input data. Note: MSTORE and MLOAD increase the highest-accessed index to their target index + 31. - -### Big Changes - -NOTE: Crypto functions, except SHA3, removed. -NOTE: SHA3 takes memory location & byte count. - -(i) A transaction now contains the following fields: - -    [ NONCE, VALUE, GASPRICE, GAS, TO, DATA, V, R, S ] - -* NONCE is a number, as in PoC-3 -* VALUE is a number, as in PoC-3 -* GAS is (as a number) the amount of GAS that will be exchanged from the sender's ETH balance in order to pay for all costs that happen due to this transaction. -* TO is a number (no longer the fixed 20-byte address that it was in PoC-3) -* GASPRICE is the wei per gas that the sender is willing to pay, as a number. -* DATA is a series of bytes -* V, R, S are numbers as before - -To evaluate: - -Let GASFEE := GAS * GASPRICE - -1. If GAS < TXDATAGAS * len(DATA) + CALLGAS , exit -1. Subtract GASFEE + VALUE from the sender's balance. If the sender's balance is too low, exit. -2. Let G := GAS - (TXDATAGAS * len(DATA) + CALLGAS) -3. Execute CALL operation with the instrinsic parameters (TO, VALUE, G, DATA, sizeof(DATA), 0, 0), (see Appendix A). -4. Add G * GASPRICE to sender's ETH balance where G is the remaining balance of gas from the CALL operation. - -(i) b. If the transaction creates a contract, it must be of the form: - -    [ NONCE, VALUE, GASPRICE, STORAGE, V, R, S ] - -Execution works as follows: 4. The algorithm is relatively computationally quick to verify, although  there is no “nice” verification formula that can be run inside EVM  code. - -Let GASFEE = (SSTOREGAS * D + CREATEGAS) * GASPRICE -where: -D is number of non-zero items of STORAGE - -1. Subtract GASFEE + VALUE from the sender's balance. If the sender's balance is too low, the transaction is declared invalid and no state change is recorded. -2. Put the contract into the blockchain, with the first portion of storage initialised to STORAGE and balance initialised to VALUE. - -NOTE: -(i) To determine if the transaction RLP encodes contract creation, extract nonce/value/basefee and then check if the following (fourth) item is a list - if so it's a creation transaction.     - -(ii) MKTX is renamed CALL. See appendix A for its execution. - -(iii) A new opcode RETURN is added. This allows the caller's memory bounded between OUTOFFSET and OUTOFFSET + OUTSIZE to be specified - -(iv) There is a block size limit (i.e. total gas allowed to be spent per block) which for PoC-3.5 is 10^6. - -### How to define instruction/step cost: - -Constants: - -* STEPGAS = 1 -* SHA3GAS = 20 -* SLOADGAS = 20 -* SSTOREGAS = 100 -* BALANCEGAS = 20 -* CREATEGAS = 100 -* CALLGAS = 20 -* MEMORYGAS = 1 -* TXDATAGAS = 5 [not used in the VM] - -Given an instruction, it is possible to calculate the gas cost of executing it as follows: - -* Unless covered by another rule below, an operation costs < STEPGAS > gas -* SHA3 costs < SHA3GAS > gas -* SLOAD costs < SLOADGAS > gas -* BALANCE costs < BALANCEGAS > gas -* SSTORE costs < D * SSTOREGAS > gas where: -- if the new value of the storage is non-zero and the old is zero, D = 2; -- if the new value of the storage is zero and the old is non-zero, D = 0; -- 1 otherwise. -* CALL costs < CALLGAS + G > gas, where G is the quantity of gas provided; some gas may be refunded though. -* CREATE costs < CREATEGAS + G > gas, where G is the quantity of gas provided. -* When you read or write memory with MSTORE, MLOAD, RETURN, SHA3, CALLDATA or CALL, enlarge the memory so that all bytes now fit in it (memory must always be a whole number of 32-byte words). Suppose that the highest previously accessed memory index is M, and the new index is N. If (N + 31) / 32 > (M + 31) / 32, add an additional < ((N + 31) / 32 - (M + 31) / 32) * MEMORYGAS > gas to the cost. - -For example, if you call `(TO, VALUE, 5000, 512, 512, 1024, 1024)`, and currently `N = 1024`, then we note that the total size of memory required is 2048 (the destination range is [1024, 2047]) and so 1024 addition , so the cost is `CALLGAS + 5000 + 1024 * MEMORYGAS = 6044`. - -### VM Opcode Set - -# 0s: arithmetic operations - - • 0x00: STOP -0 +0 - ◦ Halts execution. - ◦ Any gas left over gets returned to caller (or in the case of the top-level call, the sender converted back to ETH). - • 0x01: ADD -2 +1 - ◦ S[0] := S'[0] + S'[1] - • 0x02: MUL -2 +1 - ◦ S[0] := S'[0] * S'[1] - • 0x03: SUB -2 +1 - ◦ S[0] := S'[0] - S'[1] - • 0x04: DIV -2 +1 - ◦ S[0] := S'[0] / S'[1] - • 0x05: SDIV -2 +1 - ◦ S[0] := S'[0] / S'[1] - ◦ S'[0] & S'[1] are interpreted as signed 256-bit values for the purposes of this operation. - • 0x06: MOD -2 +1 - ◦ S[0] := S'[0] % S'[1] - • 0x07: SMOD -2 +1 - ◦ S[0] := S'[0] % S'[1] - ◦ S'[0] & S'[1] are interpreted as signed 256-bit values for the purposes of this operation. - • 0x08: EXP -2 +1 - ◦ S[0] := S'[0] + S'[1] - • 0x09: NEG -1 +1 - ◦ S[0] := -S'[0] - • 0x0a: LT -2 +1 - ◦ S[0] := S'[0] < S'[1] ? 1 : 0 - • 0x0b: GT -2 +1 - ◦ S[0] := S'[0] > S'[1] ? 1 : 0 - • 0x0c: EQ -2 +1 - ◦ S[0] := S'[0] == S'[1] ? 1 : 0 - • 0x0d: NOT -1 +1 - ◦ S[0] := S'[0] == 0 ? 1 : 0 - -# 10s: bit operations - - • 0x10: AND -2 +1 - ◦ S[0] := S'[0] AND S'[1] - • 0x11: OR -2 +1 - ◦ S[0] := S'[0] OR S'[1] - • 0x12: XOR -2 +1 - ◦ S[0] := S'[0] XOR S'[1] - • 0x13: BYTE -2 +1 - ◦ S[0] := S'[0]th byte of S'[1] - ▪ if S'[0] < 32 - ◦ S[0] := 0 - ▪ otherwise - ◦ for Xth byte, we count from left - 0th is therefore the leftmost (most significant in BE) byte. - -# 20s: crypto opcodes - - • 0x20: SHA3 -2 +1 - ◦ S[0] := SHA3( T'[ S'[0] ++ ... ++ (S'[0] + S'[1]) ]) - -# 30s: closure state opcodes - - • 0x30: ADDRESS -0 +1 - ◦ S[0] := ADDRESS - ◦ i.e. the address of this closure. - • 0x31: BALANCE -1 +1 - ◦ S[0] := B[ S'[0] ] - ◦ i.e. the balance of this closure. - • 0x32: ORIGIN -0 +1 - ◦ S[0] := A - ◦ Where A is the address of the account that made the original transaction leading to the current closure and is paying the fees - • 0x33: CALLER -0 +1 - ◦ S[0] := A - ◦ Where A is the address of the object that made this call. - • 0x34: CALLVALUE -0 +1 - ◦ S[0] := V - ◦ Where V is the value attached to this call. - • 0x35: CALLDATALOAD -1 +0 - ◦ S[0] := D[ S'[0] ... (S'[0] + 31) ] - ◦ Where D is the data attached to this call (as a byte array). - ◦ Any bytes that are out of bounds of the data are defined as zero. - • 0x36: CALLDATASIZE -0 +1 - ◦ S[0] := DS - ◦ Where DS is the number of bytes of data attached to this call. - • 0x37: GASPRICE -0 +1 - ◦ S[0] := V - ◦ Where V is the current gas price (né fee multiplier). - -# 40s: block operations - - • 0x40: PREVHASH -0 +1 - ◦ S[0] := H - ◦ Where H is the SHA3 hash of the previous block. - • 0x41: COINBASE -0 +1 - ◦ S[0] := A - ◦ Where A is the coinbase address of the current block. - • 0x42: TIMESTAMP -0 +1 - ◦ S[0] := T - ◦ Where T is the timestamp of the current block (given as the Unix time_t when this block began its existence). - • 0x43: NUMBER -0 +1 - ◦ S[0] := N - ◦ Where N is the block number of the current block (counting upwards from genesis block which has N == 0). - • 0x44: DIFFICULTY -0 +1 - ◦ S[0] := D - ◦ Where D is the difficulty of the current block. - • 0x45: GASLIMIT -0 +1 - ◦ S[0] := L - ◦ Where L is the total gas limit of the current block. Always 10^6. - -# 50s: stack, memory, storage and execution path operations - - • 0x50: PUSH X -0 +1 - ◦ PC := PC' + 2 - ◦ S[0] := P[PC' + 1] - • 0x51: POP -1 +0 - • 0x52: I -1 +2 - ◦ S[0] := S'[0] - • 0x53: SWAP -2 +2 - ◦ S[0] := S'[1] - ◦ S[1] := S'[0] - • 0x54: MLOAD -1 +1 - ◦ S[0] := T'[ S'[0] ... S'[0] + 31 ] - • 0x55: MSTORE -2 +0 - ◦ T[ S'[0] ... S'[0] + 31 ] := S'[1] - • 0x56: MSTORE8 -2 +0 - ◦ T[ S'[0] ... S'[0] + 31 ] := S'[1] & 0xff - • 0x57: SLOAD -1 +1 - ◦ S[0] := P'[ S'[0] ] - • 0x58: SSTORE -2 +0 - ◦ P[ S'[0] ] := S'[1] - • 0x59: JUMP -1 +0 - ◦ PC := S'[0] - • 0x5a: JUMPI -2 +0 - ◦ PC := S'[1] == 0 ? PC' : S'[0] - • 0x:5b PC -0 +1 - ◦ S[0] := PC - • 0x5c: MSIZE -0 +1 - ◦ S[0] = sizeof(T) - • 0x5d: GAS - ◦ S[0] := G - ◦ Where G is the amount of gas remaining after executing the opcode. - -# 60s: closure-level operations - - • 0x60: CREATE -5 +1 - ◦ Immediately creates a contract where: - ◦ The endowment is given by S'[0] - ◦ The input data of the call is given by T'[ S'[1] ... ( S'[1] + S'[2] - 1 ) ] - ◦ (Thus the number of bytes of the transaction data is given by S'[2].) - ◦ S[0] = A - ◦ where A is the address of the created contract. - ◦ Fees are deducted from the sender balance to pay for enough gas to complete the operation (i.e. contract creation fee + initial storage fee). - • 0x61: CALL -7 +1 - ◦ Immediately executes a call where: - ◦ The recipient is given by S'[0], when interpreted as an address. - ◦ The value is given by S'[1] - ◦ The gas is given by S'[2] - ◦ The input data of the call is given by T'[ S'[3] ... ( S'[3] + S'[4] - 1 ) ] - ◦ (Thus the number of bytes of the transaction is given by S'[4].) - ◦ The output data of the call is given by T[ S'[5] ... ( S'[5] + MIN( S'[6], S[0] ) - 1 ) ] - ◦ If 0 gas is specified, transfer all gas from the caller to callee gas balance, otherwise transfer only the amount given. If there isn't enough gas in the caller balance, operation fails. - ◦ If the value is less than the amount in the caller's balance then nothing is executed and the S'[2] gas gets refunded to the caller. - ◦ See Appendix A for execution. - ◦ Add any remaining callee gas to the caller's gas. - ◦ S[0] = R - ◦ where R = 1 when the instrinsic return code of the call is true, R = 0 otherwise. - • NOT YET: POST -5 +1 - ◦ Registers for delayed execution a call where: - ◦ The recipient is given by S'[0], when interpreted as an address. - ◦ The value is given by S'[1] - ◦ The gas to supply the transaction with is given by S'[2] (paid for from the current gas balance) - ◦ The input data of the call is given by T'[ S'[3] ... ( S'[3] + S'[4] - 1 ) ] - ◦ (Thus the number of bytes of the transaction is given by S'[4].) - ◦ Contract pays for itself to run at a defered time from its own GAS supply. The miner has no choice but to execute. - • NOT YET: ALARM -6 +1 - ◦ Registers for delayed execution a call where: - ◦ The recipient is given by S'[0], when interpreted as an address. - ◦ The value is given by S'[1] - ◦ The gas (to convert from ETH at the later time) is given by S'[2] - ◦ The number of blocks to wait before executing is S'[3] - ◦ The input data of the call is given by T'[ S'[4] ... ( S'[4] + S'[5] - 1 ) ] - ◦ (Thus the number of bytes of the transaction is given by S'[5].) - ◦ Total gas used now is S'[3] * S'[5] * deferFee. - ◦ Contract pays for itself to run at the defered time converting given amount of gas from its ETH balance; if it cannot pay it terminates as a bad transaction. TODO: include baseFee and allow miner freedom to determine whether to execute or not. If not, the next miner will have the chance. - • 0x62: RETURN -2 +0 - ◦ Halts execution. - ◦ R := T[ S'[0] ... ( S'[0] + S'[1] - 1 ) ] - ◦ Where the output data of the call is specified as R. - ◦ Any gas left over gets returned to caller (or in the case of the top-level call, the sender converted back to ETH). - • 0x7f: SUICIDE -1 +0 - ◦ Halts execution. - ◦ FOR ALL i: IF P[i] NOT EQUAL TO 0 THEN B[ S'[0] ] := B[ S'[0] ] + memoryFee - ◦ B[ S'[0] ] := B[ S'[0] ] + B[ ADDRESS ] - ◦ Removes all contract-related information from the Ethereum system. - -## Appendix A:  - -CALL has intrinsic parameters: - -TO, VALUE, GAS, INOFFSET, INSIZE, OUTOFFSET, OUTSIZE - -It also finishes an intrinsic boolean value relating to the success of the operation. - -The process for evaluating CALL is as follows: - -1. Let ROLLBACK := S where S is the current state. -2. Let program counter (PC) = 0. -Let it be known that all storage operations operate on TO's state. -Note that the memory is empty, thus (last used index + 1) = 0. -3. Set TXDATA to the first INSIZE bytes of memory starting from INOFFSET in the caller memory. -4. Repeat -    * Calculate the cost of the current instruction (see below), set to C -        * If the instruction is invalid or STOP, goto step 6. -    * If GAS < C then GAS := 0; S := ROLLBACK and evaluation finishes, returning false.  -    * GAS := GAS - C -    * Apply the instruction. -    Until an operation execution error has occured or the instruction is STOP, RETURN or SUICIDE. -5. If the output data of the call (R) is specified (through RETURN), then let the OUTSIZE bytes of caller memory beginning at OUTOFFSET. -6. Returns true. - - -## Appendix B - -Creation of a contract is as before, except that should there be an address collision in the creation of contract, the address is incremented (as a bigendian int) and retried until it succeeds. - - -## Examples in HLL - -A few new contracts: - -### Namecoin - -    if tx.data[0] > 1000 and !contract.storage[tx.data[0]]: -         contract.storage[tx.data[0]] = tx.data[1] - -### Currency - -    if !contract.storage[1000]: -        contract.storage[1000] = 1 -                contract.storage[tx.sender] = 10^18 -    else: -        fbal = contract.storage[tx.sender] -        tbal = contract.storage[tx.data[0]] -        if fbal >= tx.data[1]: -            contract.storage[tx.sender] = fbal - tx.data[1] -            contract.storage[tx.data[0]] = tbal + tx.data[1] -                 -### Proprietary data feed - -    if tx.sender = : -        contract.storage[tx.data[0]] = tx.data[1] -    else: -        a = bytes(32) -        a[0] = contract.storage[tx.data[0]] -        return(a,32) - -### Stdlib (callable namecoin) - -Idea: [ 0, key, value ] to register, [ 1, key, returnsize, data... ] to use - -        if tx.data[0] == 0: -                if tx.data[1] > 1000 and !contract.storage[tx.data[1]]: -                        contract.storage[tx.data[1]] = tx.data[2] -        else: -                a = bytes(tx.data[2]) -                call(contract.storage[tx.data[1]],tx.value,tx.data+96,tx.datan-96,a,tx.data[2]) -                return(a,tx.data[2]) - -### Compilation tricks - -* Compile `bytes(expr)` as MSIZE DUP < EXPR > 1 SUB 0 PUSH SWAP MSTORE8 -* At the start of every compiled program, if `tx.data` is used more than zero times put `<(n+1)*32> CALLDATA PUSH (n+1) DUP MSTORE` where `n` represents the number of variables in the program (known at compile-time). \ No newline at end of file diff --git a/preEIPS/poc5.md b/preEIPS/poc5.md deleted file mode 100644 index d6f558be9fbac..0000000000000 --- a/preEIPS/poc5.md +++ /dev/null @@ -1,125 +0,0 @@ -ALTERATIONS FOR SUICIDE - -Suicide's semantics are now: - -All funds are immediately transferred to the nominated recipient account, but the account itself remains valid. It is tagged for destruction, to be completed simultaneously with all remaining gas being refunded to the origination account (this can safely happen simultaneously since the suicidal account is necessarily a contract account and the transaction originator is necessarily externally controlled, non-contract account). - - - - -All accounts become the same type; code/storage is just empty for the non-contract accounts. - -Contract creation just specifies an initialiser; return of initialiser is body. - -[ nonce, price, gas, to, value, data, v, r, s] (to is 0 for contract creation) - -CALLDATACOPY instruction: -CALLDATACOPY MEMINDEX CALLDATAINDEX LEN? -CODESIZE -CODECOPY MEMINDEX CODEINDEX LEN - -CALL is now [ gas, to, value, datain, datain_sz, dataout, dataout_sz ] -CREATE is now [ value, datain, datain_sz ] - -Section 0x30 is now: -        ADDRESS, -        BALANCE, -        ORIGIN, -        CALLER, -        CALLVALUE, -        CALLDATALOAD, -        CALLDATASIZE, -        CALLDATACOPY = 0x37, -        CODESIZE = 0x38, -        CODECOPY = 0x39, -        GASPRICE = 0x3a, - - -Section 0x00 is now: -        STOP = 0x00,                ///< halts execution -        ADD, -        MUL, -        SUB, -        DIV, -        SDIV, -        MOD, -        SMOD, -        EXP, -        NEG, -        LT, -        GT, -        SLT = 0x0c,    // signed less than -        SGT = 0x0d,    // signed greater than -        EQ = 0x0e, -        NOT, - - - - -Use actual formula (LTMA) for gas limit: -gasLimit = floor((parent.gasLimit * (EMAFACTOR - 1) + floor(parent.gasUsed * BLK_LIMIT_FACTOR_NUM / BLK_LIMIT_FACTOR_DEN)) / EMA_FACTOR) - -BLK_LIMIT_FACTOR_NUM = 6 -BLK_LIMIT_FACTOR_DEN = 5 -EMA_FACTOR = 1024 - -For network protocol, switch IP Address to a 4-byte byte-array rather than a list of numbers.  - -Block format is now: -[ header, [ [tx0, s0, g0], [tx1, s1, g1], ...], [u0, u1, u2, ...] ] - -Block header format: -[prevHash, unclesHash, coinbase, stateRoot, txsTrieRoot, difficulty, number, minGasPrice, gasLimit, gasUsed, timestamp, extraData, nonce] - -extraData is a byte array length <= 1024. - -minGasPrice can default to 10 szabo for now. - -use triehash for the txlist instead of sha3ing the RLP: -triehash = Trie("").update(0, [tx0, s0, g0]).update(1, [tx1, s1, g1]).update( ..... ).root - -Where [tx(i), s(i), g(i)] are the ith transaction, the state root after applying the ith transaction, and the gas after applying the ith transaction and 0,1, etc are just numbers - -GAS costs: -Remove gas burn for tx data -5 GAS per byte of TXDATA -500 GAS per TXCOST -TXs no longer pay CREATE/CALL. - - -Genesis block - -Genesis block is: ( B32(0, 0, ...), B32(sha3(B())), B20(0, 0, ...), B32(stateRoot), B32(0, 0, ...), P(2^22), P(0), P(0), P(1000000), P(0), P(0), B(), B32(sha3(B(42))), B(), B() ) - -Genesis block items (as hex) are: -parentHash: 00000000000000000000000000000000000000000000000000000000000000000 -unclesHash: 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 -coinbase: 0000000000000000000000000000000000000000 -stateRoot: 11cc4aaa3b2f97cd6c858fcc0903b9b34b071e1798c91645f0e05e267028cb4a -txsTrieRoot: <> -difficulty: 400000 -number: <> -mixGasPrice: <> -gasLimit: 0f4240 -gasUsed: <> -timestamp: <> -extraData: <> -nonce: 04994f67dc55b09e814ab7ffc8df3686b4afb2bb53e60eae97ef043fe03fb829 -transaction: <> -uncles: <> - -Genesis block RLP encoded (as hex) is: -f8abf8a7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a011cc4aaa3b2f97cd6c858fcc0903b9b34b071e1798c91645f0e05e267028cb4aa1680834000008080830f4240808080a004994f67dc55b09e814ab7ffc8df3686b4afb2bb53e60eae97ef043fe03fb829c0c0 - -Note: B32 specifies a byte array of length 32, B20 specifies a byte array of length 20, B32(0, 0, ...) specifies a byte array filled with zeroes, B() specifies an empty byte array, B(42) specified a byte array of length 1 whose only element is of vaue 42, P specifies a positive integer (to be encoded as a bytearray in bigendian with no leading zeroes). - - -Javascript Bindings - -async & sync - -async is getX(..., function() {}) -sync is X(...) - - - diff --git a/preEIPS/poc6.md b/preEIPS/poc6.md deleted file mode 100644 index 900546cea5548..0000000000000 --- a/preEIPS/poc6.md +++ /dev/null @@ -1,92 +0,0 @@ -POC-7 https://ethereum.etherpad.mozilla.org/14? -Latest changes: - - ---------------------------------------------------- - -Stateless contracts: -Additional opcode: 0xf4: CALLSTATELESS -Calls self, but grabbing the code from the TO argument instead of from one's own address -DONE PY,C++, go/Java - --------------------------------------------------------- - -0x3b EXTCODESIZE -0x3c EXTCODECOPY -like CODECOPY, CODESIZE but takes an additional parameter at beginning (top of stack) containing address from which to copy. -DONE C++, Go, Java,JS - --------------------------------------------------------- - -* zero-size memory reads/writes do not lead to a size increase for fee purposes - -DONE PY,C++, go, Java,JS - --------------------------------------------------------- - -New opcodes: - -0x80...8f: DUP1 ... DUP16 -0x90...9f: SWAP1...SWAP16 (for LLVM cross-compilation) -0x14: ADDMOD -0x15: MULMOD (to make ecrecover easier) - -0x51, 0x52 are INVALID. - -DONE C++/GO/PY/Java,JS - --------------------------------------------------------- - -0xf3: POST (same as call, except 5 arguments in and 0 arguments out, and instead of immediately calling it adds the call to a postqueue, to be executed after everything else (including prior-created posts) within the scope of that transaction execution is executed) - -Transaction finalisation: -- Create contract if transaction was contract-creation -- Keep executing earliest POST while postqueue isn't empty. -- Refund unused gas to caller (this includes gas unused from POSTs) & give fees to miner. -- Execute SUICIDEs. - -DONE C++/GO/PY,JS - ----------------------------------------------------- - -New GHOST protocol - - • A block can contain as uncles headers which satisfy all of the following criteria: - ◦ They are valid headers (not necessarily valid blocks) - ◦ Their parent is a kth generation ancestor for k in {2, 3, 4, 5, 6, 7} - ◦ They were not uncles of the kth generation ancestor for k in {1, 2, 3, 4, 5, 6} - • The uncle reward is increased to 15/16x the main block reward - • The nephew reward (ie. reward for including an uncle) is set to 1/32x the main block reward - • The target block time is 12s (ie. s/42/9/g in the diff adjustment algo) - • >= 5 -> increase - • <= 4 -> reduce - -SUGGESTION: target block time 4s (eg. >= 3 increase <= 2 reduce) as a temporary stress test - -DONE C++/PY/node.js, go/Java - ----------------------------------------------------- - -for blocks, block.hash = sha3(rlp.encode(block.header)) - -for accounts which don't have code, the code is "" -and the codehash is "" (instead of sha3(()) as in PoC5) - -for contract-creation transactions, address is empty rather than 000000000000000... - -DONE C++/PY, go/Java/node.js - ---------------------------------------------------- - -CALL, CREATE, CALLDATACOPY, etc should take memory indices as given, and not as mod 2^64 (this could just be implemented as a <=2^64 error check in the code, since using 2^64 memory will be prohibitively expensive) - -DONE C++/PY, Go/Java - ---------------------------------------------------- - -PoC-6 Networking (parallel downloads) - -DONE C++, Go, node.js/Java - ---------------------------------------------------- - From 64b0a43b7e27aadfc0d9cc042aebf567f45f459a Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Tue, 21 Feb 2017 17:12:55 +0000 Subject: [PATCH 0053/1085] Rename eip-190-smart-contract-packaging-standard.md to eip-190.md --- EIPS/{eip-190-smart-contract-packaging-standard.md => eip-190.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename EIPS/{eip-190-smart-contract-packaging-standard.md => eip-190.md} (100%) diff --git a/EIPS/eip-190-smart-contract-packaging-standard.md b/EIPS/eip-190.md similarity index 100% rename from EIPS/eip-190-smart-contract-packaging-standard.md rename to EIPS/eip-190.md From e28f54737d0e28a200deaa0818a8ce8c45904526 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Tue, 21 Feb 2017 18:26:44 +0100 Subject: [PATCH 0054/1085] remove outdated paragraph --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 651165ec570f4..3e6c750c50b6c 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # EIP [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ethereum/EIPs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) Ethereum Improvement Proposal. EIPs propose and describe changes made to Ethereum Protocol. -People wishing to submit EIPs first should propose their idea as an issue and then formalize it using a PR. After discussion it will be published here. Having an EIP here does not make it a formally accepted standard until its status becomes Active. For a EIP to become Active requires the mutual consent of the community. An EIP is not finalized until it has been implemented and is in use. Those proposing changes should consider that ultimately consent may rest with the consensus of the Ethereum users. - # Contributing First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP to it. There is a [template EIP here](eip-X.md). Then submit a Pull Request to Ethereum's [EIPs repository](https://github.com/ethereum/EIPs). From a23bd30d651ec0b285defc21873417f9f1778bde Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 24 Feb 2017 12:07:02 +0100 Subject: [PATCH 0055/1085] Rename static_call to staticcall. --- EIPS/static_call.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/static_call.md b/EIPS/static_call.md index 677f85ee79c51..aab771f3db8a7 100644 --- a/EIPS/static_call.md +++ b/EIPS/static_call.md @@ -1,7 +1,7 @@ ## Preamble EIP: to be assigned - Title: New opcode STATIC_CALL + Title: New opcode STATICCALL Author: Vitalik Buterin , Christian Reitwiessner ; Type: Standard Track Category: Core @@ -22,7 +22,7 @@ To increase smart contract security, this proposal adds a new opcode that can be Opcode: `0xfa`. -`STATIC_CALL` functions equivalently to a `CALL`, except it takes 6 arguments not including value, and calls the child with a `STATIC` flag on. Any calls, static or otherwise, made by an execution instance with a `STATIC` flag on will also have a `STATIC` flag on. Any attempts to make state-changing operations inside an execution instance with a `STATIC` flag on will instead throw an exception. These operations include nonzero-value calls, creates, `LOG` calls, `SSTORE`, `SSTOREBYTES` and `SUICIDE`. +`STATICCALL` functions equivalently to a `CALL`, except it takes 6 arguments not including value, and calls the child with a `STATIC` flag on. Any calls, static or otherwise, made by an execution instance with a `STATIC` flag on will also have a `STATIC` flag on. Any attempts to make state-changing operations inside an execution instance with a `STATIC` flag on will instead throw an exception. These operations include nonzero-value calls, creates, `LOG` calls, `SSTORE`, `SSTOREBYTES` and `SUICIDE`. ## Rationale From 8856795031f2dfdb34e4a69731faa83298bda8d7 Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 24 Feb 2017 16:27:09 +0100 Subject: [PATCH 0056/1085] Test cases and scalars larger than field order. Scalars larger than the field characteristic are allowed because it only makes sense to restrict them to the group order, not the field characteristic and adding the group order as another magic constant here would complicated the specification. --- EIPS/ecopts.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/EIPS/ecopts.md b/EIPS/ecopts.md index 3ecd46a8153c4..d4b70b84df879 100644 --- a/EIPS/ecopts.md +++ b/EIPS/ecopts.md @@ -50,7 +50,7 @@ The length of the returned data is always as specified (i.e. it is not "unpadded ### Exact semantics -Invalid input: For both contracts, if any input point does not lie on the curve or any of the field elements (point coordinates or scalar) is equal or larger than the field modulus p, the contract fails. +Invalid input: For both contracts, if any input point does not lie on the curve or any of the field elements (point coordinates) is equal or larger than the field modulus p, the contract fails. The scalar can be any number between `0` and `2**256-1`. #### ADD Input: two curve points `(x, y)`. @@ -80,7 +80,14 @@ As with the introduction of any precompiled contract, contracts that already use ## Test Cases -To be written. +Inputs to test: + + - Curve points which would be valid if the numbers were taken mod p (should fail). + - Both contracts should succeed on empty input. + - Truncated input that results in a valid curve point. + - Points not on curve (but valid otherwise). + - Multiply point with scalar that lies between the order of the group and the field (should succeed). + - Multiply point with scalar that is larger than the field order (should succeed). ## Implementation From b5d5207029084d988f7bc111c40ac6314478c590 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Fri, 3 Mar 2017 12:14:28 -0500 Subject: [PATCH 0057/1085] redo table of EIPs in README --- README.md | 61 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 3e6c750c50b6c..eb5f120d7171e 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,47 @@ -# EIP [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ethereum/EIPs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) -Ethereum Improvement Proposal. EIPs propose and describe changes made to Ethereum Protocol. +# EIPs [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ethereum/EIPs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) +Ethereum Improvement Proposals (EIPs) describe standards for the Ethereum platform, including core protocol specifications, client APIs, and contract standards. # Contributing First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP to it. There is a [template EIP here](eip-X.md). Then submit a Pull Request to Ethereum's [EIPs repository](https://github.com/ethereum/EIPs). -# Current EIPS -| Number |Title | Author | Type | Layer | Status / Discussion | -| ------------- | ------------ | ------ | ----- | -------------| ------------------- | -| [1](EIPS/eip-1.md) | EIP Purpose and Guidelines | Martin Becze/Hudson Jameson | Meta | | Active | -| [2](EIPS/eip-2.mediawiki) | Homestead Hard-fork Changes | Vitalik Buterin | Standard | homestead (hard-fork) | Accepted | -| [3](EIPS/eip-3.mediawiki) | Addition of CALLDEPTH opcode | Martin Holst Swende | Standard | Consensus (hard-fork) | [Draft](https://github.com/ethereum/EIPs/issues/25) | -| [4](EIPS/eip-4.mediawiki) | EIP Classification | Joseph Chow | Meta | | Draft | -| [5](EIPS/eip-5.md) | Gas Usage for `RETURN` and `CALL*` | Christian Reitwiessner | Standard | Consensus (hard-fork) | [Draft](https://github.com/ethereum/EIPs/issues/8) | -| [6](EIPS/eip-6.md) | Renaming Suicide Variable | Hudson Jameson | Meta | | [Draft](https://github.com/ethereum/EIPs/pull/42) | -| [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Standard | homestead (hard-fork) | [Accepted](https://github.com/ethereum/EIPs/issues/23) | -| [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Standard | Networking | [Accepted](https://github.com/ethereum/EIPs/pull/49) | -| [150](https://github.com/ethereum/EIPs/issues/150) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Standard | Consensus (hard-fork) | [Accepted](https://github.com/ethereum/EIPs/issues/150) | -| [155](https://github.com/ethereum/EIPs/issues/155) | Simple replay attack protection | Vitalik Buterin | Standard | Consensus (hard-fork) | [Accepted](https://github.com/ethereum/EIPs/issues/155) | -| [160](https://github.com/ethereum/EIPs/issues/160) | EXP cost increase | Vitalik Buterin | Standard | Consensus (hard-fork) | [Accepted](https://github.com/ethereum/EIPs/issues/160) | -| [161](https://github.com/ethereum/EIPs/issues/161) | State trie clearing (invariant-preserving alternative) | Gavin Wood | Standard | Consensus (hard-fork) | [Accepted](https://github.com/ethereum/EIPs/issues/161) | -| [170](https://github.com/ethereum/EIPs/issues/170) | Contract code size limit | Vitalik Buterin | Standard | Consensus (hard-fork) | [Accepted](https://github.com/ethereum/EIPs/issues/170) | +# EIP status terms +* **Draft** - an EIP that is open for consideration +* **Accepted** - an EIP that is planned for immediate adoption, i.e. expected to be included in the next hard fork (for Core/Consensus layer EIPs). +* **Final** - an EIP that has been adopted in a previous hard fork (for Core/Consensus layer EIPs). +* **Deferred** - an EIP that is not being considered for immediate adoption. May be reconsidered in the future for a subsequent hard fork. + + + +# EIPs under consideration +| Number |Title | Author | Type | Layer | Status | +| -------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ----------| ------------| ----------| +| [5](EIPS/eip-5.md) | Gas Usage for `RETURN` and `CALL*` | Christian Reitwiessner| Standard | Core | Draft | +| [211](EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner| Standard | Core | Draft | + + + +# Accepted EIPs (planned for adoption) +| Number |Title | Author | Type | Layer | Status | +| -------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ----------| ------------| ----------| +| [86](EIPs/pull/208) | Abstraction of transaction origin and signature | Vitalik Buterin | Standard | Core | Accepted | +| [96](EIPs/pull/210) | Blockhash refactoring | Vitalik Buterin | Standard | Core | Accepted | +| [100](EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Standard | Core | Accepted | +| [140](EIPs/pull/206) | REVERT instruction in the Ethereum Virtual Machine | Beregszaszi, Mushegian| Standard | Core | Accepted | +| [196](EIPs/pull/213) | Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 | Reitwiessner | Standard | Core | Accepted | +| [197](EIPs/pull/212) | Precompiled contracts for optimal Ate pairing check on the elliptic curve alt_bn128 | Buterin, Reitwiessner | Standard | Core | Accepted | + + + +# Finalized EIPs (standards that have been adopted) +| Number |Title | Author | Type | Layer | Status | +| -------------------------- | ----------------------------------------------------------- | ----------------| ----------| ------------| --------| +| [2](EIPS/eip-2.mediawiki) | Homestead Hard-fork Changes | Vitalik Buterin | Standard | Core | Final | +| [6](EIPS/eip-6.md) | Renaming Suicide Opcode | Hudson Jameson | Standard | Interface | Final | +| [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Standard | Core | Final | +| [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Standard | Networking | Final | +| [150](EIPs/issues/150) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Standard | Core | Final | +| [155](EIPs/issues/155) | Simple replay attack protection | Vitalik Buterin | Standard | Core | Final | +| [160](EIPs/issues/160) | EXP cost increase | Vitalik Buterin | Standard | Core | Final | +| [161](EIPs/issues/161) | State trie clearing (invariant-preserving alternative) | Gavin Wood | Standard | Core | Final | +| [170](EIPs/issues/170) | Contract code size limit | Vitalik Buterin | Standard | Core | Final | + From c223f48992ac3eeb6a3486ab50f197584c6bf4ff Mon Sep 17 00:00:00 2001 From: benjaminion Date: Fri, 3 Mar 2017 20:38:33 +0000 Subject: [PATCH 0058/1085] Fix up URLs for the EIPs. Some of the URLs for the EIP numbers pointed to non-existent pages (by using absolute rather than relative paths). --- README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index eb5f120d7171e..2172b34458079 100644 --- a/README.md +++ b/README.md @@ -16,19 +16,19 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | Number |Title | Author | Type | Layer | Status | | -------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ----------| ------------| ----------| | [5](EIPS/eip-5.md) | Gas Usage for `RETURN` and `CALL*` | Christian Reitwiessner| Standard | Core | Draft | -| [211](EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner| Standard | Core | Draft | +| [211](https://github.com/ethereum/EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner| Standard | Core | Draft | # Accepted EIPs (planned for adoption) | Number |Title | Author | Type | Layer | Status | | -------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ----------| ------------| ----------| -| [86](EIPs/pull/208) | Abstraction of transaction origin and signature | Vitalik Buterin | Standard | Core | Accepted | -| [96](EIPs/pull/210) | Blockhash refactoring | Vitalik Buterin | Standard | Core | Accepted | -| [100](EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Standard | Core | Accepted | -| [140](EIPs/pull/206) | REVERT instruction in the Ethereum Virtual Machine | Beregszaszi, Mushegian| Standard | Core | Accepted | -| [196](EIPs/pull/213) | Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 | Reitwiessner | Standard | Core | Accepted | -| [197](EIPs/pull/212) | Precompiled contracts for optimal Ate pairing check on the elliptic curve alt_bn128 | Buterin, Reitwiessner | Standard | Core | Accepted | +| [86](https://github.com/ethereum/EIPs/pull/208) | Abstraction of transaction origin and signature | Vitalik Buterin | Standard | Core | Accepted | +| [96](https://github.com/ethereum/EIPs/pull/210) | Blockhash refactoring | Vitalik Buterin | Standard | Core | Accepted | +| [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Standard | Core | Accepted | +| [140](https://github.com/ethereum/EIPs/pull/206) | REVERT instruction in the Ethereum Virtual Machine | Beregszaszi, Mushegian| Standard | Core | Accepted | +| [196](https://github.com/ethereum/EIPs/pull/213) | Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 | Reitwiessner | Standard | Core | Accepted | +| [197](https://github.com/ethereum/EIPs/pull/212) | Precompiled contracts for optimal Ate pairing check on the elliptic curve alt_bn128 | Buterin, Reitwiessner | Standard | Core | Accepted | @@ -39,9 +39,9 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [6](EIPS/eip-6.md) | Renaming Suicide Opcode | Hudson Jameson | Standard | Interface | Final | | [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Standard | Core | Final | | [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Standard | Networking | Final | -| [150](EIPs/issues/150) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Standard | Core | Final | -| [155](EIPs/issues/155) | Simple replay attack protection | Vitalik Buterin | Standard | Core | Final | -| [160](EIPs/issues/160) | EXP cost increase | Vitalik Buterin | Standard | Core | Final | -| [161](EIPs/issues/161) | State trie clearing (invariant-preserving alternative) | Gavin Wood | Standard | Core | Final | -| [170](EIPs/issues/170) | Contract code size limit | Vitalik Buterin | Standard | Core | Final | +| [150](https://github.com/ethereum/EIPs/issues/150) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Standard | Core | Final | +| [155](https://github.com/ethereum/EIPs/issues/155) | Simple replay attack protection | Vitalik Buterin | Standard | Core | Final | +| [160](https://github.com/ethereum/EIPs/issues/160) | EXP cost increase | Vitalik Buterin | Standard | Core | Final | +| [161](https://github.com/ethereum/EIPs/issues/161) | State trie clearing (invariant-preserving alternative) | Gavin Wood | Standard | Core | Final | +| [170](https://github.com/ethereum/EIPs/issues/170) | Contract code size limit | Vitalik Buterin | Standard | Core | Final | From cee2889d772aaf599da2cc996c47b2694f489eb6 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Fri, 3 Mar 2017 21:22:44 -0500 Subject: [PATCH 0059/1085] add EIP-198 (bigint modexp) to accepted table --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2172b34458079..d33e0ca6a082c 100644 --- a/README.md +++ b/README.md @@ -25,11 +25,11 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | -------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ----------| ------------| ----------| | [86](https://github.com/ethereum/EIPs/pull/208) | Abstraction of transaction origin and signature | Vitalik Buterin | Standard | Core | Accepted | | [96](https://github.com/ethereum/EIPs/pull/210) | Blockhash refactoring | Vitalik Buterin | Standard | Core | Accepted | -| [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Standard | Core | Accepted | +| [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Standard | Core | Accepted | | [140](https://github.com/ethereum/EIPs/pull/206) | REVERT instruction in the Ethereum Virtual Machine | Beregszaszi, Mushegian| Standard | Core | Accepted | | [196](https://github.com/ethereum/EIPs/pull/213) | Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 | Reitwiessner | Standard | Core | Accepted | | [197](https://github.com/ethereum/EIPs/pull/212) | Precompiled contracts for optimal Ate pairing check on the elliptic curve alt_bn128 | Buterin, Reitwiessner | Standard | Core | Accepted | - +| [198](https://github.com/ethereum/EIPs/pull/198) | Precompiled contract for bigint modular exponentiation | Vitalik Buterin | Standard | Core | Accepted | # Finalized EIPs (standards that have been adopted) From f79c29a8dbc8fc8968d13cb599bedddeeada55d3 Mon Sep 17 00:00:00 2001 From: Hudson Jameson Date: Fri, 17 Mar 2017 09:10:47 -0500 Subject: [PATCH 0060/1085] Added EIP 98 to Accepted --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d33e0ca6a082c..a8378b1f9e935 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | -------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ----------| ------------| ----------| | [86](https://github.com/ethereum/EIPs/pull/208) | Abstraction of transaction origin and signature | Vitalik Buterin | Standard | Core | Accepted | | [96](https://github.com/ethereum/EIPs/pull/210) | Blockhash refactoring | Vitalik Buterin | Standard | Core | Accepted | +| [98](https://github.com/ethereum/EIPs/pull/98) | Removal of intermediate state roots from receipts | Vitalik Buterin | Standard | Core | Accepted | | [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Standard | Core | Accepted | | [140](https://github.com/ethereum/EIPs/pull/206) | REVERT instruction in the Ethereum Virtual Machine | Beregszaszi, Mushegian| Standard | Core | Accepted | | [196](https://github.com/ethereum/EIPs/pull/213) | Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 | Reitwiessner | Standard | Core | Accepted | From e1c5a77756a0f3ab2e36399c7c344975d0481bbe Mon Sep 17 00:00:00 2001 From: cdetrio Date: Fri, 17 Mar 2017 11:40:01 -0400 Subject: [PATCH 0061/1085] STATICCALL and PURE_CALL are under consideration --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index a8378b1f9e935..a5617c5a25d58 100644 --- a/README.md +++ b/README.md @@ -13,19 +13,20 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP # EIPs under consideration -| Number |Title | Author | Type | Layer | Status | -| -------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ----------| ------------| ----------| -| [5](EIPS/eip-5.md) | Gas Usage for `RETURN` and `CALL*` | Christian Reitwiessner| Standard | Core | Draft | +| Number |Title | Author | Type | Layer | Status | +| ------------------------------------------------------ | ----------------------------------------------------------------------------------- | -------------------- | ----------| ------------| ----------| +| [5](EIPS/eip-5.md) | Gas Usage for `RETURN` and `CALL*` | Christian Reitwiessner| Standard | Core | Draft | | [211](https://github.com/ethereum/EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner| Standard | Core | Draft | - +| [214](https://github.com/ethereum/EIPs/pull/214) | New opcode STATICCALL | Buterin, Reitwiessner | Standard | Core | Draft | +| [195](https://github.com/ethereum/EIPs/pull/195) | New opcode PURE_CALL | Vitalik Buterin | Standard | Core | Draft | # Accepted EIPs (planned for adoption) -| Number |Title | Author | Type | Layer | Status | -| -------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ----------| ------------| ----------| +| Number |Title | Author | Type | Layer | Status | +| ------------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ----------| ------------| ----------| | [86](https://github.com/ethereum/EIPs/pull/208) | Abstraction of transaction origin and signature | Vitalik Buterin | Standard | Core | Accepted | | [96](https://github.com/ethereum/EIPs/pull/210) | Blockhash refactoring | Vitalik Buterin | Standard | Core | Accepted | -| [98](https://github.com/ethereum/EIPs/pull/98) | Removal of intermediate state roots from receipts | Vitalik Buterin | Standard | Core | Accepted | +| [98](https://github.com/ethereum/EIPs/pull/98) | Removal of intermediate state roots from receipts | Vitalik Buterin | Standard | Core | Accepted | | [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Standard | Core | Accepted | | [140](https://github.com/ethereum/EIPs/pull/206) | REVERT instruction in the Ethereum Virtual Machine | Beregszaszi, Mushegian| Standard | Core | Accepted | | [196](https://github.com/ethereum/EIPs/pull/213) | Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 | Reitwiessner | Standard | Core | Accepted | @@ -34,15 +35,14 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP # Finalized EIPs (standards that have been adopted) -| Number |Title | Author | Type | Layer | Status | -| -------------------------- | ----------------------------------------------------------- | ----------------| ----------| ------------| --------| -| [2](EIPS/eip-2.mediawiki) | Homestead Hard-fork Changes | Vitalik Buterin | Standard | Core | Final | -| [6](EIPS/eip-6.md) | Renaming Suicide Opcode | Hudson Jameson | Standard | Interface | Final | -| [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Standard | Core | Final | -| [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Standard | Networking | Final | +| Number |Title | Author | Type | Layer | Status | +| ------------------------------------------------------- | ----------------------------------------------------------- | ----------------| ----------| ------------| --------| +| [2](EIPS/eip-2.mediawiki) | Homestead Hard-fork Changes | Vitalik Buterin | Standard | Core | Final | +| [6](EIPS/eip-6.md) | Renaming Suicide Opcode | Hudson Jameson | Standard | Interface | Final | +| [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Standard | Core | Final | +| [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Standard | Networking | Final | | [150](https://github.com/ethereum/EIPs/issues/150) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Standard | Core | Final | | [155](https://github.com/ethereum/EIPs/issues/155) | Simple replay attack protection | Vitalik Buterin | Standard | Core | Final | | [160](https://github.com/ethereum/EIPs/issues/160) | EXP cost increase | Vitalik Buterin | Standard | Core | Final | | [161](https://github.com/ethereum/EIPs/issues/161) | State trie clearing (invariant-preserving alternative) | Gavin Wood | Standard | Core | Final | | [170](https://github.com/ethereum/EIPs/issues/170) | Contract code size limit | Vitalik Buterin | Standard | Core | Final | - From 6e57adb78236e59c88c466751482a78671f9a0dc Mon Sep 17 00:00:00 2001 From: Hudson Jameson Date: Mon, 20 Mar 2017 14:44:52 -0500 Subject: [PATCH 0062/1085] Removed PURE_CALL from under consideration. Devs have made a decision to remove PURE_CALL and keep STATIC_CALL, revert+returndata, & return{size, data}. --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index a5617c5a25d58..5fa8cbab6c77a 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,6 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [5](EIPS/eip-5.md) | Gas Usage for `RETURN` and `CALL*` | Christian Reitwiessner| Standard | Core | Draft | | [211](https://github.com/ethereum/EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner| Standard | Core | Draft | | [214](https://github.com/ethereum/EIPs/pull/214) | New opcode STATICCALL | Buterin, Reitwiessner | Standard | Core | Draft | -| [195](https://github.com/ethereum/EIPs/pull/195) | New opcode PURE_CALL | Vitalik Buterin | Standard | Core | Draft | # Accepted EIPs (planned for adoption) From 2485b86e8658ea59393fd0d1f99098968048813b Mon Sep 17 00:00:00 2001 From: Hudson Jameson Date: Mon, 20 Mar 2017 18:04:02 -0500 Subject: [PATCH 0063/1085] Added Note to EIP 5 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5fa8cbab6c77a..5dc97637dfbea 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP # EIPs under consideration | Number |Title | Author | Type | Layer | Status | | ------------------------------------------------------ | ----------------------------------------------------------------------------------- | -------------------- | ----------| ------------| ----------| -| [5](EIPS/eip-5.md) | Gas Usage for `RETURN` and `CALL*` | Christian Reitwiessner| Standard | Core | Draft | +| [5](EIPS/eip-5.md) | Gas Usage for `RETURN` and `CALL*` [Note: Unneccessary if 211 is accepted] | Christian Reitwiessner| Standard | Core | Draft | | [211](https://github.com/ethereum/EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner| Standard | Core | Draft | | [214](https://github.com/ethereum/EIPs/pull/214) | New opcode STATICCALL | Buterin, Reitwiessner | Standard | Core | Draft | From 58c1828d263072421862ab53e839c85551abbb62 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 9 Feb 2017 18:16:57 +0000 Subject: [PATCH 0064/1085] Add EIP141 (invalid instruction) --- EIPS/eip-141.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 EIPS/eip-141.md diff --git a/EIPS/eip-141.md b/EIPS/eip-141.md new file mode 100644 index 0000000000000..f1346380bec92 --- /dev/null +++ b/EIPS/eip-141.md @@ -0,0 +1,29 @@ +## Preamble + + EIP: 141 + Title: Designated invalid EVM instruction + Author: Alex Beregszaszi + Type: Standard Track + Category: Core + Status: Accepted + Created: 2017-02-09 + +## Abstract + +An instruction is designated to remain as an invalid instruction. + +## Motivation + +The invalid instruction can be used as a distinct reason to abort execution. + +## Specification + +The opcode `0xfe` is the `INVALID` instruction. It can be used to abort the execution (i.e. duplicates as an `ABORT` instruction). + +## Backwards Compatibility + +This instruction was never used and therefore has no effect on past contracts. + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 2541298b633b48bd6a59483d19078dcfda90bc90 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 9 Feb 2017 18:17:43 +0000 Subject: [PATCH 0065/1085] Add EIP141 to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5dc97637dfbea..1fcccc3aa37c4 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [6](EIPS/eip-6.md) | Renaming Suicide Opcode | Hudson Jameson | Standard | Interface | Final | | [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Standard | Core | Final | | [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Standard | Networking | Final | +[ [141](EIPS/eip-141.md) | Designated invalid EVM instruction | Alex Beregsazszi| Standard | Core | Final | | [150](https://github.com/ethereum/EIPs/issues/150) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Standard | Core | Final | | [155](https://github.com/ethereum/EIPs/issues/155) | Simple replay attack protection | Vitalik Buterin | Standard | Core | Final | | [160](https://github.com/ethereum/EIPs/issues/160) | EXP cost increase | Vitalik Buterin | Standard | Core | Final | From a0ef90d2980f676a7c3c01b12c57836b210a5d98 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 6 Feb 2017 19:54:08 +0000 Subject: [PATCH 0066/1085] Draft EIP for the REVERT opcode --- EIPS/eip-draft_revert_opcode.md | 47 +++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 EIPS/eip-draft_revert_opcode.md diff --git a/EIPS/eip-draft_revert_opcode.md b/EIPS/eip-draft_revert_opcode.md new file mode 100644 index 0000000000000..7e2ed1a58bd3c --- /dev/null +++ b/EIPS/eip-draft_revert_opcode.md @@ -0,0 +1,47 @@ +## Preamble + + EIP: + Title: REVERT instruction in the Ethereum Virtual Machine + Author: Alex Beregszaszi, Nikolai Mushegian (nikolai@nexusdev.us) + Type: Standard Track + Category: Core + Status: Draft + Created: 2017-02-06 + +## Simple Summary + +The `REVERT` instruction provides a way to stop execution and revert state changes, without consuming all provided gas and with the ability to return a reason. + +## Abstract + +The `REVERT` instruction will stop execution, roll back all state changes done so far and provide a pointer to a memory section, which can be interpreted as an error code or message. While doing so, it will not consume all the remaining gas. + +## Motivation + +Currently this is not possible. There are two practical ways to revert a transaction from within a contract: running out of gas or executing an invalid instruction. Both of these options will consume all remaining gas. Additionally, reverting a transaction means that all changes, including LOGs, are lost and there is no way to convey a reason for aborting a transaction. + +## Specification + +The `REVERT` instruction is introduced at `0xfd`. Execution is aborted and state changes are rolled back. + +It expects two stack items, the top item is the `memory_length` followed by `memory_offset`. Both of these can equal to zero. The cost of the `REVERT` instruction equals to that of the `RETURN` instruction. + +In case there is not enough gas left to cover the cost of `REVERT` or there is a stack underflow, the effect of the `REVERT` instruction will equal to that of a regular out of gas exception. + +The content of the optionally provided memory section is not defined by this EIP, but is a candidate for another Informational EIP. + +## Rationale + +TBD + +## Backwards Compatibility + +This change has no effect on contracts created in the past. + +## Test Cases + +TBA + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From bb1368137fd7dfa287ba72b271dc22d46b477cc1 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 23 Mar 2017 12:32:13 +0000 Subject: [PATCH 0067/1085] Assign EIP140 to REVERT --- EIPS/eip-draft_revert_opcode.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-draft_revert_opcode.md b/EIPS/eip-draft_revert_opcode.md index 7e2ed1a58bd3c..5c456551fba51 100644 --- a/EIPS/eip-draft_revert_opcode.md +++ b/EIPS/eip-draft_revert_opcode.md @@ -1,6 +1,6 @@ ## Preamble - EIP: + EIP: 140 Title: REVERT instruction in the Ethereum Virtual Machine Author: Alex Beregszaszi, Nikolai Mushegian (nikolai@nexusdev.us) Type: Standard Track From f1af1f393ca8af73e45d28f756be0be8071ca876 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 23 Mar 2017 12:43:51 +0000 Subject: [PATCH 0068/1085] Add test case for REVERT --- EIPS/eip-draft_revert_opcode.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-draft_revert_opcode.md b/EIPS/eip-draft_revert_opcode.md index 5c456551fba51..aad30fff80c98 100644 --- a/EIPS/eip-draft_revert_opcode.md +++ b/EIPS/eip-draft_revert_opcode.md @@ -40,7 +40,14 @@ This change has no effect on contracts created in the past. ## Test Cases -TBA +``` +6c726576657274656420646174616000557f726576657274206d657373616765000000000000000000000000000000000000600052600e6000fd +``` + +should: +- return `726576657274206d657373616765` as `REVERT` data, +- the storage at key `0x0` should be left as unset and +- use 20024 gas in total. ## Copyright From 729b590308862b084a108f7204e05695e84100f8 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 23 Mar 2017 12:47:05 +0000 Subject: [PATCH 0069/1085] Swap the stack items for REVERT to be in line with RETURN --- EIPS/eip-draft_revert_opcode.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-draft_revert_opcode.md b/EIPS/eip-draft_revert_opcode.md index aad30fff80c98..65a293ab5a753 100644 --- a/EIPS/eip-draft_revert_opcode.md +++ b/EIPS/eip-draft_revert_opcode.md @@ -24,7 +24,7 @@ Currently this is not possible. There are two practical ways to revert a transac The `REVERT` instruction is introduced at `0xfd`. Execution is aborted and state changes are rolled back. -It expects two stack items, the top item is the `memory_length` followed by `memory_offset`. Both of these can equal to zero. The cost of the `REVERT` instruction equals to that of the `RETURN` instruction. +It expects two stack items, the top item is the `memory_offset` followed by `memory_length`. Both of these can equal to zero. The cost of the `REVERT` instruction equals to that of the `RETURN` instruction. In case there is not enough gas left to cover the cost of `REVERT` or there is a stack underflow, the effect of the `REVERT` instruction will equal to that of a regular out of gas exception. From c7944c477a409cfd1491c3882de9e15660fa5918 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 23 Mar 2017 12:59:21 +0000 Subject: [PATCH 0070/1085] Remove rationale (it is already explained twice) --- EIPS/eip-draft_revert_opcode.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/EIPS/eip-draft_revert_opcode.md b/EIPS/eip-draft_revert_opcode.md index 65a293ab5a753..3312facf58100 100644 --- a/EIPS/eip-draft_revert_opcode.md +++ b/EIPS/eip-draft_revert_opcode.md @@ -30,10 +30,6 @@ In case there is not enough gas left to cover the cost of `REVERT` or there is a The content of the optionally provided memory section is not defined by this EIP, but is a candidate for another Informational EIP. -## Rationale - -TBD - ## Backwards Compatibility This change has no effect on contracts created in the past. From 4455e2c105910d870aab1c500cb8f0bd447b66b2 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 23 Mar 2017 13:01:09 +0000 Subject: [PATCH 0071/1085] Mention that the execution is considered as failed --- EIPS/eip-draft_revert_opcode.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-draft_revert_opcode.md b/EIPS/eip-draft_revert_opcode.md index 3312facf58100..af5b9fcb764b1 100644 --- a/EIPS/eip-draft_revert_opcode.md +++ b/EIPS/eip-draft_revert_opcode.md @@ -22,7 +22,7 @@ Currently this is not possible. There are two practical ways to revert a transac ## Specification -The `REVERT` instruction is introduced at `0xfd`. Execution is aborted and state changes are rolled back. +The `REVERT` instruction is introduced at `0xfd`. Execution is aborted, considered as failed, and state changes are rolled back. It expects two stack items, the top item is the `memory_offset` followed by `memory_length`. Both of these can equal to zero. The cost of the `REVERT` instruction equals to that of the `RETURN` instruction. From 937e5bada93a42b89d0387c5672140a773b33f92 Mon Sep 17 00:00:00 2001 From: ethers Date: Mon, 27 Mar 2017 21:50:48 -0400 Subject: [PATCH 0072/1085] status is Final --- EIPS/eip-6.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-6.md b/EIPS/eip-6.md index 000bd4b11f05a..d6d2bc8fdfeb8 100644 --- a/EIPS/eip-6.md +++ b/EIPS/eip-6.md @@ -3,7 +3,7 @@ EIP: 6 Title: Renaming SUICIDE opcode Author: Hudson Jameson - Status: Draft + Status: Final Type: Standards Track Layer: Applications Created: 2015-11-22 From d3ad64034dd416b6ba2c308d793064f0f5a766ba Mon Sep 17 00:00:00 2001 From: ethers Date: Mon, 27 Mar 2017 21:52:03 -0400 Subject: [PATCH 0073/1085] status is Final --- EIPS/eip-7.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-7.md b/EIPS/eip-7.md index edfaaf13aac1b..f9f5059f29bf2 100644 --- a/EIPS/eip-7.md +++ b/EIPS/eip-7.md @@ -2,7 +2,7 @@ EIP: 7 Title: DELEGATECALL Author: Vitalik Buterin - Status: Accepted + Status: Final Type: Homestead feature Created: 2015-11-15 From ccf77936a6b14d1975af287467c62271fd7bb1c9 Mon Sep 17 00:00:00 2001 From: ethers Date: Mon, 27 Mar 2017 21:52:47 -0400 Subject: [PATCH 0074/1085] status is Final --- EIPS/eip-8.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-8.md b/EIPS/eip-8.md index 33faeed328c7d..11e8efcfa4d05 100644 --- a/EIPS/eip-8.md +++ b/EIPS/eip-8.md @@ -3,7 +3,7 @@ EIP: 8 Title: devp2p Forward Compatibility Requirements for Homestead Author: Felix Lange - Status: Accepted + Status: Final Type: Standards Track Layer: Networking Created: 2015-12-18 From 3abd7c1fb4113de2b85f8a8161dedaa81ba7150a Mon Sep 17 00:00:00 2001 From: Micah Zoltu Date: Sat, 1 Apr 2017 15:43:18 -0700 Subject: [PATCH 0075/1085] Adds an EIP for getting logs by a block hash. Closes #234 --- EIPS/EIP-draft-getLogs-by-block-hash.md | 50 +++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 EIPS/EIP-draft-getLogs-by-block-hash.md diff --git a/EIPS/EIP-draft-getLogs-by-block-hash.md b/EIPS/EIP-draft-getLogs-by-block-hash.md new file mode 100644 index 0000000000000..4981e5a47c831 --- /dev/null +++ b/EIPS/EIP-draft-getLogs-by-block-hash.md @@ -0,0 +1,50 @@ +## Preamble +``` +EIP: +Title: Add `blockHash` to JSON-RPC filter options. +Author: Micah Zoltu +Type: +Category: Interface +Status: Draft +Created: 2017-03-24 +``` + +## Simple Summary + +Add an option to JSON-RPC filter options (used by `eth_newFilter` and `eth_getLogs`) that allows specifying the block hash that should be included in the results. This option would be an alternative to `fromBlock`/`toBlock` options. + +## Abstract + +This addition would allow clients to fetch logs for specific blocks, whether those blocks were in the current main chain or not. This resolves some issues that make it difficult/expensive to author robust clients due to the nature of chain reorgs, unreliable network connections and the result set not containing enough details in the empty case. + +## Specification + +The filter options used by `eth_newFilter` would have an additional optional parameter named `blockHash` whose value is a single block hash. The Ethereum node responding to the request would either send back an error if the block hash was not found or it would return the results matching the filter (per normal operation) constrained to the block provided. Internally, this would function (presumably) similar to the `fromBlock` and `toBlock` filter options. + +## Rationale + +A client (dApp) who needs reliable notification of both log additions (on new blocks) and log removals (on chain reorgs) cannot achieve this while relying solely on subscriptions and filters. This is because a combination of a network or remote node failure during a reorg can result in the client getting out of sync with reality. An example of where this can happen with Websockets is when the client opens a web socket connection, sets up a log filter subscription, gets notified of some new logs, then loses the web socket connection, then (while disconnected) a re-org occurs, then the client connects back and establishes a new log filter. In this scenario they will not receive notification of the log removals from the node because they were disconnected when the removals were broadcast and the loss of their connection resulted in the node forgetting about their existence. A similar scenario can be concocted for HTTP clients where between polls for updates, the node goes down and comes back (resulting in loss of filter state) and a re-org also occurs between the same two polls. + +In order to deal with this while still providing a robust mechanism for internal block/log additional/removal, the client can maintain a blockchain internally (last `n` blocks) and only subscribe/poll for new blocks. When a new block is received, the client can reconcile their internal model with the new block, potentially back-filling parents or rolling back/removing blocks from their internal model to get in sync with the node. This can account for any type of disconnect/reorg/outage scenario and also allows the client (as an added benefit) to talk to a cluster of Ethereum nodes (e.g., via round-robin) rather than being tightly coupled to a single node. + +Once the user has a reliable stream of blocks, they can then look at the bloom filter for the new block and if the block *may* have logs of interest they can fetch the filtered logs for that block from the node. The problem that arises is that a re-org may occur between when the client receives the block and when the client fetches the logs for that block. Given the current set of filter options, the client can only ask for logs by block number. In this scenario, the logs they get back will be for a block that *isn't* the block they want the logs for and is instead for a block that was re-orged in (and may not be fully reconciled with the internal client state). This can be partially worked around by looking at the resulting logs themselves and identifying whether or not they are for the block hash requested. However, if the result set is an empty array (no logs fetched) then the client is in a situation where they don't know what block the results are for. The results could have been legitimately empty (bloom filter can yield false positives) for the block in question, or they could be receiving empty logs for a block that they don't know about. At this point, there is no decision the client can make that allows them a guarantee of recovery. They can assume the empty logs were for the correct block, but if they weren't then they will never try to fetch again. This creates a problem if the block was only transiently re-orged out because it may come back before the next block poll so the client will never witness the reorg. They can assume the empty logs were for the wrong block, an refetch them, but they may continue to get empty results putting them right back into the same situation. + +By adding the ability to fetch logs by hash, the client can be guaranteed that if they get a result set, it is for the block in question. If they get an error, then they can take appropriate action (e.g., rollback that block client-side and re-fetch latest). + +## Backwards Compatibility + +The only potential issue here is the `fromBlock` and `toBlock` fields. It wouldn't make sense to include both the hash and the number so it seems like `fromBlock`/`toBlock` should be mutually exclusive with `blockHash`. + +## Test Cases + +`{ "jsonrpc": "2.0", "id": 1, "method": "eth_getLogs", params: [{"blockHash": "0xbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0c"}] }` should return all of the logs for the block with hash `0xbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0c`. If a `topics` field is added to the filter options then a filtered set of logs for that block should be returned. If no block exists with that hash then an error should be returned with a `code` of `-32602`, a `message` of `"Invalid params"` and a `data` of `"Block with hash 0xbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0cbl0c was not found."`. + +## Implementation + +- [ ] Geth +- [ ] Parity +- [ ] EthereumJ + +## Copyright + +Copyright and related rights waived via CC0. From e2f23b3ec717bbadabe5945e75e1d61fda906197 Mon Sep 17 00:00:00 2001 From: Greg Colvin Date: Mon, 10 Apr 2017 11:22:16 -0600 Subject: [PATCH 0076/1085] Update and rename eip-184.md to eip-187.md --- EIPS/{eip-184.md => eip-187.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename EIPS/{eip-184.md => eip-187.md} (99%) diff --git a/EIPS/eip-184.md b/EIPS/eip-187.md similarity index 99% rename from EIPS/eip-184.md rename to EIPS/eip-187.md index 138338bce1b76..645534b7966e5 100644 --- a/EIPS/eip-184.md +++ b/EIPS/eip-187.md @@ -1,5 +1,5 @@ ``` -EIP: 184 +EIP: 187 Title: Subroutines and Static Jumps for the EVM Status: Draft Type: Core From ac31020fcb9124f494c08a9f6ff7e0a03758d052 Mon Sep 17 00:00:00 2001 From: Hudson Jameson Date: Wed, 12 Apr 2017 03:12:17 -0500 Subject: [PATCH 0077/1085] Edited Accepted EIPs See https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2013.md#1-resolution-for-staticcall-purecall-revert-opcode--dynamic-return-discussion-core-devs --- README.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 5dc97637dfbea..dd14406e310d3 100644 --- a/README.md +++ b/README.md @@ -11,15 +11,6 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP * **Deferred** - an EIP that is not being considered for immediate adoption. May be reconsidered in the future for a subsequent hard fork. - -# EIPs under consideration -| Number |Title | Author | Type | Layer | Status | -| ------------------------------------------------------ | ----------------------------------------------------------------------------------- | -------------------- | ----------| ------------| ----------| -| [5](EIPS/eip-5.md) | Gas Usage for `RETURN` and `CALL*` [Note: Unneccessary if 211 is accepted] | Christian Reitwiessner| Standard | Core | Draft | -| [211](https://github.com/ethereum/EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner| Standard | Core | Draft | -| [214](https://github.com/ethereum/EIPs/pull/214) | New opcode STATICCALL | Buterin, Reitwiessner | Standard | Core | Draft | - - # Accepted EIPs (planned for adoption) | Number |Title | Author | Type | Layer | Status | | ------------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ----------| ------------| ----------| @@ -31,6 +22,8 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [196](https://github.com/ethereum/EIPs/pull/213) | Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 | Reitwiessner | Standard | Core | Accepted | | [197](https://github.com/ethereum/EIPs/pull/212) | Precompiled contracts for optimal Ate pairing check on the elliptic curve alt_bn128 | Buterin, Reitwiessner | Standard | Core | Accepted | | [198](https://github.com/ethereum/EIPs/pull/198) | Precompiled contract for bigint modular exponentiation | Vitalik Buterin | Standard | Core | Accepted | +| [211](https://github.com/ethereum/EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner| Standard | Core | Draft | +| [214](https://github.com/ethereum/EIPs/pull/214) | New opcode STATICCALL | Buterin, Reitwiessner | Standard | Core | Draft | # Finalized EIPs (standards that have been adopted) @@ -45,3 +38,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [160](https://github.com/ethereum/EIPs/issues/160) | EXP cost increase | Vitalik Buterin | Standard | Core | Final | | [161](https://github.com/ethereum/EIPs/issues/161) | State trie clearing (invariant-preserving alternative) | Gavin Wood | Standard | Core | Final | | [170](https://github.com/ethereum/EIPs/issues/170) | Contract code size limit | Vitalik Buterin | Standard | Core | Final | + +# EIPs under consideration +| Number |Title | Author | Type | Layer | Status | +| ------------------------------------------------------ | ----------------------------------------------------------------------------------- | -------------------- | ----------| ------------| ----------| From 3c1c997f3d3c042f0da6b983697f29d18794926c Mon Sep 17 00:00:00 2001 From: wighawag Date: Mon, 17 Apr 2017 22:30:40 +0530 Subject: [PATCH 0078/1085] rename to eip-107 --- EIPS/{eip-XXX.md => eip-107.md} | 7 ++++--- EIPS/{eip-XXX => eip-107}/authorization-locked.png | Bin .../{eip-XXX => eip-107}/authorization-password.png | Bin EIPS/{eip-XXX => eip-107}/authorization.png | Bin 4 files changed, 4 insertions(+), 3 deletions(-) rename EIPS/{eip-XXX.md => eip-107.md} (99%) rename EIPS/{eip-XXX => eip-107}/authorization-locked.png (100%) rename EIPS/{eip-XXX => eip-107}/authorization-password.png (100%) rename EIPS/{eip-XXX => eip-107}/authorization.png (100%) diff --git a/EIPS/eip-XXX.md b/EIPS/eip-107.md similarity index 99% rename from EIPS/eip-XXX.md rename to EIPS/eip-107.md index ba13a3caeb0ab..96374488d7ff4 100644 --- a/EIPS/eip-XXX.md +++ b/EIPS/eip-107.md @@ -5,6 +5,7 @@ Created: 2016-06-05 Status: Draft Type: Standard + Category: Interface Abstract @@ -28,19 +29,19 @@ Account unlocked : ----------------- When the account is already unlocked, the user is presented with the following popup for every transaction that the dapp attempts to make : - + Account locked and no "personal" api exposed via rpc: ----------------- When the account is locked and the node do not provide access to account unlocking via its rpc interface, the following popup will be presented. This is not ideal since this require the user to know how to unlock an account: - + Account locked but node exposing the "personal" api via rpc : ----------------- A better option is to ask the user the password but this is only possible if the node allow access to the "personal" api via rpc. In such case the following dialog will be presented to the user so he/she can accept the transaction by providing the password required to unlock the account: - + Specification diff --git a/EIPS/eip-XXX/authorization-locked.png b/EIPS/eip-107/authorization-locked.png similarity index 100% rename from EIPS/eip-XXX/authorization-locked.png rename to EIPS/eip-107/authorization-locked.png diff --git a/EIPS/eip-XXX/authorization-password.png b/EIPS/eip-107/authorization-password.png similarity index 100% rename from EIPS/eip-XXX/authorization-password.png rename to EIPS/eip-107/authorization-password.png diff --git a/EIPS/eip-XXX/authorization.png b/EIPS/eip-107/authorization.png similarity index 100% rename from EIPS/eip-XXX/authorization.png rename to EIPS/eip-107/authorization.png From f412381dc9ec50f0bd3a8ef34d2558e3fb88f81f Mon Sep 17 00:00:00 2001 From: wighawag Date: Wed, 19 Apr 2017 10:31:14 +0530 Subject: [PATCH 0079/1085] set EIP number to 107 --- EIPS/eip-107.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-107.md b/EIPS/eip-107.md index bb45ab7e0ab45..2054368ab0f8d 100644 --- a/EIPS/eip-107.md +++ b/EIPS/eip-107.md @@ -1,5 +1,5 @@
-  EIP: draft
+  EIP: 107
   Title: safe "eth_sendTransaction" authorization via html popup
   Author: Ronan Sandford 
   Created: 2016-06-05

From 4ce5a7ccdc7cd5d6b37c259579953f02f496b7b1 Mon Sep 17 00:00:00 2001
From: Hudson Jameson 
Date: Fri, 21 Apr 2017 01:06:49 -0500
Subject: [PATCH 0080/1085] Changed from Draft to Accepted on 211 and 214

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 47f2fe0694d1d..58fbc6bf358a2 100644
--- a/README.md
+++ b/README.md
@@ -22,8 +22,8 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP
 | [196](https://github.com/ethereum/EIPs/pull/213)        | Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 | Reitwiessner | Standard  | Core        | Accepted  |
 | [197](https://github.com/ethereum/EIPs/pull/212)        | Precompiled contracts for optimal Ate pairing check on the elliptic curve alt_bn128 | Buterin, Reitwiessner | Standard  | Core        | Accepted  |
 | [198](https://github.com/ethereum/EIPs/pull/198)        | Precompiled contract for bigint modular exponentiation				                      | Vitalik Buterin       | Standard  | Core        | Accepted  |
-| [211](https://github.com/ethereum/EIPs/pull/211)        | New opcodes: RETURNDATASIZE and RETURNDATACOPY                                      | Christian Reitwiessner| Standard  | Core        | Draft     |
-| [214](https://github.com/ethereum/EIPs/pull/214)        | New opcode STATICCALL                                                               | Buterin, Reitwiessner | Standard  | Core        | Draft     |
+| [211](https://github.com/ethereum/EIPs/pull/211)        | New opcodes: RETURNDATASIZE and RETURNDATACOPY                                      | Christian Reitwiessner| Standard  | Core        | Accepted     |
+| [214](https://github.com/ethereum/EIPs/pull/214)        | New opcode STATICCALL                                                               | Buterin, Reitwiessner | Standard  | Core        | Accepted     |
 
 
 # Finalized EIPs (standards that have been adopted)

From a63aef39d19438d17d80a04cf29183dce81fc89b Mon Sep 17 00:00:00 2001
From: Alex Beregszaszi 
Date: Sun, 23 Apr 2017 11:28:25 +0100
Subject: [PATCH 0081/1085] Remove ROR/ROL

---
 EIPS/eip-draft_bitwise_shifts.md | 24 +-----------------------
 1 file changed, 1 insertion(+), 23 deletions(-)

diff --git a/EIPS/eip-draft_bitwise_shifts.md b/EIPS/eip-draft_bitwise_shifts.md
index 0f42f9fc0a2c8..3047beba20fbd 100644
--- a/EIPS/eip-draft_bitwise_shifts.md
+++ b/EIPS/eip-draft_bitwise_shifts.md
@@ -59,29 +59,7 @@ Notes:
 - `arg1` is interpreted as unsigned number.
 - If the shift amount is greater or equal 256 the result is 0 if `arg2` is non-negative or -1 if `arg2` is negative.
 
-### `0x1e`: `ROL` (rotate left)
-
-The `ROL` instruction (rotate left) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the second popped value `arg2` circular shifted to the left by the number of bits in the first popped value `arg1`.
-
-```
-(arg1 shl arg2) or (arg1 shr (256 - arg2)
-```
-
-Notes:
-- `arg2 rol arg1` is equivalent of `arg2 rol (arg1 mod 2^256)`
-
-### `0x1f`: `ROR` (rotate right)
-
-The `ROL` instruction (rotate right) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the second popped value `arg2` circular shifted to the right by the number of bits in the first popped value `arg1`.
-
-```
-(arg1 shr arg2) or (arg1 shl (256 - arg2)
-```
-
-Notes:
-- `arg2 ror arg1` is equivalent of `arg2 ror (arg1 mod 2^256)`
-
-The cost of the shift instructions is set at `verylow` tier (3 gas), while the rotations are 12 gas each.
+The cost of the shift instructions is set at `verylow` tier (3 gas).
 
 ## Rationale
 

From 0b3461651f2d6b32a68eba407867ec40cb5bc479 Mon Sep 17 00:00:00 2001
From: Alex Beregszaszi 
Date: Sun, 23 Apr 2017 14:50:20 +0100
Subject: [PATCH 0082/1085] Add link to client support (cpp-ethereum)

---
 EIPS/eip-draft_bitwise_shifts.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/EIPS/eip-draft_bitwise_shifts.md b/EIPS/eip-draft_bitwise_shifts.md
index 3047beba20fbd..0475ba7d9f868 100644
--- a/EIPS/eip-draft_bitwise_shifts.md
+++ b/EIPS/eip-draft_bitwise_shifts.md
@@ -76,7 +76,7 @@ TBA
 ## Implementation
 
 Client support:
-TBA
+- cpp-ethereum: https://github.com/ethereum/cpp-ethereum/pull/4054
 
 Compiler support:
 - Solidity: https://github.com/ethereum/solidity/tree/asm-bitshift

From 7bc447717f4a27be091b4d65fd0488b757c85479 Mon Sep 17 00:00:00 2001
From: Alex Beregszaszi 
Date: Sun, 23 Apr 2017 14:53:46 +0100
Subject: [PATCH 0083/1085] Swap shift operands (value is the top item)

---
 EIPS/eip-draft_bitwise_shifts.md | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/EIPS/eip-draft_bitwise_shifts.md b/EIPS/eip-draft_bitwise_shifts.md
index 0475ba7d9f868..a96665450b777 100644
--- a/EIPS/eip-draft_bitwise_shifts.md
+++ b/EIPS/eip-draft_bitwise_shifts.md
@@ -27,10 +27,10 @@ The following instructions are introduced:
 
 ### `0x1b`: `SHL` (shift left)
 
-The `SHL` instruction (shift left) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the second popped value `arg2` shifted to the left by the number of bits in the first popped value `arg1`. The result is equal to
+The `SHL` instruction (shift left) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the first popped value `arg1` shifted to the left by the number of bits in the second popped value `arg2`. The result is equal to
 
 ```
-(arg2 * 2^arg1) mod 2^256
+(arg1 * 2^arg2) mod 2^256
 ```
 
 Notes:
@@ -38,10 +38,10 @@ Notes:
 
 ### `0x1c`: `SHR` (logical shift right)
 
-The `SHR` instruction (logical shift right) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the second popped value `arg2` shifted to the right by the number of bits in the first popped value `arg1` with zero fill. The result is equal to
+The `SHR` instruction (logical shift right) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the first popped value `arg1` shifted to the right by the number of bits in the second popped value `arg2` with zero fill. The result is equal to
 
 ```
-arg2 udiv 2^arg1
+arg1 udiv 2^arg2
 ```
 
 Notes:
@@ -49,15 +49,15 @@ Notes:
 
 ### `0x1d`: `SAR` (arithmetic shift right)
 
-The `SAR` instruction (arithmetic shift right) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the second popped value `arg2` shifted to the right by the number of bits in the first popped value `arg1` with sign extension. The result is equal to
+The `SAR` instruction (arithmetic shift right) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the first popped value `arg1` shifted to the right by the number of bits in the second popped value `arg2` with sign extension. The result is equal to
 
 ```
-arg2 sdiv 2^arg1
+arg1 sdiv 2^arg2
 ```
 
 Notes:
-- `arg1` is interpreted as unsigned number.
-- If the shift amount is greater or equal 256 the result is 0 if `arg2` is non-negative or -1 if `arg2` is negative.
+- `arg2` is interpreted as unsigned number.
+- If the shift amount (`arg2`) is greater or equal 256 the result is 0 if `arg1` is non-negative or -1 if `arg1` is negative.
 
 The cost of the shift instructions is set at `verylow` tier (3 gas).
 

From 27847a875dae96c412fa71d6021c33a2ac1adcb4 Mon Sep 17 00:00:00 2001
From: Alex Beregszaszi 
Date: Sun, 23 Apr 2017 14:55:19 +0100
Subject: [PATCH 0084/1085] Rename to EIP145

---
 EIPS/{eip-draft_bitwise_shifts.md => eip-145.md} | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
 rename EIPS/{eip-draft_bitwise_shifts.md => eip-145.md} (99%)

diff --git a/EIPS/eip-draft_bitwise_shifts.md b/EIPS/eip-145.md
similarity index 99%
rename from EIPS/eip-draft_bitwise_shifts.md
rename to EIPS/eip-145.md
index a96665450b777..bd2ebc0236ad3 100644
--- a/EIPS/eip-draft_bitwise_shifts.md
+++ b/EIPS/eip-145.md
@@ -1,6 +1,6 @@
 ## Preamble
 
-    EIP: 
+    EIP: 145
     Title: Bitwise shifting instructions in EVM
     Author: Alex Beregszaszi, Paweł Bylica
     Type: Standard Track

From 793f88b6ab748b2ccf9b868ca4e67dbf4aad89c7 Mon Sep 17 00:00:00 2001
From: cdetrio 
Date: Sun, 23 Apr 2017 16:24:24 +0200
Subject: [PATCH 0085/1085] Rename eip-draft_revert_opcode.md to eip-140.md

---
 EIPS/{eip-draft_revert_opcode.md => eip-140.md} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename EIPS/{eip-draft_revert_opcode.md => eip-140.md} (100%)

diff --git a/EIPS/eip-draft_revert_opcode.md b/EIPS/eip-140.md
similarity index 100%
rename from EIPS/eip-draft_revert_opcode.md
rename to EIPS/eip-140.md

From d4f5382f5170e30496e26e93f954ec561b8db1ab Mon Sep 17 00:00:00 2001
From: Alex Beregszaszi 
Date: Sun, 23 Apr 2017 15:43:43 +0100
Subject: [PATCH 0086/1085] Clarify shift amount (arg2)

---
 EIPS/eip-145.md | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/EIPS/eip-145.md b/EIPS/eip-145.md
index bd2ebc0236ad3..91bf3232120e7 100644
--- a/EIPS/eip-145.md
+++ b/EIPS/eip-145.md
@@ -4,7 +4,7 @@
     Title: Bitwise shifting instructions in EVM
     Author: Alex Beregszaszi, Paweł Bylica
     Type: Standard Track
-    Category Core
+    Category: Core
     Status: Draft
     Created: 2017-02-13
 
@@ -34,7 +34,8 @@ The `SHL` instruction (shift left) pops 2 values from the stack, `arg1` and `arg
 ```
 
 Notes:
-- If the shift amount is greater or equal 256 the result is 0.
+- The shift amount (`arg2`) is interpreted as an unsigned number.
+- If the shift amount (`arg2`) is greater or equal 256 the result is 0.
 
 ### `0x1c`: `SHR` (logical shift right)
 
@@ -45,7 +46,8 @@ arg1 udiv 2^arg2
 ```
 
 Notes:
-- If the shift amount is greater or equal 256 the result is 0.
+- The shift amount (`arg2`) is interpreted as an unsigned number.
+- If the shift amount (`arg2`) is greater or equal 256 the result is 0.
 
 ### `0x1d`: `SAR` (arithmetic shift right)
 
@@ -56,7 +58,7 @@ arg1 sdiv 2^arg2
 ```
 
 Notes:
-- `arg2` is interpreted as unsigned number.
+- The shift amount (`arg2`) is interpreted as an unsigned number.
 - If the shift amount (`arg2`) is greater or equal 256 the result is 0 if `arg1` is non-negative or -1 if `arg1` is negative.
 
 The cost of the shift instructions is set at `verylow` tier (3 gas).

From 66acbb20a75a2f90ccbdb2ef89a39f60b8b26791 Mon Sep 17 00:00:00 2001
From: Alex Beregszaszi 
Date: Sun, 23 Apr 2017 16:40:06 +0100
Subject: [PATCH 0087/1085] Add meta EIP for Homestead

---
 EIPS/eip-draft_hfmeta_homestead.md | 31 ++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 EIPS/eip-draft_hfmeta_homestead.md

diff --git a/EIPS/eip-draft_hfmeta_homestead.md b/EIPS/eip-draft_hfmeta_homestead.md
new file mode 100644
index 0000000000000..4aa33d4df908d
--- /dev/null
+++ b/EIPS/eip-draft_hfmeta_homestead.md
@@ -0,0 +1,31 @@
+## Preamble
+
+    EIP: 
+    Title: Hardfork Meta: Homestead
+    Author: Alex Beregszaszi
+    Type: Standard Track
+    Category: Core
+    Status: Final
+    Created: 23/04/2017
+    Requires: 2, 6, 7, 8
+
+## Abstract
+
+This specifies the changes included in the hard fork named Homestead.
+
+## Specification
+
+- Codename: Homestead
+- Activation:
+  - Block >= 1,150,000 on Mainnet
+  - Block >= 494,000 on Morden
+  - Block >= 0 on future testnets
+- Included EIPs:
+  - EIP 2 (Homestead Hard-fork Changes)
+  - EIP 6 (Renaming Suicide Opcode)
+  - EIP 7 (DELEGATECALL)
+  - EIP 8 (devp2p Forward Compatibility Requirements for Homestead)
+
+## Copyright
+
+Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

From ecf59d8f8a148afef2537d4b1730111034877eb4 Mon Sep 17 00:00:00 2001
From: Greg Colvin 
Date: Tue, 25 Apr 2017 11:25:07 +0200
Subject: [PATCH 0088/1085] Create SubroutinesAndStaticJumps.md

---
 SubroutinesAndStaticJumps.md | 372 +++++++++++++++++++++++++++++++++++
 1 file changed, 372 insertions(+)
 create mode 100644 SubroutinesAndStaticJumps.md

diff --git a/SubroutinesAndStaticJumps.md b/SubroutinesAndStaticJumps.md
new file mode 100644
index 0000000000000..7087b31116c55
--- /dev/null
+++ b/SubroutinesAndStaticJumps.md
@@ -0,0 +1,372 @@
+```
+EIP: TBD
+Title: Subroutines and Static Jumps for the EVM
+Status: Draft
+Type: Core
+Author: Greg Colvin, Paweł Bylica, Christian Reitwiessner 
+Created: 2016-12-10
+Edited: 2016-29-12
+```
+## Abstract
+
+This EIP introduces new EVM opcodes and conditions on EVM code to support subroutines and static jumps, disallow dynamic jumps, and thereby make EVM code amenable to linear-time static analysis.  This will provide for better compilation, interpretation, transpilation, and formal analysis of EVM code.
+
+## MOTIVATION
+
+All current implementations of the Ethereum Virtual Machine, including the just-in-time compilers, are much too slow. This proposal identifies a major reason for this and proposes changes to the EVM specification to address the problem.
+
+In particular, it imposes restrictions on current EVM code and proposes new instructions to help provide for
+* better-optimized compilation to native code
+* faster interpretation
+* faster transpilation to eWASM
+* better compilation from other languages,
+   including eWASM and Solidity
+* better formal analysis tools
+
+These goals are achieved by
+* disallowing dynamic jumps
+* introducing subroutines - jumps with return support
+* disallowing pathological control flow and uses of the stack
+
+We also propose to validate - in linear time - that EVM contracts correctly use subroutines, avoid misuse of the stack, and meet other safety conditions _before_ placing them on the blockchain.  Validated code precludes most runtime exceptions and the need to test for them.  And well-behaved control flow and use of the stack makes life easier for interpreters, compilers, formal analysis, and other tools.
+
+## THE PROBLEM
+
+Currently the EVM supports dynamic jumps, where the address to jump to is an argument on the stack. These dynamic jumps obscure the structure of the code and thus mostly inhibit control- and data-flow analysis.  This puts the quality and speed of optimized compilation fundamentally at odds.  Further, since every jump can potentially be to any jump destination in the code, the number of possible paths through the code goes up as the product of the number of jumps by the number of destinations, as does the time complexity of static analysis.  But absent dynamic jumps code can be statically analyzed in linear time.
+
+Static analysis includes validation, and much of optimization, compilation, transpilation, and formal analysis; every part of the tool chain benefits when linear-time analysis is available.  In particular, faster control-flow analysis means faster compilation of EVM code to native code, and better data-flow analysis can help the compiler and the interpreter better track the size of the values on the stack and use native 64- and 32-bit operations when possible.  Also, conditions which are checked at validation time don’t have to be checked repeatedly at runtime.
+
+Note that analyses of a contract’s bytecode before execution - such as optimizations performed before interpretation, JIT compilation, and on-the-fly machine code generation - must be efficient and linear-time. Otherwise, specially crafted contracts can be used as attack vectors against clients that use static analysis of EVM code before the creation or execution of contracts.
+
+## PROPOSAL
+
+We propose to deprecate two existing instructions - `JUMP` and `JUMPI`. They take their argument on the stack, which means that unless the value is constant they can jump to any `JUMPDEST`.  (In simple cases like `PUSH 0 JUMP` the value on the stack can be known to be constant, but in general it's difficult.)  We must nonetheless continue to support them in old code.
+
+Having deprecated `JUMP` and `JUMPI`, we propose new instructions to support their legitimate uses.
+
+### Preliminaries
+
+These forms
+* `INSTRUCTION x,`
+* `INSTRUCTION x, y`
+* `INSTRUCTION n, x ...`
+
+name instructions with one, two, and two or more arguments, respectively.  An instruction is represented in the bytecode as a single-byte opcode.  The arguments are laid out as immediate data bytes following the opcode.  The size and encoding of immediate data fields is open to change.  In particular, easily-parsed variable-length encodings might prove useful for bytecode offsets - which are in practice small but in principle can be large.
+
+### Primitives
+
+The two most important uses of `JUMP` and `JUMPI` are static jumps and return jumps. Conditional and unconditional static jumps are the mainstay of control flow.  Return jumps are implemented as a dynamic jump to a return address pushed on the stack.  With the combination of a static jump and a dynamic return jump you can - and Solidity does - implement subroutines.  The problem is that static analysis cannot tell the one place the return jump is going, so it must analyze every possibility.
+
+Static jumps are provided by
+* `JUMPTO jump_target`
+* `JUMPIF jump_target`
+which are the same as `JUMP` and `JUMPI` except that they jump to an immediate `jump_target`, given as four immediate bytes, rather than an address on the stack.
+
+To support subroutines, `BEGINSUB`, `JUMPSUB`, and `RETURNSUB` are provided.  Brief descriptions follow, and full semantics are given below.
+
+* `BEGINSUB n_args, n_results`
+marks the **single** entry to a subroutine.  `n_args` items are taken off of the stack at entry to, and `n_results` items are placed on the stack at return from the subroutine. `n_args` and `n_results` are given as one immediate byte each.  The bytecode for a subroutine ends at the next `BEGINSUB` instruction (or `BEGINDATA`, below) or at the end of the bytecode.
+
+* `JUMPSUB jump_target`
+jumps to an immediate subroutine address, given as four immediate bytes.
+
+* `RETURNSUB`
+returns from the current subroutine to the instruction following the JUMPSUB that entered it.
+
+These five simple instructions form the primitives of the proposal.
+
+### Data
+
+In order to validate subroutines, EVM bytecode must be sequentially scanned matching jumps to their destinations.  Since creation code has to contain the runtime code as data, that code might not correctly validate in the creation context and also does not have to be validated prior to the execution of the creation code. Because of that, there needs to be a way to place data into the bytecode that will be skipped over and not validated.  Such data will prove useful for other purposes as well.
+
+* `BEGINDATA`
+specifies that all of the following bytes to the end of the bytecode are data, and not reachable code.
+
+### Indirect Jumps
+
+The primitive operations provide for static jumps.  Dynamic jumps are also used for O(1) indirection: an address to jump to is selected to push on the stack and be jumped to.  So we also propose two more instructions to provide for constrained indirection.  We support these with vectors of `JUMPDEST` or `BEGINSUB` offsets stored inline, which can be selected with an index on the stack.  That constrains validation to a specified subset of all possible destinations.  The danger of quadratic blow up is avoided because it takes as much space to store the jump vectors as it does to code the worst case exploit. 
+
+Dynamic jumps to a `JUMPDEST` are used to implement O(1) jumptables, which are useful for dense switch statements, and are implemented as instructions similar to this one on most CPUs.
+* `JUMPV n, jumpdest ...`
+jumps to one of a vector of `n` `JUMPDEST` offsets via a zero-based index on the stack.  The vector is stored inline in the bytecode.  If the index is greater than or equal to `n - 1` the last (default) offset is used.  `n` is given as four immediate bytes, all `JUMPDEST` offsets as four immediate bytes each.
+
+Dynamic jumps to a `BEGINSUB` are used to implement O(1) virtual functions and callbacks, which take just two pointer dereferences on most CPUs.
+* `JUMPSUBV n, beginsub ...`
+jumps to one of a vector of `n` `BEGINSUB` offsets via a zero-based index on the stack.  The vector is stored inline in the bytecode, MSB-first.  If the index is greater than or equal to `n - 1` the last (default) offset is used.  `n` is given as four immediate bytes, the `n` offsets as four immediate bytes each.
+
+`JUMPV` and `JUMPSUBV` are not strictly necessary.  They provide O(1) operations that can be replaced by O(n) or O(log n) EVM code using static jumps, but that code will be slower, larger and use more gas for things that can and should be fast, small, and cheap, and that are directly supported in WASM with br_table and call_indirect.
+
+### Variable Access
+
+These operations provide convenient access to subroutine parameters and other variables at fixed stack offsets within a subroutine.
+
+* `PUTLOCAL n`
+Pops the top value on the stack and copies it to local variable `n`.
+
+* `GETLOCAL n`
+Pushes the value of local variable `n` on the EVM stack.
+
+Local variable `n` is `FP[-n]` as defined below.
+
+## SEMANTICS
+
+Jumps to and returns from subroutines are described here in terms of
+* the EVM data stack, (as defined in the [Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf) usually just called “the stack”,
+* a return stack of `JUMPSUB` and `JUMPSUBV` offsets, and
+* a frame stack of frame pointers.
+
+We will adopt the following conventions to describe the machine state:
+* The _program counter_ `PC` is (as usual) the byte offset of the currently executing instruction.
+* The _stack pointer_ `SP` corresponds to the number of items on the stack - the _stack size_.  As a negative offset it addresses the current top of the stack of data values, where new items are pushed.
+* The _frame pointer_ `FP` is set to `SP + n_args` at entry to the currently executing subroutine.
+* The _stack items_ between the frame pointer and the current stack pointer are called the _frame_.
+* The current number of items in the frame, `FP - SP`, is the _frame size_.
+
+Defining the frame pointer so as to include the arguments is unconventional, but better fits our stack semantics and simplifies the remainder of the proposal.
+
+The frame pointer and return stacks are internal to the subroutine mechanism, and not directly accessible to the program.  This is necessary to prevent the program from modifying its state in ways that could be invalid.
+
+The first instruction of an array of EVM bytecode begins execution of a _main_ routine with no arguments, `SP` and `FP` set to 0, and with one value on the return stack - `code size - 1`. (Executing the virtual byte of 0 after this offset causes an EVM to stop.  Thus executing a `RETURNSUB` with no prior `JUMPSUB` or `JUMBSUBV` - that is, in the _main_ routine - executes a `STOP`.)
+
+Execution of a subroutine begins with `JUMPSUB` or `JUMPSUBV`, which
+* push `PC` on the return stack,
+* push `FP` on the frame stack,
+thus suspending execution of the current subroutine, and
+* set `FP` to `SP + n_args`, and
+* set `PC` to the specified `BEGINSUB` address,
+thus beginning execution of the new subroutine.
+(The _main_ routine is not addressable by `JUMPSUB` instructions.)
+
+Execution of a subroutine is suspended during and resumed after execution of nested subroutines, and ends upon encountering a `RETURNSUB`, which
+* sets `FP` to the top of the virtual frame stack and pops the stack, and
+* sets `PC` to top of the return stack and pops the stack
+* advances `PC` to the next instruction
+thus resuming execution of the enclosing subroutine or _main_ program.
+A `STOP or `RETURN` also ends the execution of a subroutine.
+
+## VALIDITY
+
+We would like to consider EVM code valid if and only if no execution of the program can lead to an exceptional halting state.  But we must and will validate code in linear time.  So our validation does not consider the code’s data and computations, only its control flow and stack use.  This means we will reject programs with invalid code paths, even if those paths cannot be executed at runtime.  Most conditions can be validated, and will not need to be checked at runtime; the exceptions are sufficient gas and sufficient stack.  So some false negatives and runtime checks are the price we pay for linear time validation.
+
+_Execution_ is as defined in the Yellow Paper - a sequence of changes in the EVM state.  The conditions on valid code are preserved by state changes.  At runtime, if execution of an instruction would violate a condition the execution is in an exceptional halting state.  The yellow paper defines five such states.
+>1  Insufficient gas
+
+>2  More than 1024 stack items
+
+>3  Insufficient stack items
+
+>4  Invalid jump destination
+
+>5  Invalid instruction
+
+We propose to expand and extend the Yellow Paper conditions to handle the new instructions we propose. 
+
+To handle the return stack we expand the conditions on stack size:
+>2a  The size of the data stack does not exceed 1024.
+
+>2b  The size of the return stack does not exceed 1024.
+
+Given our more detailed description of the data stack we restate condition 3 - stack underflow - as
+>3  `SP` must be less than or equal to `FP`
+
+Since the various `DUP` and `SWAP` operations are formalized as taking items off the stack and putting them back on, this prevents `DUP` and `SWAP` from accessing data below the frame pointer, since taking too many items off of the stack would mean that `SP` is less than `FP`.
+
+To handle the new jump instructions and subroutine boundaries we expand the conditions on jumps and jump destinations.
+>4a  `JUMPTO`, `JUMPIF`, and `JUMPV` address only `JUMPDEST` instructions.
+
+>4b  `JUMPSUB` and `JUMPSUBV` address only `BEGINSUB` instructions.
+
+>4c  `JUMP` instructions do not address instructions outside of the subroutine they occur in.
+
+We have two new conditions on execution to ensure consistent use of the stack by subroutines:
+>6  For `JUMPSUB` and `JUMPSUBV` the frame size is at least the `n_args` of the `BEGINSUB`(s) to jump to.
+
+>7  For `RETURNSUB` the frame size is equal to the `n_results` of the enclosing `BEGINSUB`.
+
+Finally, we have one condition that prevents pathological uses of the stack:
+>8  For every instruction in the code the frame size is constant.
+
+In practice, we must test at runtime for conditions 1 and 2 - sufficient gas and sufficient stack.  We don’t know how much gas there will be, we don’t know how deep a recursion may go, and analysis of stack depth even for non-recursive programs is non-trivial.
+
+All of the remaining conditions we validate statically.
+
+## VALIDATION
+
+Validation comprises two tasks:
+* Checking that jump destinations are correct and instructions valid.
+* Checking that subroutines satisfy the conditions on control flow and stack use.
+
+We sketch out these two validation functions in pseudo-C below.   To simplify the presentation only the five primitives are handled (`JUMPV` and `JUMPSUBV` would just add more complexity to loop over their vectors), we assume helper functions for extracting instruction arguments from immediate data and managing the stack pointer and program counter, and some optimizations are forgone.
+
+### Validating jumps
+
+Validating that jumps are to valid addresses takes two sequential passes over the bytecode - one to build sets of jump destinations and subroutine entry points, another to check that addresses jumped to are in the appropriate sets.
+```
+    bytecode[code_size]   // contains EVM bytecode to validate
+    is_sub[code_size]     // is there a BEGINSUB at PC?
+    is_dest[code_size]    // is there a JUMPDEST at PC?
+    sub_for_pc[code_size] // which BEGINSUB is PC in?
+    
+    bool validate_jumps(PC)
+    {
+        current_sub = PC
+
+        // build sets of BEGINSUBs and JUMPDESTs
+        for (PC = 0; instruction = bytecode[PC]; PC = advance_pc(PC))
+        {
+            if instruction is invalid
+                return false
+            if instruction is BEGINDATA
+                return true
+            if instruction is BEGINSUB
+                is_sub[PC] = true
+                current_sub = PC
+                sub_for_pc[PC] = current_sub
+            if instruction is JUMPDEST
+                is_dest[PC] = true
+            sub_for_pc[PC] = current_sub
+        }
+        
+        // check that targets are in subroutine
+        for (PC = 0; instruction = bytecode[PC]; PC = advance_pc(PC))
+        {
+            if instruction is BEGINDATA
+                break;
+            if instruction is BEGINSUB
+                current_sub = PC
+            if instruction is JUMPSUB
+                if is_sub[jump_target(PC)] is false
+                    return false
+            if instruction is JUMPTO or JUMPIF
+                if is_dest[jump_target(PC)] is false
+                    return false
+            if sub_for_pc[PC] is not current_sub
+                return false
+       }
+        return true
+    }
+```
+Note that code like this is already run by EVMs to check dynamic jumps, including building the jump destination set every time a contract is run, and doing a lookup in the jump destination set before every jump.
+
+### Validating subroutines
+
+This function can be seen as a symbolic execution of a subroutine in the EVM code, where only the effect of the instructions on the state being validated is computed.  Thus the structure of this function is very similar to an EVM interpreter.  This function can also be seen as an acyclic traversal of the directed graph formed by taking instructions as vertexes and sequential and branching connections as edges, checking conditions along the way.  The traversal is accomplished via recursion, and cycles are broken by returning when a vertex which has already been visited is reached.  The time complexity of this traversal is O(n-vertices + n-edges)
+
+The basic approach is to call `validate_subroutine(i, 0, 0)`, for _i_ equal to the first instruction in the EVM code through each `BEGINDATA` offset.  `validate_subroutine()` traverses instructions sequentially, recursing when `JUMP` and `JUMPI` instructions are encountered.  When a destination is reached that has been visited before it returns, thus breaking cycles.  It returns true if the subroutine is valid, false otherwise.
+
+```
+    bytecode[code_size]     // contains EVM bytecode to validate
+    frame_size[code_size ]  // is filled with -1
+
+    // we validate each subroutine individually, as if at top level
+    // * PC is the offset in the code to start validating at
+    // * return_pc is the top PC on return stack that RETURNSUB returns to
+    // * at top level FP = 0, so SP is both the frame size and the stack size
+    validate_subroutine(PC, return_pc, SP)
+    {
+        // traverse code sequentially, recurse for jumps
+        while true
+        {
+            instruction = bytecode[PC]
+
+            // if frame size set we have been here before
+            if frame_size[PC] >= 0
+            {
+                // check for constant frame size
+                if instruction is JUMPDEST
+                    if SP != frame_size[PC]
+                        return false
+
+                // return to break cycle
+                return true
+            }
+            frame_size[PC] = SP
+
+            // effect of instruction on stack
+            n_removed = removed_items(instructions)
+            n_added = added_items(instruction)
+
+            // check for stack underflow
+            if SP < n_removed
+                return false
+
+            // net effect of removing and adding stack items
+            SP -= n_removed
+            SP += n_added
+
+            // check for stack overflow
+            if SP > 1024
+                return false
+
+            if instruction is STOP, RETURN, or SUICIDE
+                return true	   
+
+            // violates single entry
+            if instruction is BEGINSUB
+                 return false
+
+            // return to top or from recursion to JUMPSUB
+            if instruction is RETURNSUB
+                break;
+
+            if instruction is JUMPSUB
+            {
+                // check for enough arguments
+                sub_pc = jump_target(PC)
+                if SP < n_args(sub_pc)
+                    return false
+                return true
+            }
+
+            // reset PC to destination of jump
+            if instruction is JUMPTO
+            {
+                PC = jump_target(PC)
+                continue 
+            }
+
+            // recurse to jump to code to validate 
+            if instruction is JUMPIF
+            {
+                if not validate_subroutine(jump_target(PC), return_pc, SP)
+                    return false
+            }
+
+            // advance PC according to instruction
+            PC = advance_pc(PC)
+        }
+
+        // check for right number of results
+        if SP != n_results(return_pc)
+            return false
+        return true
+    }
+```
+
+### COSTS & CODES
+
+All of the instructions are O(1) with a small constant, requiring just a few machine operations each, whereas a `JUMP` or `JUMPI` must do an O(log n) binary search of an array of `JUMPDEST` offsets before every jump. With the cost of `JUMPI` being _high_ and the cost of `JUMP` being _mid_, we suggest the cost of `JUMPV` and `JUMPSUBV` should be _mid_, `JUMPSUB` and `JUMPIF` should be _low_, and`JUMPTO` should be _verylow_.  Measurement will tell.
+
+We tentatively suggest the following opcodes:
+```
+0xB0 JUMPTO
+0xB1 JUMPIF
+0XB2 JUMPSUB
+0xB4 JUMPSUBV
+0xB5 BEGINSUB
+0xB6 BEGINDATA
+0xB8 RETURNSUB
+0xB9 PUTLOCAL
+0xBA GETLOCAL
+```
+
+### GETTING THERE FROM HERE
+
+These changes would need to be implemented in phases at decent intervals:
+>1 If this EIP is accepted, invalid code should be deprecated. Tools should stop generating invalid code, users should stop writing it, and clients should warn about loading it.
+
+>2 A later hard fork would require clients to place only valid code on the block chain.  Note that despite the fork old EVM code will still need to be supported indefinitely.
+
+If desired, the period of deprecation can be extended indefinitely by continuing to accept code not versioned as new - but without validation.  That is, by delaying step 2.  Since we must continue to run old code this is not technically difficult. 
+
+Implementation of this proposal need not be difficult,  At the least, interpreters can simply be extended with the new opcodes and run unchanged otherwise.  The new opcodes require only stacks for the frame pointers and return offsets and the few pushes, pops, and assignments described above.  JIT code can use native calls.  Further optimizations include minimizing runtime checks for exceptions and taking advantage of validated code wherever possible.

From 09cf8ab755fd5d8a03cd3dbb3d0456767f2a82e5 Mon Sep 17 00:00:00 2001
From: Greg Colvin 
Date: Tue, 25 Apr 2017 11:26:29 +0200
Subject: [PATCH 0089/1085] Delete SubroutinesAndStaticJumps.md

---
 SubroutinesAndStaticJumps.md | 372 -----------------------------------
 1 file changed, 372 deletions(-)
 delete mode 100644 SubroutinesAndStaticJumps.md

diff --git a/SubroutinesAndStaticJumps.md b/SubroutinesAndStaticJumps.md
deleted file mode 100644
index 7087b31116c55..0000000000000
--- a/SubroutinesAndStaticJumps.md
+++ /dev/null
@@ -1,372 +0,0 @@
-```
-EIP: TBD
-Title: Subroutines and Static Jumps for the EVM
-Status: Draft
-Type: Core
-Author: Greg Colvin, Paweł Bylica, Christian Reitwiessner 
-Created: 2016-12-10
-Edited: 2016-29-12
-```
-## Abstract
-
-This EIP introduces new EVM opcodes and conditions on EVM code to support subroutines and static jumps, disallow dynamic jumps, and thereby make EVM code amenable to linear-time static analysis.  This will provide for better compilation, interpretation, transpilation, and formal analysis of EVM code.
-
-## MOTIVATION
-
-All current implementations of the Ethereum Virtual Machine, including the just-in-time compilers, are much too slow. This proposal identifies a major reason for this and proposes changes to the EVM specification to address the problem.
-
-In particular, it imposes restrictions on current EVM code and proposes new instructions to help provide for
-* better-optimized compilation to native code
-* faster interpretation
-* faster transpilation to eWASM
-* better compilation from other languages,
-   including eWASM and Solidity
-* better formal analysis tools
-
-These goals are achieved by
-* disallowing dynamic jumps
-* introducing subroutines - jumps with return support
-* disallowing pathological control flow and uses of the stack
-
-We also propose to validate - in linear time - that EVM contracts correctly use subroutines, avoid misuse of the stack, and meet other safety conditions _before_ placing them on the blockchain.  Validated code precludes most runtime exceptions and the need to test for them.  And well-behaved control flow and use of the stack makes life easier for interpreters, compilers, formal analysis, and other tools.
-
-## THE PROBLEM
-
-Currently the EVM supports dynamic jumps, where the address to jump to is an argument on the stack. These dynamic jumps obscure the structure of the code and thus mostly inhibit control- and data-flow analysis.  This puts the quality and speed of optimized compilation fundamentally at odds.  Further, since every jump can potentially be to any jump destination in the code, the number of possible paths through the code goes up as the product of the number of jumps by the number of destinations, as does the time complexity of static analysis.  But absent dynamic jumps code can be statically analyzed in linear time.
-
-Static analysis includes validation, and much of optimization, compilation, transpilation, and formal analysis; every part of the tool chain benefits when linear-time analysis is available.  In particular, faster control-flow analysis means faster compilation of EVM code to native code, and better data-flow analysis can help the compiler and the interpreter better track the size of the values on the stack and use native 64- and 32-bit operations when possible.  Also, conditions which are checked at validation time don’t have to be checked repeatedly at runtime.
-
-Note that analyses of a contract’s bytecode before execution - such as optimizations performed before interpretation, JIT compilation, and on-the-fly machine code generation - must be efficient and linear-time. Otherwise, specially crafted contracts can be used as attack vectors against clients that use static analysis of EVM code before the creation or execution of contracts.
-
-## PROPOSAL
-
-We propose to deprecate two existing instructions - `JUMP` and `JUMPI`. They take their argument on the stack, which means that unless the value is constant they can jump to any `JUMPDEST`.  (In simple cases like `PUSH 0 JUMP` the value on the stack can be known to be constant, but in general it's difficult.)  We must nonetheless continue to support them in old code.
-
-Having deprecated `JUMP` and `JUMPI`, we propose new instructions to support their legitimate uses.
-
-### Preliminaries
-
-These forms
-* `INSTRUCTION x,`
-* `INSTRUCTION x, y`
-* `INSTRUCTION n, x ...`
-
-name instructions with one, two, and two or more arguments, respectively.  An instruction is represented in the bytecode as a single-byte opcode.  The arguments are laid out as immediate data bytes following the opcode.  The size and encoding of immediate data fields is open to change.  In particular, easily-parsed variable-length encodings might prove useful for bytecode offsets - which are in practice small but in principle can be large.
-
-### Primitives
-
-The two most important uses of `JUMP` and `JUMPI` are static jumps and return jumps. Conditional and unconditional static jumps are the mainstay of control flow.  Return jumps are implemented as a dynamic jump to a return address pushed on the stack.  With the combination of a static jump and a dynamic return jump you can - and Solidity does - implement subroutines.  The problem is that static analysis cannot tell the one place the return jump is going, so it must analyze every possibility.
-
-Static jumps are provided by
-* `JUMPTO jump_target`
-* `JUMPIF jump_target`
-which are the same as `JUMP` and `JUMPI` except that they jump to an immediate `jump_target`, given as four immediate bytes, rather than an address on the stack.
-
-To support subroutines, `BEGINSUB`, `JUMPSUB`, and `RETURNSUB` are provided.  Brief descriptions follow, and full semantics are given below.
-
-* `BEGINSUB n_args, n_results`
-marks the **single** entry to a subroutine.  `n_args` items are taken off of the stack at entry to, and `n_results` items are placed on the stack at return from the subroutine. `n_args` and `n_results` are given as one immediate byte each.  The bytecode for a subroutine ends at the next `BEGINSUB` instruction (or `BEGINDATA`, below) or at the end of the bytecode.
-
-* `JUMPSUB jump_target`
-jumps to an immediate subroutine address, given as four immediate bytes.
-
-* `RETURNSUB`
-returns from the current subroutine to the instruction following the JUMPSUB that entered it.
-
-These five simple instructions form the primitives of the proposal.
-
-### Data
-
-In order to validate subroutines, EVM bytecode must be sequentially scanned matching jumps to their destinations.  Since creation code has to contain the runtime code as data, that code might not correctly validate in the creation context and also does not have to be validated prior to the execution of the creation code. Because of that, there needs to be a way to place data into the bytecode that will be skipped over and not validated.  Such data will prove useful for other purposes as well.
-
-* `BEGINDATA`
-specifies that all of the following bytes to the end of the bytecode are data, and not reachable code.
-
-### Indirect Jumps
-
-The primitive operations provide for static jumps.  Dynamic jumps are also used for O(1) indirection: an address to jump to is selected to push on the stack and be jumped to.  So we also propose two more instructions to provide for constrained indirection.  We support these with vectors of `JUMPDEST` or `BEGINSUB` offsets stored inline, which can be selected with an index on the stack.  That constrains validation to a specified subset of all possible destinations.  The danger of quadratic blow up is avoided because it takes as much space to store the jump vectors as it does to code the worst case exploit. 
-
-Dynamic jumps to a `JUMPDEST` are used to implement O(1) jumptables, which are useful for dense switch statements, and are implemented as instructions similar to this one on most CPUs.
-* `JUMPV n, jumpdest ...`
-jumps to one of a vector of `n` `JUMPDEST` offsets via a zero-based index on the stack.  The vector is stored inline in the bytecode.  If the index is greater than or equal to `n - 1` the last (default) offset is used.  `n` is given as four immediate bytes, all `JUMPDEST` offsets as four immediate bytes each.
-
-Dynamic jumps to a `BEGINSUB` are used to implement O(1) virtual functions and callbacks, which take just two pointer dereferences on most CPUs.
-* `JUMPSUBV n, beginsub ...`
-jumps to one of a vector of `n` `BEGINSUB` offsets via a zero-based index on the stack.  The vector is stored inline in the bytecode, MSB-first.  If the index is greater than or equal to `n - 1` the last (default) offset is used.  `n` is given as four immediate bytes, the `n` offsets as four immediate bytes each.
-
-`JUMPV` and `JUMPSUBV` are not strictly necessary.  They provide O(1) operations that can be replaced by O(n) or O(log n) EVM code using static jumps, but that code will be slower, larger and use more gas for things that can and should be fast, small, and cheap, and that are directly supported in WASM with br_table and call_indirect.
-
-### Variable Access
-
-These operations provide convenient access to subroutine parameters and other variables at fixed stack offsets within a subroutine.
-
-* `PUTLOCAL n`
-Pops the top value on the stack and copies it to local variable `n`.
-
-* `GETLOCAL n`
-Pushes the value of local variable `n` on the EVM stack.
-
-Local variable `n` is `FP[-n]` as defined below.
-
-## SEMANTICS
-
-Jumps to and returns from subroutines are described here in terms of
-* the EVM data stack, (as defined in the [Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf) usually just called “the stack”,
-* a return stack of `JUMPSUB` and `JUMPSUBV` offsets, and
-* a frame stack of frame pointers.
-
-We will adopt the following conventions to describe the machine state:
-* The _program counter_ `PC` is (as usual) the byte offset of the currently executing instruction.
-* The _stack pointer_ `SP` corresponds to the number of items on the stack - the _stack size_.  As a negative offset it addresses the current top of the stack of data values, where new items are pushed.
-* The _frame pointer_ `FP` is set to `SP + n_args` at entry to the currently executing subroutine.
-* The _stack items_ between the frame pointer and the current stack pointer are called the _frame_.
-* The current number of items in the frame, `FP - SP`, is the _frame size_.
-
-Defining the frame pointer so as to include the arguments is unconventional, but better fits our stack semantics and simplifies the remainder of the proposal.
-
-The frame pointer and return stacks are internal to the subroutine mechanism, and not directly accessible to the program.  This is necessary to prevent the program from modifying its state in ways that could be invalid.
-
-The first instruction of an array of EVM bytecode begins execution of a _main_ routine with no arguments, `SP` and `FP` set to 0, and with one value on the return stack - `code size - 1`. (Executing the virtual byte of 0 after this offset causes an EVM to stop.  Thus executing a `RETURNSUB` with no prior `JUMPSUB` or `JUMBSUBV` - that is, in the _main_ routine - executes a `STOP`.)
-
-Execution of a subroutine begins with `JUMPSUB` or `JUMPSUBV`, which
-* push `PC` on the return stack,
-* push `FP` on the frame stack,
-thus suspending execution of the current subroutine, and
-* set `FP` to `SP + n_args`, and
-* set `PC` to the specified `BEGINSUB` address,
-thus beginning execution of the new subroutine.
-(The _main_ routine is not addressable by `JUMPSUB` instructions.)
-
-Execution of a subroutine is suspended during and resumed after execution of nested subroutines, and ends upon encountering a `RETURNSUB`, which
-* sets `FP` to the top of the virtual frame stack and pops the stack, and
-* sets `PC` to top of the return stack and pops the stack
-* advances `PC` to the next instruction
-thus resuming execution of the enclosing subroutine or _main_ program.
-A `STOP or `RETURN` also ends the execution of a subroutine.
-
-## VALIDITY
-
-We would like to consider EVM code valid if and only if no execution of the program can lead to an exceptional halting state.  But we must and will validate code in linear time.  So our validation does not consider the code’s data and computations, only its control flow and stack use.  This means we will reject programs with invalid code paths, even if those paths cannot be executed at runtime.  Most conditions can be validated, and will not need to be checked at runtime; the exceptions are sufficient gas and sufficient stack.  So some false negatives and runtime checks are the price we pay for linear time validation.
-
-_Execution_ is as defined in the Yellow Paper - a sequence of changes in the EVM state.  The conditions on valid code are preserved by state changes.  At runtime, if execution of an instruction would violate a condition the execution is in an exceptional halting state.  The yellow paper defines five such states.
->1  Insufficient gas
-
->2  More than 1024 stack items
-
->3  Insufficient stack items
-
->4  Invalid jump destination
-
->5  Invalid instruction
-
-We propose to expand and extend the Yellow Paper conditions to handle the new instructions we propose. 
-
-To handle the return stack we expand the conditions on stack size:
->2a  The size of the data stack does not exceed 1024.
-
->2b  The size of the return stack does not exceed 1024.
-
-Given our more detailed description of the data stack we restate condition 3 - stack underflow - as
->3  `SP` must be less than or equal to `FP`
-
-Since the various `DUP` and `SWAP` operations are formalized as taking items off the stack and putting them back on, this prevents `DUP` and `SWAP` from accessing data below the frame pointer, since taking too many items off of the stack would mean that `SP` is less than `FP`.
-
-To handle the new jump instructions and subroutine boundaries we expand the conditions on jumps and jump destinations.
->4a  `JUMPTO`, `JUMPIF`, and `JUMPV` address only `JUMPDEST` instructions.
-
->4b  `JUMPSUB` and `JUMPSUBV` address only `BEGINSUB` instructions.
-
->4c  `JUMP` instructions do not address instructions outside of the subroutine they occur in.
-
-We have two new conditions on execution to ensure consistent use of the stack by subroutines:
->6  For `JUMPSUB` and `JUMPSUBV` the frame size is at least the `n_args` of the `BEGINSUB`(s) to jump to.
-
->7  For `RETURNSUB` the frame size is equal to the `n_results` of the enclosing `BEGINSUB`.
-
-Finally, we have one condition that prevents pathological uses of the stack:
->8  For every instruction in the code the frame size is constant.
-
-In practice, we must test at runtime for conditions 1 and 2 - sufficient gas and sufficient stack.  We don’t know how much gas there will be, we don’t know how deep a recursion may go, and analysis of stack depth even for non-recursive programs is non-trivial.
-
-All of the remaining conditions we validate statically.
-
-## VALIDATION
-
-Validation comprises two tasks:
-* Checking that jump destinations are correct and instructions valid.
-* Checking that subroutines satisfy the conditions on control flow and stack use.
-
-We sketch out these two validation functions in pseudo-C below.   To simplify the presentation only the five primitives are handled (`JUMPV` and `JUMPSUBV` would just add more complexity to loop over their vectors), we assume helper functions for extracting instruction arguments from immediate data and managing the stack pointer and program counter, and some optimizations are forgone.
-
-### Validating jumps
-
-Validating that jumps are to valid addresses takes two sequential passes over the bytecode - one to build sets of jump destinations and subroutine entry points, another to check that addresses jumped to are in the appropriate sets.
-```
-    bytecode[code_size]   // contains EVM bytecode to validate
-    is_sub[code_size]     // is there a BEGINSUB at PC?
-    is_dest[code_size]    // is there a JUMPDEST at PC?
-    sub_for_pc[code_size] // which BEGINSUB is PC in?
-    
-    bool validate_jumps(PC)
-    {
-        current_sub = PC
-
-        // build sets of BEGINSUBs and JUMPDESTs
-        for (PC = 0; instruction = bytecode[PC]; PC = advance_pc(PC))
-        {
-            if instruction is invalid
-                return false
-            if instruction is BEGINDATA
-                return true
-            if instruction is BEGINSUB
-                is_sub[PC] = true
-                current_sub = PC
-                sub_for_pc[PC] = current_sub
-            if instruction is JUMPDEST
-                is_dest[PC] = true
-            sub_for_pc[PC] = current_sub
-        }
-        
-        // check that targets are in subroutine
-        for (PC = 0; instruction = bytecode[PC]; PC = advance_pc(PC))
-        {
-            if instruction is BEGINDATA
-                break;
-            if instruction is BEGINSUB
-                current_sub = PC
-            if instruction is JUMPSUB
-                if is_sub[jump_target(PC)] is false
-                    return false
-            if instruction is JUMPTO or JUMPIF
-                if is_dest[jump_target(PC)] is false
-                    return false
-            if sub_for_pc[PC] is not current_sub
-                return false
-       }
-        return true
-    }
-```
-Note that code like this is already run by EVMs to check dynamic jumps, including building the jump destination set every time a contract is run, and doing a lookup in the jump destination set before every jump.
-
-### Validating subroutines
-
-This function can be seen as a symbolic execution of a subroutine in the EVM code, where only the effect of the instructions on the state being validated is computed.  Thus the structure of this function is very similar to an EVM interpreter.  This function can also be seen as an acyclic traversal of the directed graph formed by taking instructions as vertexes and sequential and branching connections as edges, checking conditions along the way.  The traversal is accomplished via recursion, and cycles are broken by returning when a vertex which has already been visited is reached.  The time complexity of this traversal is O(n-vertices + n-edges)
-
-The basic approach is to call `validate_subroutine(i, 0, 0)`, for _i_ equal to the first instruction in the EVM code through each `BEGINDATA` offset.  `validate_subroutine()` traverses instructions sequentially, recursing when `JUMP` and `JUMPI` instructions are encountered.  When a destination is reached that has been visited before it returns, thus breaking cycles.  It returns true if the subroutine is valid, false otherwise.
-
-```
-    bytecode[code_size]     // contains EVM bytecode to validate
-    frame_size[code_size ]  // is filled with -1
-
-    // we validate each subroutine individually, as if at top level
-    // * PC is the offset in the code to start validating at
-    // * return_pc is the top PC on return stack that RETURNSUB returns to
-    // * at top level FP = 0, so SP is both the frame size and the stack size
-    validate_subroutine(PC, return_pc, SP)
-    {
-        // traverse code sequentially, recurse for jumps
-        while true
-        {
-            instruction = bytecode[PC]
-
-            // if frame size set we have been here before
-            if frame_size[PC] >= 0
-            {
-                // check for constant frame size
-                if instruction is JUMPDEST
-                    if SP != frame_size[PC]
-                        return false
-
-                // return to break cycle
-                return true
-            }
-            frame_size[PC] = SP
-
-            // effect of instruction on stack
-            n_removed = removed_items(instructions)
-            n_added = added_items(instruction)
-
-            // check for stack underflow
-            if SP < n_removed
-                return false
-
-            // net effect of removing and adding stack items
-            SP -= n_removed
-            SP += n_added
-
-            // check for stack overflow
-            if SP > 1024
-                return false
-
-            if instruction is STOP, RETURN, or SUICIDE
-                return true	   
-
-            // violates single entry
-            if instruction is BEGINSUB
-                 return false
-
-            // return to top or from recursion to JUMPSUB
-            if instruction is RETURNSUB
-                break;
-
-            if instruction is JUMPSUB
-            {
-                // check for enough arguments
-                sub_pc = jump_target(PC)
-                if SP < n_args(sub_pc)
-                    return false
-                return true
-            }
-
-            // reset PC to destination of jump
-            if instruction is JUMPTO
-            {
-                PC = jump_target(PC)
-                continue 
-            }
-
-            // recurse to jump to code to validate 
-            if instruction is JUMPIF
-            {
-                if not validate_subroutine(jump_target(PC), return_pc, SP)
-                    return false
-            }
-
-            // advance PC according to instruction
-            PC = advance_pc(PC)
-        }
-
-        // check for right number of results
-        if SP != n_results(return_pc)
-            return false
-        return true
-    }
-```
-
-### COSTS & CODES
-
-All of the instructions are O(1) with a small constant, requiring just a few machine operations each, whereas a `JUMP` or `JUMPI` must do an O(log n) binary search of an array of `JUMPDEST` offsets before every jump. With the cost of `JUMPI` being _high_ and the cost of `JUMP` being _mid_, we suggest the cost of `JUMPV` and `JUMPSUBV` should be _mid_, `JUMPSUB` and `JUMPIF` should be _low_, and`JUMPTO` should be _verylow_.  Measurement will tell.
-
-We tentatively suggest the following opcodes:
-```
-0xB0 JUMPTO
-0xB1 JUMPIF
-0XB2 JUMPSUB
-0xB4 JUMPSUBV
-0xB5 BEGINSUB
-0xB6 BEGINDATA
-0xB8 RETURNSUB
-0xB9 PUTLOCAL
-0xBA GETLOCAL
-```
-
-### GETTING THERE FROM HERE
-
-These changes would need to be implemented in phases at decent intervals:
->1 If this EIP is accepted, invalid code should be deprecated. Tools should stop generating invalid code, users should stop writing it, and clients should warn about loading it.
-
->2 A later hard fork would require clients to place only valid code on the block chain.  Note that despite the fork old EVM code will still need to be supported indefinitely.
-
-If desired, the period of deprecation can be extended indefinitely by continuing to accept code not versioned as new - but without validation.  That is, by delaying step 2.  Since we must continue to run old code this is not technically difficult. 
-
-Implementation of this proposal need not be difficult,  At the least, interpreters can simply be extended with the new opcodes and run unchanged otherwise.  The new opcodes require only stacks for the frame pointers and return offsets and the few pushes, pops, and assignments described above.  JIT code can use native calls.  Further optimizations include minimizing runtime checks for exceptions and taking advantage of validated code wherever possible.

From cb444e28e56dfe3e9c0aa93581b7dda62f6083c6 Mon Sep 17 00:00:00 2001
From: Greg Colvin 
Date: Tue, 25 Apr 2017 11:28:06 +0200
Subject: [PATCH 0090/1085] Create JumpsAndSubs.md

---
 EIPS/JumpsAndSubs.md | 372 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 372 insertions(+)
 create mode 100644 EIPS/JumpsAndSubs.md

diff --git a/EIPS/JumpsAndSubs.md b/EIPS/JumpsAndSubs.md
new file mode 100644
index 0000000000000..7087b31116c55
--- /dev/null
+++ b/EIPS/JumpsAndSubs.md
@@ -0,0 +1,372 @@
+```
+EIP: TBD
+Title: Subroutines and Static Jumps for the EVM
+Status: Draft
+Type: Core
+Author: Greg Colvin, Paweł Bylica, Christian Reitwiessner 
+Created: 2016-12-10
+Edited: 2016-29-12
+```
+## Abstract
+
+This EIP introduces new EVM opcodes and conditions on EVM code to support subroutines and static jumps, disallow dynamic jumps, and thereby make EVM code amenable to linear-time static analysis.  This will provide for better compilation, interpretation, transpilation, and formal analysis of EVM code.
+
+## MOTIVATION
+
+All current implementations of the Ethereum Virtual Machine, including the just-in-time compilers, are much too slow. This proposal identifies a major reason for this and proposes changes to the EVM specification to address the problem.
+
+In particular, it imposes restrictions on current EVM code and proposes new instructions to help provide for
+* better-optimized compilation to native code
+* faster interpretation
+* faster transpilation to eWASM
+* better compilation from other languages,
+   including eWASM and Solidity
+* better formal analysis tools
+
+These goals are achieved by
+* disallowing dynamic jumps
+* introducing subroutines - jumps with return support
+* disallowing pathological control flow and uses of the stack
+
+We also propose to validate - in linear time - that EVM contracts correctly use subroutines, avoid misuse of the stack, and meet other safety conditions _before_ placing them on the blockchain.  Validated code precludes most runtime exceptions and the need to test for them.  And well-behaved control flow and use of the stack makes life easier for interpreters, compilers, formal analysis, and other tools.
+
+## THE PROBLEM
+
+Currently the EVM supports dynamic jumps, where the address to jump to is an argument on the stack. These dynamic jumps obscure the structure of the code and thus mostly inhibit control- and data-flow analysis.  This puts the quality and speed of optimized compilation fundamentally at odds.  Further, since every jump can potentially be to any jump destination in the code, the number of possible paths through the code goes up as the product of the number of jumps by the number of destinations, as does the time complexity of static analysis.  But absent dynamic jumps code can be statically analyzed in linear time.
+
+Static analysis includes validation, and much of optimization, compilation, transpilation, and formal analysis; every part of the tool chain benefits when linear-time analysis is available.  In particular, faster control-flow analysis means faster compilation of EVM code to native code, and better data-flow analysis can help the compiler and the interpreter better track the size of the values on the stack and use native 64- and 32-bit operations when possible.  Also, conditions which are checked at validation time don’t have to be checked repeatedly at runtime.
+
+Note that analyses of a contract’s bytecode before execution - such as optimizations performed before interpretation, JIT compilation, and on-the-fly machine code generation - must be efficient and linear-time. Otherwise, specially crafted contracts can be used as attack vectors against clients that use static analysis of EVM code before the creation or execution of contracts.
+
+## PROPOSAL
+
+We propose to deprecate two existing instructions - `JUMP` and `JUMPI`. They take their argument on the stack, which means that unless the value is constant they can jump to any `JUMPDEST`.  (In simple cases like `PUSH 0 JUMP` the value on the stack can be known to be constant, but in general it's difficult.)  We must nonetheless continue to support them in old code.
+
+Having deprecated `JUMP` and `JUMPI`, we propose new instructions to support their legitimate uses.
+
+### Preliminaries
+
+These forms
+* `INSTRUCTION x,`
+* `INSTRUCTION x, y`
+* `INSTRUCTION n, x ...`
+
+name instructions with one, two, and two or more arguments, respectively.  An instruction is represented in the bytecode as a single-byte opcode.  The arguments are laid out as immediate data bytes following the opcode.  The size and encoding of immediate data fields is open to change.  In particular, easily-parsed variable-length encodings might prove useful for bytecode offsets - which are in practice small but in principle can be large.
+
+### Primitives
+
+The two most important uses of `JUMP` and `JUMPI` are static jumps and return jumps. Conditional and unconditional static jumps are the mainstay of control flow.  Return jumps are implemented as a dynamic jump to a return address pushed on the stack.  With the combination of a static jump and a dynamic return jump you can - and Solidity does - implement subroutines.  The problem is that static analysis cannot tell the one place the return jump is going, so it must analyze every possibility.
+
+Static jumps are provided by
+* `JUMPTO jump_target`
+* `JUMPIF jump_target`
+which are the same as `JUMP` and `JUMPI` except that they jump to an immediate `jump_target`, given as four immediate bytes, rather than an address on the stack.
+
+To support subroutines, `BEGINSUB`, `JUMPSUB`, and `RETURNSUB` are provided.  Brief descriptions follow, and full semantics are given below.
+
+* `BEGINSUB n_args, n_results`
+marks the **single** entry to a subroutine.  `n_args` items are taken off of the stack at entry to, and `n_results` items are placed on the stack at return from the subroutine. `n_args` and `n_results` are given as one immediate byte each.  The bytecode for a subroutine ends at the next `BEGINSUB` instruction (or `BEGINDATA`, below) or at the end of the bytecode.
+
+* `JUMPSUB jump_target`
+jumps to an immediate subroutine address, given as four immediate bytes.
+
+* `RETURNSUB`
+returns from the current subroutine to the instruction following the JUMPSUB that entered it.
+
+These five simple instructions form the primitives of the proposal.
+
+### Data
+
+In order to validate subroutines, EVM bytecode must be sequentially scanned matching jumps to their destinations.  Since creation code has to contain the runtime code as data, that code might not correctly validate in the creation context and also does not have to be validated prior to the execution of the creation code. Because of that, there needs to be a way to place data into the bytecode that will be skipped over and not validated.  Such data will prove useful for other purposes as well.
+
+* `BEGINDATA`
+specifies that all of the following bytes to the end of the bytecode are data, and not reachable code.
+
+### Indirect Jumps
+
+The primitive operations provide for static jumps.  Dynamic jumps are also used for O(1) indirection: an address to jump to is selected to push on the stack and be jumped to.  So we also propose two more instructions to provide for constrained indirection.  We support these with vectors of `JUMPDEST` or `BEGINSUB` offsets stored inline, which can be selected with an index on the stack.  That constrains validation to a specified subset of all possible destinations.  The danger of quadratic blow up is avoided because it takes as much space to store the jump vectors as it does to code the worst case exploit. 
+
+Dynamic jumps to a `JUMPDEST` are used to implement O(1) jumptables, which are useful for dense switch statements, and are implemented as instructions similar to this one on most CPUs.
+* `JUMPV n, jumpdest ...`
+jumps to one of a vector of `n` `JUMPDEST` offsets via a zero-based index on the stack.  The vector is stored inline in the bytecode.  If the index is greater than or equal to `n - 1` the last (default) offset is used.  `n` is given as four immediate bytes, all `JUMPDEST` offsets as four immediate bytes each.
+
+Dynamic jumps to a `BEGINSUB` are used to implement O(1) virtual functions and callbacks, which take just two pointer dereferences on most CPUs.
+* `JUMPSUBV n, beginsub ...`
+jumps to one of a vector of `n` `BEGINSUB` offsets via a zero-based index on the stack.  The vector is stored inline in the bytecode, MSB-first.  If the index is greater than or equal to `n - 1` the last (default) offset is used.  `n` is given as four immediate bytes, the `n` offsets as four immediate bytes each.
+
+`JUMPV` and `JUMPSUBV` are not strictly necessary.  They provide O(1) operations that can be replaced by O(n) or O(log n) EVM code using static jumps, but that code will be slower, larger and use more gas for things that can and should be fast, small, and cheap, and that are directly supported in WASM with br_table and call_indirect.
+
+### Variable Access
+
+These operations provide convenient access to subroutine parameters and other variables at fixed stack offsets within a subroutine.
+
+* `PUTLOCAL n`
+Pops the top value on the stack and copies it to local variable `n`.
+
+* `GETLOCAL n`
+Pushes the value of local variable `n` on the EVM stack.
+
+Local variable `n` is `FP[-n]` as defined below.
+
+## SEMANTICS
+
+Jumps to and returns from subroutines are described here in terms of
+* the EVM data stack, (as defined in the [Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf) usually just called “the stack”,
+* a return stack of `JUMPSUB` and `JUMPSUBV` offsets, and
+* a frame stack of frame pointers.
+
+We will adopt the following conventions to describe the machine state:
+* The _program counter_ `PC` is (as usual) the byte offset of the currently executing instruction.
+* The _stack pointer_ `SP` corresponds to the number of items on the stack - the _stack size_.  As a negative offset it addresses the current top of the stack of data values, where new items are pushed.
+* The _frame pointer_ `FP` is set to `SP + n_args` at entry to the currently executing subroutine.
+* The _stack items_ between the frame pointer and the current stack pointer are called the _frame_.
+* The current number of items in the frame, `FP - SP`, is the _frame size_.
+
+Defining the frame pointer so as to include the arguments is unconventional, but better fits our stack semantics and simplifies the remainder of the proposal.
+
+The frame pointer and return stacks are internal to the subroutine mechanism, and not directly accessible to the program.  This is necessary to prevent the program from modifying its state in ways that could be invalid.
+
+The first instruction of an array of EVM bytecode begins execution of a _main_ routine with no arguments, `SP` and `FP` set to 0, and with one value on the return stack - `code size - 1`. (Executing the virtual byte of 0 after this offset causes an EVM to stop.  Thus executing a `RETURNSUB` with no prior `JUMPSUB` or `JUMBSUBV` - that is, in the _main_ routine - executes a `STOP`.)
+
+Execution of a subroutine begins with `JUMPSUB` or `JUMPSUBV`, which
+* push `PC` on the return stack,
+* push `FP` on the frame stack,
+thus suspending execution of the current subroutine, and
+* set `FP` to `SP + n_args`, and
+* set `PC` to the specified `BEGINSUB` address,
+thus beginning execution of the new subroutine.
+(The _main_ routine is not addressable by `JUMPSUB` instructions.)
+
+Execution of a subroutine is suspended during and resumed after execution of nested subroutines, and ends upon encountering a `RETURNSUB`, which
+* sets `FP` to the top of the virtual frame stack and pops the stack, and
+* sets `PC` to top of the return stack and pops the stack
+* advances `PC` to the next instruction
+thus resuming execution of the enclosing subroutine or _main_ program.
+A `STOP or `RETURN` also ends the execution of a subroutine.
+
+## VALIDITY
+
+We would like to consider EVM code valid if and only if no execution of the program can lead to an exceptional halting state.  But we must and will validate code in linear time.  So our validation does not consider the code’s data and computations, only its control flow and stack use.  This means we will reject programs with invalid code paths, even if those paths cannot be executed at runtime.  Most conditions can be validated, and will not need to be checked at runtime; the exceptions are sufficient gas and sufficient stack.  So some false negatives and runtime checks are the price we pay for linear time validation.
+
+_Execution_ is as defined in the Yellow Paper - a sequence of changes in the EVM state.  The conditions on valid code are preserved by state changes.  At runtime, if execution of an instruction would violate a condition the execution is in an exceptional halting state.  The yellow paper defines five such states.
+>1  Insufficient gas
+
+>2  More than 1024 stack items
+
+>3  Insufficient stack items
+
+>4  Invalid jump destination
+
+>5  Invalid instruction
+
+We propose to expand and extend the Yellow Paper conditions to handle the new instructions we propose. 
+
+To handle the return stack we expand the conditions on stack size:
+>2a  The size of the data stack does not exceed 1024.
+
+>2b  The size of the return stack does not exceed 1024.
+
+Given our more detailed description of the data stack we restate condition 3 - stack underflow - as
+>3  `SP` must be less than or equal to `FP`
+
+Since the various `DUP` and `SWAP` operations are formalized as taking items off the stack and putting them back on, this prevents `DUP` and `SWAP` from accessing data below the frame pointer, since taking too many items off of the stack would mean that `SP` is less than `FP`.
+
+To handle the new jump instructions and subroutine boundaries we expand the conditions on jumps and jump destinations.
+>4a  `JUMPTO`, `JUMPIF`, and `JUMPV` address only `JUMPDEST` instructions.
+
+>4b  `JUMPSUB` and `JUMPSUBV` address only `BEGINSUB` instructions.
+
+>4c  `JUMP` instructions do not address instructions outside of the subroutine they occur in.
+
+We have two new conditions on execution to ensure consistent use of the stack by subroutines:
+>6  For `JUMPSUB` and `JUMPSUBV` the frame size is at least the `n_args` of the `BEGINSUB`(s) to jump to.
+
+>7  For `RETURNSUB` the frame size is equal to the `n_results` of the enclosing `BEGINSUB`.
+
+Finally, we have one condition that prevents pathological uses of the stack:
+>8  For every instruction in the code the frame size is constant.
+
+In practice, we must test at runtime for conditions 1 and 2 - sufficient gas and sufficient stack.  We don’t know how much gas there will be, we don’t know how deep a recursion may go, and analysis of stack depth even for non-recursive programs is non-trivial.
+
+All of the remaining conditions we validate statically.
+
+## VALIDATION
+
+Validation comprises two tasks:
+* Checking that jump destinations are correct and instructions valid.
+* Checking that subroutines satisfy the conditions on control flow and stack use.
+
+We sketch out these two validation functions in pseudo-C below.   To simplify the presentation only the five primitives are handled (`JUMPV` and `JUMPSUBV` would just add more complexity to loop over their vectors), we assume helper functions for extracting instruction arguments from immediate data and managing the stack pointer and program counter, and some optimizations are forgone.
+
+### Validating jumps
+
+Validating that jumps are to valid addresses takes two sequential passes over the bytecode - one to build sets of jump destinations and subroutine entry points, another to check that addresses jumped to are in the appropriate sets.
+```
+    bytecode[code_size]   // contains EVM bytecode to validate
+    is_sub[code_size]     // is there a BEGINSUB at PC?
+    is_dest[code_size]    // is there a JUMPDEST at PC?
+    sub_for_pc[code_size] // which BEGINSUB is PC in?
+    
+    bool validate_jumps(PC)
+    {
+        current_sub = PC
+
+        // build sets of BEGINSUBs and JUMPDESTs
+        for (PC = 0; instruction = bytecode[PC]; PC = advance_pc(PC))
+        {
+            if instruction is invalid
+                return false
+            if instruction is BEGINDATA
+                return true
+            if instruction is BEGINSUB
+                is_sub[PC] = true
+                current_sub = PC
+                sub_for_pc[PC] = current_sub
+            if instruction is JUMPDEST
+                is_dest[PC] = true
+            sub_for_pc[PC] = current_sub
+        }
+        
+        // check that targets are in subroutine
+        for (PC = 0; instruction = bytecode[PC]; PC = advance_pc(PC))
+        {
+            if instruction is BEGINDATA
+                break;
+            if instruction is BEGINSUB
+                current_sub = PC
+            if instruction is JUMPSUB
+                if is_sub[jump_target(PC)] is false
+                    return false
+            if instruction is JUMPTO or JUMPIF
+                if is_dest[jump_target(PC)] is false
+                    return false
+            if sub_for_pc[PC] is not current_sub
+                return false
+       }
+        return true
+    }
+```
+Note that code like this is already run by EVMs to check dynamic jumps, including building the jump destination set every time a contract is run, and doing a lookup in the jump destination set before every jump.
+
+### Validating subroutines
+
+This function can be seen as a symbolic execution of a subroutine in the EVM code, where only the effect of the instructions on the state being validated is computed.  Thus the structure of this function is very similar to an EVM interpreter.  This function can also be seen as an acyclic traversal of the directed graph formed by taking instructions as vertexes and sequential and branching connections as edges, checking conditions along the way.  The traversal is accomplished via recursion, and cycles are broken by returning when a vertex which has already been visited is reached.  The time complexity of this traversal is O(n-vertices + n-edges)
+
+The basic approach is to call `validate_subroutine(i, 0, 0)`, for _i_ equal to the first instruction in the EVM code through each `BEGINDATA` offset.  `validate_subroutine()` traverses instructions sequentially, recursing when `JUMP` and `JUMPI` instructions are encountered.  When a destination is reached that has been visited before it returns, thus breaking cycles.  It returns true if the subroutine is valid, false otherwise.
+
+```
+    bytecode[code_size]     // contains EVM bytecode to validate
+    frame_size[code_size ]  // is filled with -1
+
+    // we validate each subroutine individually, as if at top level
+    // * PC is the offset in the code to start validating at
+    // * return_pc is the top PC on return stack that RETURNSUB returns to
+    // * at top level FP = 0, so SP is both the frame size and the stack size
+    validate_subroutine(PC, return_pc, SP)
+    {
+        // traverse code sequentially, recurse for jumps
+        while true
+        {
+            instruction = bytecode[PC]
+
+            // if frame size set we have been here before
+            if frame_size[PC] >= 0
+            {
+                // check for constant frame size
+                if instruction is JUMPDEST
+                    if SP != frame_size[PC]
+                        return false
+
+                // return to break cycle
+                return true
+            }
+            frame_size[PC] = SP
+
+            // effect of instruction on stack
+            n_removed = removed_items(instructions)
+            n_added = added_items(instruction)
+
+            // check for stack underflow
+            if SP < n_removed
+                return false
+
+            // net effect of removing and adding stack items
+            SP -= n_removed
+            SP += n_added
+
+            // check for stack overflow
+            if SP > 1024
+                return false
+
+            if instruction is STOP, RETURN, or SUICIDE
+                return true	   
+
+            // violates single entry
+            if instruction is BEGINSUB
+                 return false
+
+            // return to top or from recursion to JUMPSUB
+            if instruction is RETURNSUB
+                break;
+
+            if instruction is JUMPSUB
+            {
+                // check for enough arguments
+                sub_pc = jump_target(PC)
+                if SP < n_args(sub_pc)
+                    return false
+                return true
+            }
+
+            // reset PC to destination of jump
+            if instruction is JUMPTO
+            {
+                PC = jump_target(PC)
+                continue 
+            }
+
+            // recurse to jump to code to validate 
+            if instruction is JUMPIF
+            {
+                if not validate_subroutine(jump_target(PC), return_pc, SP)
+                    return false
+            }
+
+            // advance PC according to instruction
+            PC = advance_pc(PC)
+        }
+
+        // check for right number of results
+        if SP != n_results(return_pc)
+            return false
+        return true
+    }
+```
+
+### COSTS & CODES
+
+All of the instructions are O(1) with a small constant, requiring just a few machine operations each, whereas a `JUMP` or `JUMPI` must do an O(log n) binary search of an array of `JUMPDEST` offsets before every jump. With the cost of `JUMPI` being _high_ and the cost of `JUMP` being _mid_, we suggest the cost of `JUMPV` and `JUMPSUBV` should be _mid_, `JUMPSUB` and `JUMPIF` should be _low_, and`JUMPTO` should be _verylow_.  Measurement will tell.
+
+We tentatively suggest the following opcodes:
+```
+0xB0 JUMPTO
+0xB1 JUMPIF
+0XB2 JUMPSUB
+0xB4 JUMPSUBV
+0xB5 BEGINSUB
+0xB6 BEGINDATA
+0xB8 RETURNSUB
+0xB9 PUTLOCAL
+0xBA GETLOCAL
+```
+
+### GETTING THERE FROM HERE
+
+These changes would need to be implemented in phases at decent intervals:
+>1 If this EIP is accepted, invalid code should be deprecated. Tools should stop generating invalid code, users should stop writing it, and clients should warn about loading it.
+
+>2 A later hard fork would require clients to place only valid code on the block chain.  Note that despite the fork old EVM code will still need to be supported indefinitely.
+
+If desired, the period of deprecation can be extended indefinitely by continuing to accept code not versioned as new - but without validation.  That is, by delaying step 2.  Since we must continue to run old code this is not technically difficult. 
+
+Implementation of this proposal need not be difficult,  At the least, interpreters can simply be extended with the new opcodes and run unchanged otherwise.  The new opcodes require only stacks for the frame pointers and return offsets and the few pushes, pops, and assignments described above.  JIT code can use native calls.  Further optimizations include minimizing runtime checks for exceptions and taking advantage of validated code wherever possible.

From 27337482761b2a4c9be4e2ec7646b64bdb399657 Mon Sep 17 00:00:00 2001
From: Greg Colvin 
Date: Tue, 25 Apr 2017 11:29:18 +0200
Subject: [PATCH 0091/1085] Delete eip-187.md

---
 EIPS/eip-187.md | 355 ------------------------------------------------
 1 file changed, 355 deletions(-)
 delete mode 100644 EIPS/eip-187.md

diff --git a/EIPS/eip-187.md b/EIPS/eip-187.md
deleted file mode 100644
index 645534b7966e5..0000000000000
--- a/EIPS/eip-187.md
+++ /dev/null
@@ -1,355 +0,0 @@
-```
-EIP: 187
-Title: Subroutines and Static Jumps for the EVM
-Status: Draft
-Type: Core
-Author: Greg Colvin, Paweł Bylica, Christian Reitwiessner 
-Created: 2016-12-10
-Edited: 2016-29-12
-```
-## Abstract
-
-This EIP introduces new EVM opcodes and conditions on EVM code to support subroutines and static jumps, disallow dynamic jumps, and thereby make EVM code amenable to linear-time static analysis.  This will provide for better compilation, interpretation, transpilation, and formal analysis of EVM code.
-
-## MOTIVATION
-
-All current implementations of the Ethereum Virtual Machine, including the just-in-time compilers, are much too slow. This proposal identifies a major reason for this and proposes changes to the EVM specification to address the problem.
-
-In particular, it imposes restrictions on current EVM code and proposes new instructions to help provide for
-* better-optimized compilation to native code
-* faster interpretation
-* faster transpilation to eWASM
-* better compilation from other languages,
-   including eWASM and Solidity
-* better formal analysis tools
-
-These goals are achieved by
-* disallowing dynamic jumps
-* introducing subroutines - jumps with return support
-* disallowing pathological control flow and uses of the stack
-
-We also propose to validate - in linear time - that EVM contracts correctly use subroutines, avoid misuse of the stack, and meet other safety conditions _before_ placing them on the blockchain.  Validated code precludes most runtime exceptions and the need to test for them.  And well-behaved control flow and use of the stack makes life easier for interpreters, compilers, formal analysis, and other tools.
-
-## THE PROBLEM
-
-Currently the EVM supports dynamic jumps, where the address to jump to is an argument on the stack. These dynamic jumps obscure the structure of the code and thus mostly inhibit control- and data-flow analysis.  This puts the quality and speed of optimized compilation fundamentally at odds.  Further, since every jump can potentially be to any jump destination in the code, the number of possible paths through the code goes up as the product of the number of jumps by the number of destinations, as does the time complexity of static analysis.  But absent dynamic jumps code can be statically analyzed in linear time.
-
-Static analysis includes validation, and much of optimization, compilation, transpilation, and formal analysis; every part of the tool chain benefits when linear-time analysis is available.  In particular, faster control-flow analysis means faster compilation of EVM code to native code, and better data-flow analysis can help the compiler and the interpreter better track the size of the values on the stack and use native 64- and 32-bit operations when possible.  Also, conditions which are checked at validation time don’t have to be checked repeatedly at runtime.
-
-Note that analyses of a contract’s bytecode before execution - such as optimizations performed before interpretation, JIT compilation, and on-the-fly machine code generation - must be efficient and linear-time. Otherwise, specially crafted contracts can be used as attack vectors against clients that use static analysis of EVM code before the creation or execution of contracts.
-
-## PROPOSAL
-
-We propose to deprecate two existing instructions - `JUMP` and `JUMPI`. They take their argument on the stack, which means that unless the value is constant they can jump to any `JUMPDEST`.  (In simple cases like `PUSH 0 JUMP` the value on the stack can be known to be constant, but in general it's difficult.)  We must nonetheless continue to support them in old code.
-
-Having deprecated `JUMP` and `JUMPI`, we propose new instructions to support their legitimate uses.
-
-### Preliminaries
-
-These forms
-* `INSTRUCTION x,`
-* `INSTRUCTION x, y`
-* `INSTRUCTION n, x ...`
-
-name instructions with one, two, and two or more arguments, respectively.  An instruction is represented in the bytecode as a single-byte opcode.  The arguments are laid out as immediate data bytes following the opcode.  The size and encoding of immediate data fields is open to change.  In particular, easily-parsed variable-length encodings might prove useful for bytecode offsets - which are in practice small but in principle can be large.
-
-### Primitives
-
-The two most important uses of `JUMP` and `JUMPI` are static jumps and return jumps. Conditional and unconditional static jumps are the mainstay of control flow.  Return jumps are implemented as a dynamic jump to a return address pushed on the stack.  With the combination of a static jump and a dynamic return jump you can - and Solidity does - implement subroutines.  The problem is that static analysis cannot tell the one place the return jump is going, so it must analyze every possibility.
-
-Static jumps are provided by
-* `JUMPTO jump_target`
-* `JUMPIF jump_target`
-which are the same as `JUMP` and `JUMPI` except that they jump to an immediate `jump_target`, given as four immediate bytes, rather than an address on the stack.
-
-To support subroutines, `BEGINSUB`, `JUMPSUB`, and `RETURNSUB` are provided.  Brief descriptions follow, and full semantics are given below.
-
-* `BEGINSUB n_args, n_results`
-marks the **single** entry to a subroutine.  `n_args` items are taken off of the stack at entry to, and `n_results` items are placed on the stack at return from the subroutine. `n_args` and `n_results` are given as one immediate byte each.  The bytecode for a subroutine ends at the next `BEGINSUB` instruction (or `BEGINDATA`, below) or at the end of the bytecode.
-
-* `JUMPSUB jump_target`
-jumps to an immediate subroutine address, given as four immediate bytes.
-
-* `RETURNSUB`
-returns from the current subroutine to the instruction following the JUMPSUB that entered it.
-
-These five simple instructions form the primitives of the proposal.
-
-### Data
-
-In order to validate subroutines, EVM bytecode must be sequentially scanned matching jumps to their destinations.  Since creation code has to contain the runtime code as data, that code might not correctly validate in the creation context and also does not have to be validated prior to the execution of the creation code. Because of that, there needs to be a way to place data into the bytecode that will be skipped over and not validated.  Such data will prove useful for other purposes as well.
-
-* `BEGINDATA`
-specifies that all of the following bytes to the end of the bytecode are data, and not reachable code.
-
-### Indirect Jumps
-
-The primitive operations provide for static jumps.  Dynamic jumps are also used for O(1) indirection: an address to jump to is selected to push on the stack and be jumped to.  So we also propose two more instructions to provide for constrained indirection.  We support these with vectors of `JUMPDEST` or `BEGINSUB` offsets stored inline, which can be selected with an index on the stack.  That constrains validation to a specified subset of all possible destinations.  The danger of quadratic blow up is avoided because it takes as much space to store the jump vectors as it does to code the worst case exploit. 
-
-Dynamic jumps to a `JUMPDEST` are used to implement O(1) jumptables, which are useful for dense switch statements, and are implemented as instructions similar to this one on most CPUs.
-* `JUMPV n, jumpdest ...`
-jumps to one of a vector of `n` `JUMPDEST` offsets via a zero-based index on the stack.  The vector is stored inline in the bytecode.  If the index is greater than or equal to `n - 1` the last (default) offset is used.  `n` is given as four immediate bytes, all `JUMPDEST` offsets as four immediate bytes each.
-
-Dynamic jumps to a `BEGINSUB` are used to implement O(1) virtual functions and callbacks, which take just two pointer dereferences in C.
-* `JUMPSUBV n, beginsub ...`
-jumps to one of a vector of `n` `BEGINSUB` offsets via a zero-based index on the stack.  The vector is stored inline in the bytecode, MSB-first.  If the index is greater than or equal to `n - 1` the last (default) offset is used.  `n` is given as four immediate bytes, the `n` offsets as four immediate bytes each.
-
-`JUMPV` and `JUMPSUBV` are not strictly necessary.  They provide O(1) operations that can be replaced by O(n) or O(log n) EVM code using static jumps, but that code will be slower, larger and use more gas for things that can and should be fast, small, and cheap, and that are directly supported in WASM with br_table and call_indirect.
-
-## SEMANTICS
-
-Jumps to and returns from subroutines are described here in terms of
-* the EVM data stack, usually just called “the stack”,
-* a return stack of `JUMPSUB` and `JUMPSUBV` offsets, and
-* a virtual stack of frame pointers (not needed at runtime).
-
-We will adopt the following conventions to describe the machine state:
-* The _program counter_ `PC` is (as usual) the byte offset of the currently executing instruction.
-* The _stack pointer_ `SP` corresponds to the number of items on the stack - the _stack size_.  As an offset it addresses the current top of the stack of data values, where new items are pushed.
-* The virtual _frame pointer_ `FP` is set to `SP - n_args` at entry to the currently executing subroutine.
-* The _stack items_ between the frame pointer and the current stack pointer are called the _frame_.
-* The current number of items in the frame, `SP - FP`, is the _frame size_.
-
-Placing the frame pointer at the beginning of the arguments rather than the end is unconventional, but better fits our stack semantics and simplifies the remainder of the proposal.
-
-Note that frame pointers and the frame pointer stack, being virtual, are only needed for the following descriptions of subroutine semantics, not for their actual implementation.  Also, the return stack is internal to the subroutine mechanism, and not directly accessible to the program.
-
-The first instruction of an array of EVM bytecode begins execution of a _main_ routine with no arguments, `SP` and `FP` set to 0, and with one value on the return stack - `code size - 1`. (Executing the virtual byte of 0 after this offset causes an EVM to stop.  Thus executing a `RETURNSUB` with no prior `JUMPSUB` or `JUMBSUBV` - that is, in the _main_ routine - executes a `STOP`.)
-
-Execution of a subroutine begins with `JUMPSUB` or `JUMPSUBV`, which
-* push `PC` on the return stack,
-* push `FP` on the virtual frame stack,
-thus suspending execution of the current subroutine, and
-* set `FP` to `SP - n_args`, and
-* set `PC` to the specified `BEGINSUB` address,
-thus beginning execution of the new subroutine.
-(The _main_ routine is not addressable by `JUMPSUB` instructions.)
-
-Execution of a subroutine is suspended during and resumed after execution of nested subroutines, and ends upon encountering a `RETURNSUB`, which
-* sets `FP` to the top of the virtual frame stack and pops the stack, and
-* sets `PC` to top of the return stack and pops the stack
-* advances `PC` to the next instruction
-thus resuming execution of the enclosing subroutine or _main_ program.
-A `STOP or `RETURN` also ends the execution of a subroutine.
-
-## VALIDITY
-
-We would like to consider EVM code valid if and only if no execution of the program can lead to an exceptional halting state.  But we must and will validate code in linear time.  So our validation does not consider the code’s data and computations, only its control flow and stack use.  This means we will reject programs with invalid code paths, even if those paths cannot be executed at runtime.  Most conditions can be validated, and will not need to be checked at runtime; the exceptions are sufficient gas and sufficient stack.  So some false negatives and runtime checks are the price we pay for linear time validation.
-
-_Execution_ is as defined in the Yellow Paper - a sequence of changes in the EVM state.  The conditions on valid code are preserved by state changes.  At runtime, if execution of an instruction would violate a condition the execution is in an exceptional halting state.  The yellow paper defines five such states.
->1  Insufficient gas
-
->2  More than 1024 stack items
-
->3  Insufficient stack items
-
->4  Invalid jump destination
-
->5  Invalid instruction
-
-We propose to expand and extend the Yellow Paper conditions to handle the new instructions we propose. 
-
-To handle the return stack we expand the conditions on stack size:
->2a  The size of the data stack does not exceed 1024.
-
->2b  The size of the return stack does not exceed 1024.
-
-Given our more detailed description of the data stack we restate condition 3 - stack underflow - as
->3  `SP` must be greater than or equal to `FP`
-
-Since the various `DUP` and `SWAP` operations are formalized as taking items off the stack and putting them back on, this prevents `DUP` and `SWAP` from accessing data below the frame pointer, since taking too many items off of the stack would mean that `SP` is less than `FP`.
-
-To handle the new jump instructions and subroutine boundaries we expand the conditions on jumps and jump destinations.
->4a  `JUMPTO`, `JUMPIF`, and `JUMPV` address only `JUMPDEST` instructions.
-
->4b  `JUMPSUB` and `JUMPSUBV` address only `BEGINSUB` instructions.
-
->4c  `JUMP` instructions do not address instructions outside of the subroutine they occur in.
-
-We have two new conditions on execution to ensure consistent use of the stack by subroutines:
->6  For `JUMPSUB` and `JUMPSUBV` the frame size is at least the `n_args` of the `BEGINSUB`(s) to jump to.
-
->7  For `RETURNSUB` the frame size is equal to the `n_results` of the enclosing `BEGINSUB`.
-
-Finally, we have one condition that prevents pathological uses of the stack:
->8  For every instruction in the code the frame size is constant.
-
-In practice, we must test at runtime for conditions 1 and 2 - sufficient gas and sufficient stack.  We don’t know how much gas there will be, we don’t know how deep a recursion may go, and analysis of stack depth even for non-recursive programs is non-trivial.
-
-All of the remaining conditions we validate statically.
-
-## VALIDATION
-
-Validation comprises two tasks:
-* Checking that jump destinations are correct and instructions valid.
-* Checking that subroutines satisfy the conditions on control flow and stack use.
-
-We sketch out these two validation functions in pseudo-C below.   To simplify the presentation only the five primitives are handled (`JUMPV` and `JUMPSUBV` would just add more complexity to loop over their vectors), we assume helper functions for extracting instruction arguments from immediate data and managing the stack pointer and program counter, and some optimizations are forgone.
-
-### Validating jumps
-
-Validating that jumps are to valid addresses takes two sequential passes over the bytecode - one to build sets of jump destinations and subroutine entry points, another to check that addresses jumped to are in the appropriate sets.
-```
-    bytecode[code_size]   // contains EVM bytecode to validate
-    is_sub[code_size]     // is there a BEGINSUB at PC?
-    is_dest[code_size]    // is there a JUMPDEST at PC?
-    sub_for_pc[code_size] // which BEGINSUB is PC in?
-    
-    bool validate_jumps(PC)
-    {
-        current_sub = PC
-
-        // build sets of BEGINSUBs and JUMPDESTs
-        for (PC = 0; instruction = bytecode[PC]; PC = advance_pc(PC))
-        {
-            if instruction is invalid
-                return false
-            if instruction is BEGINDATA
-                return true
-            if instruction is BEGINSUB
-                is_sub[PC] = true
-                current_sub = PC
-                sub_for_pc[PC] = current_sub
-            if instruction is JUMPDEST
-                is_dest[PC] = true
-            sub_for_pc[PC] = current_sub
-        }
-        
-        // check that targets are in subroutine
-        for (PC = 0; instruction = bytecode[PC]; PC = advance_pc(PC))
-        {
-            if instruction is BEGINDATA
-                break;
-            if instruction is BEGINSUB
-                current_sub = PC
-            if instruction is JUMPSUB
-                if is_sub[jump_target(PC)] is false
-                    return false
-            if instruction is JUMPTO or JUMPIF
-                if is_dest[jump_target(PC)] is false
-                    return false
-            if sub_for_pc[PC] is not current_sub
-                return false
-       }
-        return true
-    }
-```
-Note that code like this is already run by EVMs to check dynamic jumps, including building the jump destination set every time a contract is run, and doing a lookup in the jump destination set before every jump.
-
-### Validating subroutines
-
-This function can be seen as a symbolic execution of a subroutine in the EVM code, where only the effect of the instructions on the state being validated is computed.  Thus the structure of this function is very similar to an EVM interpreter.  This function can also be seen as an acyclic traversal of the directed graph formed by taking instructions as vertexes and sequential and branching connections as edges, checking conditions along the way.  The traversal is accomplished via recursion, and cycles are broken by returning when a vertex which has already been visited is reached.  The time complexity of this traversal is O(n-vertices + n-edges)
-
-The basic approach is to call `validate_subroutine(i, 0, 0)`, for _i_ equal to the first instruction in the EVM code through each `BEGINDATA` offset.  `validate_subroutine()` traverses instructions sequentially, recursing when `JUMP` and `JUMPI` instructions are encountered.  When a destination is reached that has been visited before it returns, thus breaking cycles.  It returns true if the subroutine is valid, false otherwise.
-
-```
-    bytecode[code_size]     // contains EVM bytecode to validate
-    frame_size[code_size ]  // is filled with -1
-
-    // we validate each subroutine individually, as if at top level
-    // * PC is the offset in the code to start validating at
-    // * return_pc is the top PC on return stack that RETURNSUB returns to
-    // * at top level FP = 0, so SP is both the frame size and the stack size
-    validate_subroutine(PC, return_pc, SP)
-    {
-        // traverse code sequentially, recurse for jumps
-        while true
-        {
-            instruction = bytecode[PC]
-
-            // if frame size set we have been here before
-            if frame_size[PC] >= 0
-            {
-                // check for constant frame size
-                if instruction is JUMPDEST
-                    if SP != frame_size[PC]
-                        return false
-
-                // return to break cycle
-                return true
-            }
-            frame_size[PC] = SP
-
-            // effect of instruction on stack
-            n_removed = removed_items(instructions)
-            n_added = added_items(instruction)
-
-            // check for stack underflow
-            if SP < n_removed
-                return false
-
-            // net effect of removing and adding stack items
-            SP -= n_removed
-            SP += n_added
-
-            // check for stack overflow
-            if SP > 1024
-                return false
-
-            if instruction is STOP, RETURN, or SUICIDE
-                return true	   
-
-            // violates single entry
-            if instruction is BEGINSUB
-                 return false
-
-            // return to top or from recursion to JUMPSUB
-            if instruction is RETURNSUB
-                break;
-
-            if instruction is JUMPSUB
-            {
-                // check for enough arguments
-                sub_pc = jump_target(PC)
-                if SP < n_args(sub_pc)
-                    return false
-                return true
-            }
-
-            // reset PC to destination of jump
-            if instruction is JUMPTO
-            {
-                PC = jump_target(PC)
-                continue 
-            }
-
-            // recurse to jump to code to validate 
-            if instruction is JUMPIF
-            {
-                if not validate_subroutine(jump_target(PC), return_pc, SP)
-                    return false
-            }
-
-            // advance PC according to instruction
-            PC = advance_pc(PC)
-        }
-
-        // check for right number of results
-        if SP != n_results(return_pc)
-            return false
-        return true
-    }
-```
-
-### COSTS & CODES
-
-All of the instructions are O(1) with a small constant, requiring just a few machine operations each, whereas a `JUMP` or `JUMPI` must do an O(log n) binary search of an array of `JUMPDEST` offsets before every jump. With the cost of `JUMPI` being _high_ and the cost of `JUMP` being _mid_, we suggest the cost of `JUMPV` and `JUMPSUBV` should be _mid_, `JUMPSUB` and `JUMPIF` should be _low_, and`JUMPTO` should be _verylow_.  Measurement will tell.
-
-We tentatively suggest the following opcodes:
-```
-0x4C JUMPTO     0x5C BEGINSUB
-0x4D JUMPIF     0x5D BEGINDATA
-0X4E JUMPSUB    0x5E RETURNSUB
-0x4F JUMPSUBV
-```
-
-### GETTING THERE FROM HERE
-
-These changes would need to be implemented in phases at decent intervals:
->1 If this EIP is accepted, invalid code should be deprecated. Tools should stop generating invalid code, users should stop writing it, and clients should warn about loading it.
-
->2 A later hard fork would require clients to place only valid code on the block chain.  Note that despite the fork old EVM code will still need to be supported indefinitely.
-
-If desired, the period of deprecation can be extended indefinitely by continuing to accept code not versioned as new - but without validation.  Since we must continue to run old code this is not technically difficult. 
-
-Implementation of this proposal need not be difficult,  At the least, interpreters can simply be extended with the new opcodes and run unchanged otherwise.  The new opcodes require only a stack for the return offsets and the few pushes, pops, and assignments described above.  JIT code can use native calls.  Further optimizations include minimizing runtime checks for exceptions and taking advantage of validated code wherever possible.

From d10be75eabedcebcc91f1e64916cf1ee4777fe19 Mon Sep 17 00:00:00 2001
From: chriseth 
Date: Tue, 25 Apr 2017 12:46:22 +0200
Subject: [PATCH 0092/1085] Assign number and add clarifictaions.

---
 EIPS/returndatacopy.md | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/EIPS/returndatacopy.md b/EIPS/returndatacopy.md
index 2d4c7e8d0d55a..66bbd3e17ddca 100644
--- a/EIPS/returndatacopy.md
+++ b/EIPS/returndatacopy.md
@@ -1,6 +1,6 @@
 ## Preamble
 
-    EIP:
+    EIP: 211
     Title: New opcodes: RETURNDATASIZE and RETURNDATACOPY
     Author: Christian Reitwiessner 
     Type: Standard Track
@@ -29,16 +29,21 @@ Note that this proposal also makes the EIP that proposes to allow to return data
 
 ## Specification
 
-Add two new opcodes:
+Add two new opcodes and amend the semantics of any opcode that creates a new call frame (like `CALL`, `CREATE`, `DELEGATECALL`, ...) called call-like opcodes in the following. It is assumed that the EVM (to be more specific: an EVM call frame) has a new internal buffer of variable size, called the return data buffer. This buffer is created empty for each new call frame. Upon executing any call-like opcode, the buffer is cleared (its size is set to zero). After executing a call-like opcode, the complete return data (or failure data, see EIP [206](https://github.com/ethereum/EIPs/pull/206)) of the call is stored in the return data buffer (of the caller), and its size changed accordingly. As an exception, `CREATE` is considered to return the empty buffer in the success case and the failure data in the failure case. 
+
+As an optimization, it is possible to share the return data buffer across call frames because only one will be non-empty at any time.
 
 `RETURNDATASIZE`: `0xd`
 
-Pushes the size of the return data (or the failure return data, see EIP [206](https://github.com/ethereum/EIPs/pull/206)) of the previous call onto the stack. If there was no previous call, pushes zero.
+Pushes the size of the return data buffer onto the stack.
 Gas costs: 2 (same as `CALLDATASIZE`)
 
 `RETURNDATACOPY`: `0xe`
 
-This opcode has similar semantics to `CALLDATACOPY`, but instead of copying data from the call data, it copies data from the return data of the previous call. If the return data is accessed beyond its length, it is considered to be filled with zeros. If there was no previous call, copies zeros.
+This opcode has similar semantics to `CALLDATACOPY`, but instead of copying data from the call data, it copies data from the return data buffer. If the return data buffer is accessed beyond its size, it is considered to be filled with zeros.
+
+ALTERNATIVE: If the return data is accessed beyond its size, results in failure.
+
 Gas costs: `3 + 3 * ceil(amount / 32)` (same as `CALLDATACOPY`)
 
 ## Rationale
@@ -47,6 +52,8 @@ Other solutions that would allow returning dynamic data were considered, but the
 
 Note that the EVM implementation needs to keep the return data until the next call or the return from the current call. Since this resource was already paid for as part of the memory of the callee, it should not be a problem. Implementations may either choose to keep the full memory of the callee alive until the next call or copy only the return data to a special memory area.
 
+Keeping the memory of the callee until the next call-like opcode does not increase the peak memory usage in the following sense: Any memory allocation in the caller's frame that happens after the return from the call can be moved before the call without a change in gas costs, but will add this allocation to the peak allocation.
+
 The number values of the opcodes were allocated in the same nibble block that also contains `CALLDATASIZE` and `CALLDATACOPY`.
 
 ## Backwards Compatibility

From 598de64d6ba97bf1aa253ad579c228d0f856f044 Mon Sep 17 00:00:00 2001
From: Nick Johnson 
Date: Tue, 25 Apr 2017 15:14:22 +0100
Subject: [PATCH 0093/1085] Delete JumpsAndSubs.md

---
 EIPS/JumpsAndSubs.md | 372 -------------------------------------------
 1 file changed, 372 deletions(-)
 delete mode 100644 EIPS/JumpsAndSubs.md

diff --git a/EIPS/JumpsAndSubs.md b/EIPS/JumpsAndSubs.md
deleted file mode 100644
index 7087b31116c55..0000000000000
--- a/EIPS/JumpsAndSubs.md
+++ /dev/null
@@ -1,372 +0,0 @@
-```
-EIP: TBD
-Title: Subroutines and Static Jumps for the EVM
-Status: Draft
-Type: Core
-Author: Greg Colvin, Paweł Bylica, Christian Reitwiessner 
-Created: 2016-12-10
-Edited: 2016-29-12
-```
-## Abstract
-
-This EIP introduces new EVM opcodes and conditions on EVM code to support subroutines and static jumps, disallow dynamic jumps, and thereby make EVM code amenable to linear-time static analysis.  This will provide for better compilation, interpretation, transpilation, and formal analysis of EVM code.
-
-## MOTIVATION
-
-All current implementations of the Ethereum Virtual Machine, including the just-in-time compilers, are much too slow. This proposal identifies a major reason for this and proposes changes to the EVM specification to address the problem.
-
-In particular, it imposes restrictions on current EVM code and proposes new instructions to help provide for
-* better-optimized compilation to native code
-* faster interpretation
-* faster transpilation to eWASM
-* better compilation from other languages,
-   including eWASM and Solidity
-* better formal analysis tools
-
-These goals are achieved by
-* disallowing dynamic jumps
-* introducing subroutines - jumps with return support
-* disallowing pathological control flow and uses of the stack
-
-We also propose to validate - in linear time - that EVM contracts correctly use subroutines, avoid misuse of the stack, and meet other safety conditions _before_ placing them on the blockchain.  Validated code precludes most runtime exceptions and the need to test for them.  And well-behaved control flow and use of the stack makes life easier for interpreters, compilers, formal analysis, and other tools.
-
-## THE PROBLEM
-
-Currently the EVM supports dynamic jumps, where the address to jump to is an argument on the stack. These dynamic jumps obscure the structure of the code and thus mostly inhibit control- and data-flow analysis.  This puts the quality and speed of optimized compilation fundamentally at odds.  Further, since every jump can potentially be to any jump destination in the code, the number of possible paths through the code goes up as the product of the number of jumps by the number of destinations, as does the time complexity of static analysis.  But absent dynamic jumps code can be statically analyzed in linear time.
-
-Static analysis includes validation, and much of optimization, compilation, transpilation, and formal analysis; every part of the tool chain benefits when linear-time analysis is available.  In particular, faster control-flow analysis means faster compilation of EVM code to native code, and better data-flow analysis can help the compiler and the interpreter better track the size of the values on the stack and use native 64- and 32-bit operations when possible.  Also, conditions which are checked at validation time don’t have to be checked repeatedly at runtime.
-
-Note that analyses of a contract’s bytecode before execution - such as optimizations performed before interpretation, JIT compilation, and on-the-fly machine code generation - must be efficient and linear-time. Otherwise, specially crafted contracts can be used as attack vectors against clients that use static analysis of EVM code before the creation or execution of contracts.
-
-## PROPOSAL
-
-We propose to deprecate two existing instructions - `JUMP` and `JUMPI`. They take their argument on the stack, which means that unless the value is constant they can jump to any `JUMPDEST`.  (In simple cases like `PUSH 0 JUMP` the value on the stack can be known to be constant, but in general it's difficult.)  We must nonetheless continue to support them in old code.
-
-Having deprecated `JUMP` and `JUMPI`, we propose new instructions to support their legitimate uses.
-
-### Preliminaries
-
-These forms
-* `INSTRUCTION x,`
-* `INSTRUCTION x, y`
-* `INSTRUCTION n, x ...`
-
-name instructions with one, two, and two or more arguments, respectively.  An instruction is represented in the bytecode as a single-byte opcode.  The arguments are laid out as immediate data bytes following the opcode.  The size and encoding of immediate data fields is open to change.  In particular, easily-parsed variable-length encodings might prove useful for bytecode offsets - which are in practice small but in principle can be large.
-
-### Primitives
-
-The two most important uses of `JUMP` and `JUMPI` are static jumps and return jumps. Conditional and unconditional static jumps are the mainstay of control flow.  Return jumps are implemented as a dynamic jump to a return address pushed on the stack.  With the combination of a static jump and a dynamic return jump you can - and Solidity does - implement subroutines.  The problem is that static analysis cannot tell the one place the return jump is going, so it must analyze every possibility.
-
-Static jumps are provided by
-* `JUMPTO jump_target`
-* `JUMPIF jump_target`
-which are the same as `JUMP` and `JUMPI` except that they jump to an immediate `jump_target`, given as four immediate bytes, rather than an address on the stack.
-
-To support subroutines, `BEGINSUB`, `JUMPSUB`, and `RETURNSUB` are provided.  Brief descriptions follow, and full semantics are given below.
-
-* `BEGINSUB n_args, n_results`
-marks the **single** entry to a subroutine.  `n_args` items are taken off of the stack at entry to, and `n_results` items are placed on the stack at return from the subroutine. `n_args` and `n_results` are given as one immediate byte each.  The bytecode for a subroutine ends at the next `BEGINSUB` instruction (or `BEGINDATA`, below) or at the end of the bytecode.
-
-* `JUMPSUB jump_target`
-jumps to an immediate subroutine address, given as four immediate bytes.
-
-* `RETURNSUB`
-returns from the current subroutine to the instruction following the JUMPSUB that entered it.
-
-These five simple instructions form the primitives of the proposal.
-
-### Data
-
-In order to validate subroutines, EVM bytecode must be sequentially scanned matching jumps to their destinations.  Since creation code has to contain the runtime code as data, that code might not correctly validate in the creation context and also does not have to be validated prior to the execution of the creation code. Because of that, there needs to be a way to place data into the bytecode that will be skipped over and not validated.  Such data will prove useful for other purposes as well.
-
-* `BEGINDATA`
-specifies that all of the following bytes to the end of the bytecode are data, and not reachable code.
-
-### Indirect Jumps
-
-The primitive operations provide for static jumps.  Dynamic jumps are also used for O(1) indirection: an address to jump to is selected to push on the stack and be jumped to.  So we also propose two more instructions to provide for constrained indirection.  We support these with vectors of `JUMPDEST` or `BEGINSUB` offsets stored inline, which can be selected with an index on the stack.  That constrains validation to a specified subset of all possible destinations.  The danger of quadratic blow up is avoided because it takes as much space to store the jump vectors as it does to code the worst case exploit. 
-
-Dynamic jumps to a `JUMPDEST` are used to implement O(1) jumptables, which are useful for dense switch statements, and are implemented as instructions similar to this one on most CPUs.
-* `JUMPV n, jumpdest ...`
-jumps to one of a vector of `n` `JUMPDEST` offsets via a zero-based index on the stack.  The vector is stored inline in the bytecode.  If the index is greater than or equal to `n - 1` the last (default) offset is used.  `n` is given as four immediate bytes, all `JUMPDEST` offsets as four immediate bytes each.
-
-Dynamic jumps to a `BEGINSUB` are used to implement O(1) virtual functions and callbacks, which take just two pointer dereferences on most CPUs.
-* `JUMPSUBV n, beginsub ...`
-jumps to one of a vector of `n` `BEGINSUB` offsets via a zero-based index on the stack.  The vector is stored inline in the bytecode, MSB-first.  If the index is greater than or equal to `n - 1` the last (default) offset is used.  `n` is given as four immediate bytes, the `n` offsets as four immediate bytes each.
-
-`JUMPV` and `JUMPSUBV` are not strictly necessary.  They provide O(1) operations that can be replaced by O(n) or O(log n) EVM code using static jumps, but that code will be slower, larger and use more gas for things that can and should be fast, small, and cheap, and that are directly supported in WASM with br_table and call_indirect.
-
-### Variable Access
-
-These operations provide convenient access to subroutine parameters and other variables at fixed stack offsets within a subroutine.
-
-* `PUTLOCAL n`
-Pops the top value on the stack and copies it to local variable `n`.
-
-* `GETLOCAL n`
-Pushes the value of local variable `n` on the EVM stack.
-
-Local variable `n` is `FP[-n]` as defined below.
-
-## SEMANTICS
-
-Jumps to and returns from subroutines are described here in terms of
-* the EVM data stack, (as defined in the [Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf) usually just called “the stack”,
-* a return stack of `JUMPSUB` and `JUMPSUBV` offsets, and
-* a frame stack of frame pointers.
-
-We will adopt the following conventions to describe the machine state:
-* The _program counter_ `PC` is (as usual) the byte offset of the currently executing instruction.
-* The _stack pointer_ `SP` corresponds to the number of items on the stack - the _stack size_.  As a negative offset it addresses the current top of the stack of data values, where new items are pushed.
-* The _frame pointer_ `FP` is set to `SP + n_args` at entry to the currently executing subroutine.
-* The _stack items_ between the frame pointer and the current stack pointer are called the _frame_.
-* The current number of items in the frame, `FP - SP`, is the _frame size_.
-
-Defining the frame pointer so as to include the arguments is unconventional, but better fits our stack semantics and simplifies the remainder of the proposal.
-
-The frame pointer and return stacks are internal to the subroutine mechanism, and not directly accessible to the program.  This is necessary to prevent the program from modifying its state in ways that could be invalid.
-
-The first instruction of an array of EVM bytecode begins execution of a _main_ routine with no arguments, `SP` and `FP` set to 0, and with one value on the return stack - `code size - 1`. (Executing the virtual byte of 0 after this offset causes an EVM to stop.  Thus executing a `RETURNSUB` with no prior `JUMPSUB` or `JUMBSUBV` - that is, in the _main_ routine - executes a `STOP`.)
-
-Execution of a subroutine begins with `JUMPSUB` or `JUMPSUBV`, which
-* push `PC` on the return stack,
-* push `FP` on the frame stack,
-thus suspending execution of the current subroutine, and
-* set `FP` to `SP + n_args`, and
-* set `PC` to the specified `BEGINSUB` address,
-thus beginning execution of the new subroutine.
-(The _main_ routine is not addressable by `JUMPSUB` instructions.)
-
-Execution of a subroutine is suspended during and resumed after execution of nested subroutines, and ends upon encountering a `RETURNSUB`, which
-* sets `FP` to the top of the virtual frame stack and pops the stack, and
-* sets `PC` to top of the return stack and pops the stack
-* advances `PC` to the next instruction
-thus resuming execution of the enclosing subroutine or _main_ program.
-A `STOP or `RETURN` also ends the execution of a subroutine.
-
-## VALIDITY
-
-We would like to consider EVM code valid if and only if no execution of the program can lead to an exceptional halting state.  But we must and will validate code in linear time.  So our validation does not consider the code’s data and computations, only its control flow and stack use.  This means we will reject programs with invalid code paths, even if those paths cannot be executed at runtime.  Most conditions can be validated, and will not need to be checked at runtime; the exceptions are sufficient gas and sufficient stack.  So some false negatives and runtime checks are the price we pay for linear time validation.
-
-_Execution_ is as defined in the Yellow Paper - a sequence of changes in the EVM state.  The conditions on valid code are preserved by state changes.  At runtime, if execution of an instruction would violate a condition the execution is in an exceptional halting state.  The yellow paper defines five such states.
->1  Insufficient gas
-
->2  More than 1024 stack items
-
->3  Insufficient stack items
-
->4  Invalid jump destination
-
->5  Invalid instruction
-
-We propose to expand and extend the Yellow Paper conditions to handle the new instructions we propose. 
-
-To handle the return stack we expand the conditions on stack size:
->2a  The size of the data stack does not exceed 1024.
-
->2b  The size of the return stack does not exceed 1024.
-
-Given our more detailed description of the data stack we restate condition 3 - stack underflow - as
->3  `SP` must be less than or equal to `FP`
-
-Since the various `DUP` and `SWAP` operations are formalized as taking items off the stack and putting them back on, this prevents `DUP` and `SWAP` from accessing data below the frame pointer, since taking too many items off of the stack would mean that `SP` is less than `FP`.
-
-To handle the new jump instructions and subroutine boundaries we expand the conditions on jumps and jump destinations.
->4a  `JUMPTO`, `JUMPIF`, and `JUMPV` address only `JUMPDEST` instructions.
-
->4b  `JUMPSUB` and `JUMPSUBV` address only `BEGINSUB` instructions.
-
->4c  `JUMP` instructions do not address instructions outside of the subroutine they occur in.
-
-We have two new conditions on execution to ensure consistent use of the stack by subroutines:
->6  For `JUMPSUB` and `JUMPSUBV` the frame size is at least the `n_args` of the `BEGINSUB`(s) to jump to.
-
->7  For `RETURNSUB` the frame size is equal to the `n_results` of the enclosing `BEGINSUB`.
-
-Finally, we have one condition that prevents pathological uses of the stack:
->8  For every instruction in the code the frame size is constant.
-
-In practice, we must test at runtime for conditions 1 and 2 - sufficient gas and sufficient stack.  We don’t know how much gas there will be, we don’t know how deep a recursion may go, and analysis of stack depth even for non-recursive programs is non-trivial.
-
-All of the remaining conditions we validate statically.
-
-## VALIDATION
-
-Validation comprises two tasks:
-* Checking that jump destinations are correct and instructions valid.
-* Checking that subroutines satisfy the conditions on control flow and stack use.
-
-We sketch out these two validation functions in pseudo-C below.   To simplify the presentation only the five primitives are handled (`JUMPV` and `JUMPSUBV` would just add more complexity to loop over their vectors), we assume helper functions for extracting instruction arguments from immediate data and managing the stack pointer and program counter, and some optimizations are forgone.
-
-### Validating jumps
-
-Validating that jumps are to valid addresses takes two sequential passes over the bytecode - one to build sets of jump destinations and subroutine entry points, another to check that addresses jumped to are in the appropriate sets.
-```
-    bytecode[code_size]   // contains EVM bytecode to validate
-    is_sub[code_size]     // is there a BEGINSUB at PC?
-    is_dest[code_size]    // is there a JUMPDEST at PC?
-    sub_for_pc[code_size] // which BEGINSUB is PC in?
-    
-    bool validate_jumps(PC)
-    {
-        current_sub = PC
-
-        // build sets of BEGINSUBs and JUMPDESTs
-        for (PC = 0; instruction = bytecode[PC]; PC = advance_pc(PC))
-        {
-            if instruction is invalid
-                return false
-            if instruction is BEGINDATA
-                return true
-            if instruction is BEGINSUB
-                is_sub[PC] = true
-                current_sub = PC
-                sub_for_pc[PC] = current_sub
-            if instruction is JUMPDEST
-                is_dest[PC] = true
-            sub_for_pc[PC] = current_sub
-        }
-        
-        // check that targets are in subroutine
-        for (PC = 0; instruction = bytecode[PC]; PC = advance_pc(PC))
-        {
-            if instruction is BEGINDATA
-                break;
-            if instruction is BEGINSUB
-                current_sub = PC
-            if instruction is JUMPSUB
-                if is_sub[jump_target(PC)] is false
-                    return false
-            if instruction is JUMPTO or JUMPIF
-                if is_dest[jump_target(PC)] is false
-                    return false
-            if sub_for_pc[PC] is not current_sub
-                return false
-       }
-        return true
-    }
-```
-Note that code like this is already run by EVMs to check dynamic jumps, including building the jump destination set every time a contract is run, and doing a lookup in the jump destination set before every jump.
-
-### Validating subroutines
-
-This function can be seen as a symbolic execution of a subroutine in the EVM code, where only the effect of the instructions on the state being validated is computed.  Thus the structure of this function is very similar to an EVM interpreter.  This function can also be seen as an acyclic traversal of the directed graph formed by taking instructions as vertexes and sequential and branching connections as edges, checking conditions along the way.  The traversal is accomplished via recursion, and cycles are broken by returning when a vertex which has already been visited is reached.  The time complexity of this traversal is O(n-vertices + n-edges)
-
-The basic approach is to call `validate_subroutine(i, 0, 0)`, for _i_ equal to the first instruction in the EVM code through each `BEGINDATA` offset.  `validate_subroutine()` traverses instructions sequentially, recursing when `JUMP` and `JUMPI` instructions are encountered.  When a destination is reached that has been visited before it returns, thus breaking cycles.  It returns true if the subroutine is valid, false otherwise.
-
-```
-    bytecode[code_size]     // contains EVM bytecode to validate
-    frame_size[code_size ]  // is filled with -1
-
-    // we validate each subroutine individually, as if at top level
-    // * PC is the offset in the code to start validating at
-    // * return_pc is the top PC on return stack that RETURNSUB returns to
-    // * at top level FP = 0, so SP is both the frame size and the stack size
-    validate_subroutine(PC, return_pc, SP)
-    {
-        // traverse code sequentially, recurse for jumps
-        while true
-        {
-            instruction = bytecode[PC]
-
-            // if frame size set we have been here before
-            if frame_size[PC] >= 0
-            {
-                // check for constant frame size
-                if instruction is JUMPDEST
-                    if SP != frame_size[PC]
-                        return false
-
-                // return to break cycle
-                return true
-            }
-            frame_size[PC] = SP
-
-            // effect of instruction on stack
-            n_removed = removed_items(instructions)
-            n_added = added_items(instruction)
-
-            // check for stack underflow
-            if SP < n_removed
-                return false
-
-            // net effect of removing and adding stack items
-            SP -= n_removed
-            SP += n_added
-
-            // check for stack overflow
-            if SP > 1024
-                return false
-
-            if instruction is STOP, RETURN, or SUICIDE
-                return true	   
-
-            // violates single entry
-            if instruction is BEGINSUB
-                 return false
-
-            // return to top or from recursion to JUMPSUB
-            if instruction is RETURNSUB
-                break;
-
-            if instruction is JUMPSUB
-            {
-                // check for enough arguments
-                sub_pc = jump_target(PC)
-                if SP < n_args(sub_pc)
-                    return false
-                return true
-            }
-
-            // reset PC to destination of jump
-            if instruction is JUMPTO
-            {
-                PC = jump_target(PC)
-                continue 
-            }
-
-            // recurse to jump to code to validate 
-            if instruction is JUMPIF
-            {
-                if not validate_subroutine(jump_target(PC), return_pc, SP)
-                    return false
-            }
-
-            // advance PC according to instruction
-            PC = advance_pc(PC)
-        }
-
-        // check for right number of results
-        if SP != n_results(return_pc)
-            return false
-        return true
-    }
-```
-
-### COSTS & CODES
-
-All of the instructions are O(1) with a small constant, requiring just a few machine operations each, whereas a `JUMP` or `JUMPI` must do an O(log n) binary search of an array of `JUMPDEST` offsets before every jump. With the cost of `JUMPI` being _high_ and the cost of `JUMP` being _mid_, we suggest the cost of `JUMPV` and `JUMPSUBV` should be _mid_, `JUMPSUB` and `JUMPIF` should be _low_, and`JUMPTO` should be _verylow_.  Measurement will tell.
-
-We tentatively suggest the following opcodes:
-```
-0xB0 JUMPTO
-0xB1 JUMPIF
-0XB2 JUMPSUB
-0xB4 JUMPSUBV
-0xB5 BEGINSUB
-0xB6 BEGINDATA
-0xB8 RETURNSUB
-0xB9 PUTLOCAL
-0xBA GETLOCAL
-```
-
-### GETTING THERE FROM HERE
-
-These changes would need to be implemented in phases at decent intervals:
->1 If this EIP is accepted, invalid code should be deprecated. Tools should stop generating invalid code, users should stop writing it, and clients should warn about loading it.
-
->2 A later hard fork would require clients to place only valid code on the block chain.  Note that despite the fork old EVM code will still need to be supported indefinitely.
-
-If desired, the period of deprecation can be extended indefinitely by continuing to accept code not versioned as new - but without validation.  That is, by delaying step 2.  Since we must continue to run old code this is not technically difficult. 
-
-Implementation of this proposal need not be difficult,  At the least, interpreters can simply be extended with the new opcodes and run unchanged otherwise.  The new opcodes require only stacks for the frame pointers and return offsets and the few pushes, pops, and assignments described above.  JIT code can use native calls.  Further optimizations include minimizing runtime checks for exceptions and taking advantage of validated code wherever possible.

From 77b5fa53f1e7b10321543e34ffe23050345b345c Mon Sep 17 00:00:00 2001
From: Greg Colvin 
Date: Tue, 25 Apr 2017 16:42:40 +0200
Subject: [PATCH 0094/1085] Create eip-draft-jumps_and_subs-xyz.md

---
 EIPS/eip-draft-jumps_and_subs-xyz.md | 372 +++++++++++++++++++++++++++
 1 file changed, 372 insertions(+)
 create mode 100644 EIPS/eip-draft-jumps_and_subs-xyz.md

diff --git a/EIPS/eip-draft-jumps_and_subs-xyz.md b/EIPS/eip-draft-jumps_and_subs-xyz.md
new file mode 100644
index 0000000000000..d3a9a0d6630fa
--- /dev/null
+++ b/EIPS/eip-draft-jumps_and_subs-xyz.md
@@ -0,0 +1,372 @@
+```
+EIP: TBD
+Title: Subroutines and Static Jumps for the EVM
+Status: Draft
+Type: Core
+Author: Greg Colvin , Paweł Bylica, Christian Reitwiessner
+Created: 2016-12-10
+Edited: 2017-25-4
+```
+## Abstract
+
+This EIP introduces new EVM opcodes and conditions on EVM code to support subroutines and static jumps, disallow dynamic jumps, and thereby make EVM code amenable to linear-time static analysis.  This will provide for better compilation, interpretation, transpilation, and formal analysis of EVM code.
+
+## MOTIVATION
+
+All current implementations of the Ethereum Virtual Machine, including the just-in-time compilers, are much too slow. This proposal identifies a major reason for this and proposes changes to the EVM specification to address the problem.
+
+In particular, it imposes restrictions on current EVM code and proposes new instructions to help provide for
+* better-optimized compilation to native code
+* faster interpretation
+* faster transpilation to eWASM
+* better compilation from other languages,
+   including eWASM and Solidity
+* better formal analysis tools
+
+These goals are achieved by
+* disallowing dynamic jumps
+* introducing subroutines - jumps with return support
+* disallowing pathological control flow and uses of the stack
+
+We also propose to validate - in linear time - that EVM contracts correctly use subroutines, avoid misuse of the stack, and meet other safety conditions _before_ placing them on the blockchain.  Validated code precludes most runtime exceptions and the need to test for them.  And well-behaved control flow and use of the stack makes life easier for interpreters, compilers, formal analysis, and other tools.
+
+## THE PROBLEM
+
+Currently the EVM supports dynamic jumps, where the address to jump to is an argument on the stack. These dynamic jumps obscure the structure of the code and thus mostly inhibit control- and data-flow analysis.  This puts the quality and speed of optimized compilation fundamentally at odds.  Further, since every jump can potentially be to any jump destination in the code, the number of possible paths through the code goes up as the product of the number of jumps by the number of destinations, as does the time complexity of static analysis.  But absent dynamic jumps code can be statically analyzed in linear time.
+
+Static analysis includes validation, and much of optimization, compilation, transpilation, and formal analysis; every part of the tool chain benefits when linear-time analysis is available.  In particular, faster control-flow analysis means faster compilation of EVM code to native code, and better data-flow analysis can help the compiler and the interpreter better track the size of the values on the stack and use native 64- and 32-bit operations when possible.  Also, conditions which are checked at validation time don’t have to be checked repeatedly at runtime.
+
+Note that analyses of a contract’s bytecode before execution - such as optimizations performed before interpretation, JIT compilation, and on-the-fly machine code generation - must be efficient and linear-time. Otherwise, specially crafted contracts can be used as attack vectors against clients that use static analysis of EVM code before the creation or execution of contracts.
+
+## PROPOSAL
+
+We propose to deprecate two existing instructions - `JUMP` and `JUMPI`. They take their argument on the stack, which means that unless the value is constant they can jump to any `JUMPDEST`.  (In simple cases like `PUSH 0 JUMP` the value on the stack can be known to be constant, but in general it's difficult.)  We must nonetheless continue to support them in old code.
+
+Having deprecated `JUMP` and `JUMPI`, we propose new instructions to support their legitimate uses.
+
+### Preliminaries
+
+These forms
+* `INSTRUCTION x,`
+* `INSTRUCTION x, y`
+* `INSTRUCTION n, x ...`
+
+name instructions with one, two, and two or more arguments, respectively.  An instruction is represented in the bytecode as a single-byte opcode.  The arguments are laid out as immediate data bytes following the opcode.  The size and encoding of immediate data fields is open to change.  In particular, easily-parsed variable-length encodings might prove useful for bytecode offsets - which are in practice small but in principle can be large.
+
+### Primitives
+
+The two most important uses of `JUMP` and `JUMPI` are static jumps and return jumps. Conditional and unconditional static jumps are the mainstay of control flow.  Return jumps are implemented as a dynamic jump to a return address pushed on the stack.  With the combination of a static jump and a dynamic return jump you can - and Solidity does - implement subroutines.  The problem is that static analysis cannot tell the one place the return jump is going, so it must analyze every possibility.
+
+Static jumps are provided by
+* `JUMPTO jump_target`
+* `JUMPIF jump_target`
+which are the same as `JUMP` and `JUMPI` except that they jump to an immediate `jump_target`, given as four immediate bytes, rather than an address on the stack.
+
+To support subroutines, `BEGINSUB`, `JUMPSUB`, and `RETURNSUB` are provided.  Brief descriptions follow, and full semantics are given below.
+
+* `BEGINSUB n_args, n_results`
+marks the **single** entry to a subroutine.  `n_args` items are taken off of the stack at entry to, and `n_results` items are placed on the stack at return from the subroutine. `n_args` and `n_results` are given as one immediate byte each.  The bytecode for a subroutine ends at the next `BEGINSUB` instruction (or `BEGINDATA`, below) or at the end of the bytecode.
+
+* `JUMPSUB jump_target`
+jumps to an immediate subroutine address, given as four immediate bytes.
+
+* `RETURNSUB`
+returns from the current subroutine to the instruction following the JUMPSUB that entered it.
+
+These five simple instructions form the primitives of the proposal.
+
+### Data
+
+In order to validate subroutines, EVM bytecode must be sequentially scanned matching jumps to their destinations.  Since creation code has to contain the runtime code as data, that code might not correctly validate in the creation context and also does not have to be validated prior to the execution of the creation code. Because of that, there needs to be a way to place data into the bytecode that will be skipped over and not validated.  Such data will prove useful for other purposes as well.
+
+* `BEGINDATA`
+specifies that all of the following bytes to the end of the bytecode are data, and not reachable code.
+
+### Indirect Jumps
+
+The primitive operations provide for static jumps.  Dynamic jumps are also used for O(1) indirection: an address to jump to is selected to push on the stack and be jumped to.  So we also propose two more instructions to provide for constrained indirection.  We support these with vectors of `JUMPDEST` or `BEGINSUB` offsets stored inline, which can be selected with an index on the stack.  That constrains validation to a specified subset of all possible destinations.  The danger of quadratic blow up is avoided because it takes as much space to store the jump vectors as it does to code the worst case exploit. 
+
+Dynamic jumps to a `JUMPDEST` are used to implement O(1) jumptables, which are useful for dense switch statements, and are implemented as instructions similar to this one on most CPUs.
+* `JUMPV n, jumpdest ...`
+jumps to one of a vector of `n` `JUMPDEST` offsets via a zero-based index on the stack.  The vector is stored inline in the bytecode.  If the index is greater than or equal to `n - 1` the last (default) offset is used.  `n` is given as four immediate bytes, all `JUMPDEST` offsets as four immediate bytes each.
+
+Dynamic jumps to a `BEGINSUB` are used to implement O(1) virtual functions and callbacks, which take just two pointer dereferences on most CPUs.
+* `JUMPSUBV n, beginsub ...`
+jumps to one of a vector of `n` `BEGINSUB` offsets via a zero-based index on the stack.  The vector is stored inline in the bytecode, MSB-first.  If the index is greater than or equal to `n - 1` the last (default) offset is used.  `n` is given as four immediate bytes, the `n` offsets as four immediate bytes each.
+
+`JUMPV` and `JUMPSUBV` are not strictly necessary.  They provide O(1) operations that can be replaced by O(n) or O(log n) EVM code using static jumps, but that code will be slower, larger and use more gas for things that can and should be fast, small, and cheap, and that are directly supported in WASM with br_table and call_indirect.
+
+### Variable Access
+
+These operations provide convenient access to subroutine parameters and other variables at fixed stack offsets within a subroutine.
+
+* `PUTLOCAL n`
+Pops the top value on the stack and copies it to local variable `n`.
+
+* `GETLOCAL n`
+Pushes the value of local variable `n` on the EVM stack.
+
+Local variable `n` is `FP[-n]` as defined below.
+
+## SEMANTICS
+
+Jumps to and returns from subroutines are described here in terms of
+* the EVM data stack, (as defined in the [Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf) usually just called “the stack”,
+* a return stack of `JUMPSUB` and `JUMPSUBV` offsets, and
+* a frame stack of frame pointers.
+
+We will adopt the following conventions to describe the machine state:
+* The _program counter_ `PC` is (as usual) the byte offset of the currently executing instruction.
+* The _stack pointer_ `SP` corresponds to the number of items on the stack - the _stack size_.  As a negative offset it addresses the current top of the stack of data values, where new items are pushed.
+* The _frame pointer_ `FP` is set to `SP + n_args` at entry to the currently executing subroutine.
+* The _stack items_ between the frame pointer and the current stack pointer are called the _frame_.
+* The current number of items in the frame, `FP - SP`, is the _frame size_.
+
+Defining the frame pointer so as to include the arguments is unconventional, but better fits our stack semantics and simplifies the remainder of the proposal.
+
+The frame pointer and return stacks are internal to the subroutine mechanism, and not directly accessible to the program.  This is necessary to prevent the program from modifying its state in ways that could be invalid.
+
+The first instruction of an array of EVM bytecode begins execution of a _main_ routine with no arguments, `SP` and `FP` set to 0, and with one value on the return stack - `code size - 1`. (Executing the virtual byte of 0 after this offset causes an EVM to stop.  Thus executing a `RETURNSUB` with no prior `JUMPSUB` or `JUMBSUBV` - that is, in the _main_ routine - executes a `STOP`.)
+
+Execution of a subroutine begins with `JUMPSUB` or `JUMPSUBV`, which
+* push `PC` on the return stack,
+* push `FP` on the frame stack,
+thus suspending execution of the current subroutine, and
+* set `FP` to `SP + n_args`, and
+* set `PC` to the specified `BEGINSUB` address,
+thus beginning execution of the new subroutine.
+(The _main_ routine is not addressable by `JUMPSUB` instructions.)
+
+Execution of a subroutine is suspended during and resumed after execution of nested subroutines, and ends upon encountering a `RETURNSUB`, which
+* sets `FP` to the top of the virtual frame stack and pops the stack, and
+* sets `PC` to top of the return stack and pops the stack
+* advances `PC` to the next instruction
+thus resuming execution of the enclosing subroutine or _main_ program.
+A `STOP or `RETURN` also ends the execution of a subroutine.
+
+## VALIDITY
+
+We would like to consider EVM code valid if and only if no execution of the program can lead to an exceptional halting state.  But we must and will validate code in linear time.  So our validation does not consider the code’s data and computations, only its control flow and stack use.  This means we will reject programs with invalid code paths, even if those paths cannot be executed at runtime.  Most conditions can be validated, and will not need to be checked at runtime; the exceptions are sufficient gas and sufficient stack.  So some false negatives and runtime checks are the price we pay for linear time validation.
+
+_Execution_ is as defined in the Yellow Paper - a sequence of changes in the EVM state.  The conditions on valid code are preserved by state changes.  At runtime, if execution of an instruction would violate a condition the execution is in an exceptional halting state.  The yellow paper defines five such states.
+>1  Insufficient gas
+
+>2  More than 1024 stack items
+
+>3  Insufficient stack items
+
+>4  Invalid jump destination
+
+>5  Invalid instruction
+
+We propose to expand and extend the Yellow Paper conditions to handle the new instructions we propose. 
+
+To handle the return stack we expand the conditions on stack size:
+>2a  The size of the data stack does not exceed 1024.
+
+>2b  The size of the return stack does not exceed 1024.
+
+Given our more detailed description of the data stack we restate condition 3 - stack underflow - as
+>3  `SP` must be less than or equal to `FP`
+
+Since the various `DUP` and `SWAP` operations are formalized as taking items off the stack and putting them back on, this prevents `DUP` and `SWAP` from accessing data below the frame pointer, since taking too many items off of the stack would mean that `SP` is less than `FP`.
+
+To handle the new jump instructions and subroutine boundaries we expand the conditions on jumps and jump destinations.
+>4a  `JUMPTO`, `JUMPIF`, and `JUMPV` address only `JUMPDEST` instructions.
+
+>4b  `JUMPSUB` and `JUMPSUBV` address only `BEGINSUB` instructions.
+
+>4c  `JUMP` instructions do not address instructions outside of the subroutine they occur in.
+
+We have two new conditions on execution to ensure consistent use of the stack by subroutines:
+>6  For `JUMPSUB` and `JUMPSUBV` the frame size is at least the `n_args` of the `BEGINSUB`(s) to jump to.
+
+>7  For `RETURNSUB` the frame size is equal to the `n_results` of the enclosing `BEGINSUB`.
+
+Finally, we have one condition that prevents pathological uses of the stack:
+>8  For every instruction in the code the frame size is constant.
+
+In practice, we must test at runtime for conditions 1 and 2 - sufficient gas and sufficient stack.  We don’t know how much gas there will be, we don’t know how deep a recursion may go, and analysis of stack depth even for non-recursive programs is non-trivial.
+
+All of the remaining conditions we validate statically.
+
+## VALIDATION
+
+Validation comprises two tasks:
+* Checking that jump destinations are correct and instructions valid.
+* Checking that subroutines satisfy the conditions on control flow and stack use.
+
+We sketch out these two validation functions in pseudo-C below.   To simplify the presentation only the five primitives are handled (`JUMPV` and `JUMPSUBV` would just add more complexity to loop over their vectors), we assume helper functions for extracting instruction arguments from immediate data and managing the stack pointer and program counter, and some optimizations are forgone.
+
+### Validating jumps
+
+Validating that jumps are to valid addresses takes two sequential passes over the bytecode - one to build sets of jump destinations and subroutine entry points, another to check that addresses jumped to are in the appropriate sets.
+```
+    bytecode[code_size]   // contains EVM bytecode to validate
+    is_sub[code_size]     // is there a BEGINSUB at PC?
+    is_dest[code_size]    // is there a JUMPDEST at PC?
+    sub_for_pc[code_size] // which BEGINSUB is PC in?
+    
+    bool validate_jumps(PC)
+    {
+        current_sub = PC
+
+        // build sets of BEGINSUBs and JUMPDESTs
+        for (PC = 0; instruction = bytecode[PC]; PC = advance_pc(PC))
+        {
+            if instruction is invalid
+                return false
+            if instruction is BEGINDATA
+                return true
+            if instruction is BEGINSUB
+                is_sub[PC] = true
+                current_sub = PC
+                sub_for_pc[PC] = current_sub
+            if instruction is JUMPDEST
+                is_dest[PC] = true
+            sub_for_pc[PC] = current_sub
+        }
+        
+        // check that targets are in subroutine
+        for (PC = 0; instruction = bytecode[PC]; PC = advance_pc(PC))
+        {
+            if instruction is BEGINDATA
+                break;
+            if instruction is BEGINSUB
+                current_sub = PC
+            if instruction is JUMPSUB
+                if is_sub[jump_target(PC)] is false
+                    return false
+            if instruction is JUMPTO or JUMPIF
+                if is_dest[jump_target(PC)] is false
+                    return false
+            if sub_for_pc[PC] is not current_sub
+                return false
+       }
+        return true
+    }
+```
+Note that code like this is already run by EVMs to check dynamic jumps, including building the jump destination set every time a contract is run, and doing a lookup in the jump destination set before every jump.
+
+### Validating subroutines
+
+This function can be seen as a symbolic execution of a subroutine in the EVM code, where only the effect of the instructions on the state being validated is computed.  Thus the structure of this function is very similar to an EVM interpreter.  This function can also be seen as an acyclic traversal of the directed graph formed by taking instructions as vertexes and sequential and branching connections as edges, checking conditions along the way.  The traversal is accomplished via recursion, and cycles are broken by returning when a vertex which has already been visited is reached.  The time complexity of this traversal is O(n-vertices + n-edges)
+
+The basic approach is to call `validate_subroutine(i, 0, 0)`, for _i_ equal to the first instruction in the EVM code through each `BEGINDATA` offset.  `validate_subroutine()` traverses instructions sequentially, recursing when `JUMP` and `JUMPI` instructions are encountered.  When a destination is reached that has been visited before it returns, thus breaking cycles.  It returns true if the subroutine is valid, false otherwise.
+
+```
+    bytecode[code_size]     // contains EVM bytecode to validate
+    frame_size[code_size ]  // is filled with -1
+
+    // we validate each subroutine individually, as if at top level
+    // * PC is the offset in the code to start validating at
+    // * return_pc is the top PC on return stack that RETURNSUB returns to
+    // * at top level FP = 0, so SP is both the frame size and the stack size
+    validate_subroutine(PC, return_pc, SP)
+    {
+        // traverse code sequentially, recurse for jumps
+        while true
+        {
+            instruction = bytecode[PC]
+
+            // if frame size set we have been here before
+            if frame_size[PC] >= 0
+            {
+                // check for constant frame size
+                if instruction is JUMPDEST
+                    if SP != frame_size[PC]
+                        return false
+
+                // return to break cycle
+                return true
+            }
+            frame_size[PC] = SP
+
+            // effect of instruction on stack
+            n_removed = removed_items(instructions)
+            n_added = added_items(instruction)
+
+            // check for stack underflow
+            if SP < n_removed
+                return false
+
+            // net effect of removing and adding stack items
+            SP -= n_removed
+            SP += n_added
+
+            // check for stack overflow
+            if SP > 1024
+                return false
+
+            if instruction is STOP, RETURN, or SUICIDE
+                return true	   
+
+            // violates single entry
+            if instruction is BEGINSUB
+                 return false
+
+            // return to top or from recursion to JUMPSUB
+            if instruction is RETURNSUB
+                break;
+
+            if instruction is JUMPSUB
+            {
+                // check for enough arguments
+                sub_pc = jump_target(PC)
+                if SP < n_args(sub_pc)
+                    return false
+                return true
+            }
+
+            // reset PC to destination of jump
+            if instruction is JUMPTO
+            {
+                PC = jump_target(PC)
+                continue 
+            }
+
+            // recurse to jump to code to validate 
+            if instruction is JUMPIF
+            {
+                if not validate_subroutine(jump_target(PC), return_pc, SP)
+                    return false
+            }
+
+            // advance PC according to instruction
+            PC = advance_pc(PC)
+        }
+
+        // check for right number of results
+        if SP != n_results(return_pc)
+            return false
+        return true
+    }
+```
+
+### COSTS & CODES
+
+All of the instructions are O(1) with a small constant, requiring just a few machine operations each, whereas a `JUMP` or `JUMPI` must do an O(log n) binary search of an array of `JUMPDEST` offsets before every jump. With the cost of `JUMPI` being _high_ and the cost of `JUMP` being _mid_, we suggest the cost of `JUMPV` and `JUMPSUBV` should be _mid_, `JUMPSUB` and `JUMPIF` should be _low_, and`JUMPTO` should be _verylow_.  Measurement will tell.
+
+We tentatively suggest the following opcodes:
+```
+0xB0 JUMPTO
+0xB1 JUMPIF
+0XB2 JUMPSUB
+0xB4 JUMPSUBV
+0xB5 BEGINSUB
+0xB6 BEGINDATA
+0xB8 RETURNSUB
+0xB9 PUTLOCAL
+0xBA GETLOCAL
+```
+
+### GETTING THERE FROM HERE
+
+These changes would need to be implemented in phases at decent intervals:
+>1 If this EIP is accepted, invalid code should be deprecated. Tools should stop generating invalid code, users should stop writing it, and clients should warn about loading it.
+
+>2 A later hard fork would require clients to place only valid code on the block chain.  Note that despite the fork old EVM code will still need to be supported indefinitely.
+
+If desired, the period of deprecation can be extended indefinitely by continuing to accept code not versioned as new - but without validation.  That is, by delaying step 2.  Since we must continue to run old code this is not technically difficult. 
+
+Implementation of this proposal need not be difficult,  At the least, interpreters can simply be extended with the new opcodes and run unchanged otherwise.  The new opcodes require only stacks for the frame pointers and return offsets and the few pushes, pops, and assignments described above.  JIT code can use native calls.  Further optimizations include minimizing runtime checks for exceptions and taking advantage of validated code wherever possible.

From a8a7e5c39967d208c2098c248e418d3b7457e9ff Mon Sep 17 00:00:00 2001
From: Greg Colvin 
Date: Tue, 25 Apr 2017 17:37:07 +0200
Subject: [PATCH 0095/1085] Update eip-draft-simd-xyz.md

---
 EIPS/eip-draft-simd-xyz.md | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/EIPS/eip-draft-simd-xyz.md b/EIPS/eip-draft-simd-xyz.md
index 3d52b84fd7e36..61d6f49a3a0fc 100644
--- a/EIPS/eip-draft-simd-xyz.md
+++ b/EIPS/eip-draft-simd-xyz.md
@@ -1,10 +1,11 @@
-EIP: 
+```EIP: 
 Title: SIMD Operations for the EVM
 Author: Greg Colvin, greg@colvin.org
 Type: Standard Track
 Category: Core
 Status: Draft
 Created: 2017-04-25
+```
 
 ## ABSTRACT
 

From 77b7c902463700c486c95f6d43327267de2b2f7f Mon Sep 17 00:00:00 2001
From: Greg Colvin 
Date: Tue, 25 Apr 2017 17:38:21 +0200
Subject: [PATCH 0096/1085] Update eip-draft-simd-xyz.md

---
 EIPS/eip-draft-simd-xyz.md | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/EIPS/eip-draft-simd-xyz.md b/EIPS/eip-draft-simd-xyz.md
index 61d6f49a3a0fc..91f196a55615e 100644
--- a/EIPS/eip-draft-simd-xyz.md
+++ b/EIPS/eip-draft-simd-xyz.md
@@ -1,4 +1,5 @@
-```EIP: 
+```
+EIP: 
 Title: SIMD Operations for the EVM
 Author: Greg Colvin, greg@colvin.org
 Type: Standard Track

From 2eddd9668e9520479c3ed3e9ed67368a2cf29329 Mon Sep 17 00:00:00 2001
From: Greg Colvin 
Date: Thu, 27 Apr 2017 19:04:27 +0200
Subject: [PATCH 0097/1085] Rename eip-draft-jumps_and_subs-xyz.md to
 eip-615.md

---
 EIPS/{eip-draft-jumps_and_subs-xyz.md => eip-615.md} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename EIPS/{eip-draft-jumps_and_subs-xyz.md => eip-615.md} (100%)

diff --git a/EIPS/eip-draft-jumps_and_subs-xyz.md b/EIPS/eip-615.md
similarity index 100%
rename from EIPS/eip-draft-jumps_and_subs-xyz.md
rename to EIPS/eip-615.md

From f7329960258dd17e2a0ec91d7e76bc4f2bf45d57 Mon Sep 17 00:00:00 2001
From: Greg Colvin 
Date: Thu, 27 Apr 2017 19:09:35 +0200
Subject: [PATCH 0098/1085] Rename EIPS/eip-draft-simd-xyz.md to
 EIPS/eip-EIPS/eip-616.md.md

---
 EIPS/{eip-draft-simd-xyz.md => eip-EIPS/eip-616.md.md} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename EIPS/{eip-draft-simd-xyz.md => eip-EIPS/eip-616.md.md} (100%)

diff --git a/EIPS/eip-draft-simd-xyz.md b/EIPS/eip-EIPS/eip-616.md.md
similarity index 100%
rename from EIPS/eip-draft-simd-xyz.md
rename to EIPS/eip-EIPS/eip-616.md.md

From 4a9ccf6afc53b0faa7d2e3f6afb352053b48b6d3 Mon Sep 17 00:00:00 2001
From: Greg Colvin 
Date: Thu, 27 Apr 2017 19:14:21 +0200
Subject: [PATCH 0099/1085] Rename eip-616.md.md to eip-616.md

---
 EIPS/eip-EIPS/{eip-616.md.md => eip-616.md} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename EIPS/eip-EIPS/{eip-616.md.md => eip-616.md} (100%)

diff --git a/EIPS/eip-EIPS/eip-616.md.md b/EIPS/eip-EIPS/eip-616.md
similarity index 100%
rename from EIPS/eip-EIPS/eip-616.md.md
rename to EIPS/eip-EIPS/eip-616.md

From dc50f9dfcf239a80b1d074ce84b9376dcbeee6de Mon Sep 17 00:00:00 2001
From: Greg Colvin 
Date: Sat, 29 Apr 2017 22:53:42 +0200
Subject: [PATCH 0100/1085] Update eip-615.md

---
 EIPS/eip-615.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/EIPS/eip-615.md b/EIPS/eip-615.md
index d3a9a0d6630fa..cca829b0723ab 100644
--- a/EIPS/eip-615.md
+++ b/EIPS/eip-615.md
@@ -1,5 +1,5 @@
 ```
-EIP: TBD
+EIP: 615
 Title: Subroutines and Static Jumps for the EVM
 Status: Draft
 Type: Core

From 08a967997ff1f3c47745bbd4b1fe95e74a8a3e2f Mon Sep 17 00:00:00 2001
From: cdetrio 
Date: Sun, 30 Apr 2017 10:59:06 -0400
Subject: [PATCH 0101/1085] copy EIP-150 from issues

---
 EIPS/eip-150.md | 72 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)
 create mode 100644 EIPS/eip-150.md

diff --git a/EIPS/eip-150.md b/EIPS/eip-150.md
new file mode 100644
index 0000000000000..9e863e6a3ce81
--- /dev/null
+++ b/EIPS/eip-150.md
@@ -0,0 +1,72 @@
+EDITOR NOTE: below is a copy of the EIP 150 https://github.com/ethereum/EIPs/issues/150#issue-179028421 raw text fetched on 2017-04-30.
+
+UPDATE: version 1c of this spec has been implemented and is active on the mainnet as of block 2463000. Spec is kept unmodified for archival purposes.
+### Specification (version 1)
+
+If `block.number >= FORK_BLKNUM`, then:
+- Increase the gas cost of EXTCODESIZE to 700
+- Increase the base gas cost of EXTCODECOPY to 700
+- Increase the gas cost of BALANCE to 400
+- Increase the gas cost of SLOAD to 200
+- Increase the gas cost of CALL, DELEGATECALL, CALLCODE to 700
+- Increase the gas cost of SUICIDE to 5000
+- Increase the recommended gas limit target to 5.5 million
+- If a call asks for more gas than the maximum allowed amount, do not return an OOG error; instead, call with the maximum allowed amount of gas (this is equivalent to a version of #90)
+
+That is, substitute:
+
+```
+        extra_gas = (not ext.account_exists(to)) * opcodes.GCALLNEWACCOUNT + \
+            (value > 0) * opcodes.GCALLVALUETRANSFER
+        submsg_gas = gas + opcodes.GSTIPEND * (value > 0)
+        if compustate.gas < gas + extra_gas:
+            return vm_exception('OUT OF GAS', needed=gas+extra_gas)
+```
+
+With:
+
+```
+        extra_gas = (not ext.account_exists(to)) * opcodes.GCALLNEWACCOUNT + \
+            (value > 0) * opcodes.GCALLVALUETRANSFER
+        if compustate.gas < extra_gas:
+            return vm_exception('OUT OF GAS', needed=extra_gas)
+        if compustate.gas < gas + extra_gas:
+            gas = compustate.gas - extra_gas
+        submsg_gas = gas + opcodes.GSTIPEND * (value > 0)
+```
+### Specification (version 1b)
+
+All of the above, but:
+- Define "all but one 64th" of `N` as `N - floor(N / 64)`
+- If a call asks for more gas than the maximum allowed amount (ie. total amount of gas remaining in the parent after subtracting the gas cost of the call and memory expansion), do not return an OOG error; instead, if a call asks for more gas than all but one 64th of the maximum allowed amount, call with all but one 64th of the maximum allowed amount of gas  (this is equivalent to a version of #90 plus #114). CREATE only provides all but one 64th of the parent gas  to the child call.
+### Specification (version 1c)
+
+All of the above, and:
+
+If SUICIDE hits a newly created account, it triggers an additional gas cost of 25000 (similar to CALLs)
+### Specification (version 2)
+
+If `block.number >= METROPOLIS_FORK_BLKNUM`, then:
+- Increase the gas cost of EXTCODESIZE to 4000
+- Increase the base gas cost of EXTCODECOPY to 4000
+- Increase the gas cost of BALANCE to 400
+- Increase the gas cost of SLOAD to 200
+- Increase the gas cost of CALL, CALLDELEGATE, CALLCODE to 4000
+- Increase the gas cost of SUICIDE to 5000
+- If SUICIDE hits a newly created account, it triggers an additional gas cost of 25000 (similar to CALLs)
+- Increase the recommended gas limit target to 5.5 million
+- Define "all but one 64th" of `N` as `N - floor(N / 64)`
+- If a call asks for more gas than the maximum allowed amount, do not return an OOG error; instead, if a call asks for more gas than all but one 64th of the maximum allowed amount, call with all but one 64th of the maximum allowed amount of gas (this is equivalent to a version of #90 plus #114). CREATE only provides all but one 64th of the parent gas to the child call.
+
+When executing EXTCODESIZE, EXTCODECOPY, CALL, CALLDELEGATE or CALLCODE (but NOT BALANCE), let CODELOADING_GAS be `int(400 + len(code) / 6)`. At the end of the call, refund an additional 4000 - CODELOADING_GAS (if CODELOADING < 0, refund nothing). CREATE only provides 63/64 of the parent gas to the child call.
+### Rationale
+
+Recent denial-of-service attacks have shown that opcodes that read the state tree are under-priced relative to other opcodes. There are software changes that have been made, are being made and can be made in order to mitigate the situation; however, the fact will remain that such opcodes will be by a substantial margin the easiest known mechanism to degrade network performance via transaction spam. The concern arises because it takes a long time to read from disk, and is additionally a risk to future sharding proposals as the "attack transactions" that have so far been most successful in degrading network performance would also require tens of megabytes to provide Merkle proofs for. This EIP increases the cost of storage reading opcodes to address this concern. The costs have been derived from an updated version of the calculation table used to generate the 1.0 gas costs: https://docs.google.com/spreadsheets/d/15wghZr-Z6sRSMdmRmhls9dVXTOpxKy8Y64oy9MvDZEQ/edit#gid=0 ; the rules attempt to target a limit of 8 MB of data that needs to be read in order to process a block, and include an estimate of 500 bytes for a Merkle proof for SLOAD and 1000 for an account.
+
+The first version of the EIP aims to be simple, and adds a flat penalty of 300 gas on top of the costs calculated in this table to account for the cost of loading the code (~17-21 kb in the worst case). The second version of the EIP instead adds an explicit parameter to take into account the size of code loading. Note that this parameter is weighted ~60% below the computed weight; this is to account for the fact that loading a large contiguous of code is, on a per-byte basis, much more efficient in terms of disk seeks (which often have a minimum size of 4kb regardless of the size of the actual object) than making several Merkle queries. A worst-case contract would take 3000 gas to load; a contract 2kb in size would take ~720 gas. This also has the benefit that it prevents a potential DoS vector against precomputation-heavy JIT VMs, where an attacker calls a large contract, requires the VM to just-in-time compile its entire code, only executes for perhaps ten cycles and then leaves. Version 2b fixes a problem where EXTCODESIZE is called with a small amount of gas, so that execution tries to fetch the contract code but runs out-of-gas upon seeing its size, thereby adding a large number of bytes to the merkle proof (and required DB load unless proper caching is added) but still only costing a relatively small amount of gas.
+
+BALANCE is not affected by the per-byte changes because checking an account's balance does not require loading its code.
+
+The EIP 90 gas mechanic is introduced because without it, all current contracts that make calls would stop working as they use an expression like `msg.gas - 40` to determine how much gas to make a call with, relying on the gas cost of calls being 40. In the more complex version, EIP 114 is introduced because, given that we are making the cost of a call higher and less predictable, we have an opportunity to do it at no extra cost to currently available guarantees, and so we also achieve the benefit of replacing the call stack depth limit with a "softer" gas-based restriction, thereby eliminating call stack depth attacks as a class of attack that contract developers have to worry about and hence increasing contract programming safety. Note that with the given parameters, the de-facto maximum call stack depth is limited to ~340 (down from ~1024), mitigating the harm caused by any further potential quadratic-complexity DoS attacks that rely on calls.
+
+The gas limit increase is recommended so as to preserve the de-facto transactions-per-second processing capability of the system for average contracts.

From 92b131b1905dc22ef9316ad74bfc5c3b65434871 Mon Sep 17 00:00:00 2001
From: cdetrio 
Date: Sun, 30 Apr 2017 11:27:34 -0400
Subject: [PATCH 0102/1085] add preamble

---
 EIPS/eip-150.md | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/EIPS/eip-150.md b/EIPS/eip-150.md
index 9e863e6a3ce81..6aacf91803cb3 100644
--- a/EIPS/eip-150.md
+++ b/EIPS/eip-150.md
@@ -1,6 +1,16 @@
-EDITOR NOTE: below is a copy of the EIP 150 https://github.com/ethereum/EIPs/issues/150#issue-179028421 raw text fetched on 2017-04-30.
-
 UPDATE: version 1c of this spec has been implemented and is active on the mainnet as of block 2463000. Spec is kept unmodified for archival purposes.
+
+## Preamble
+```
+EIP: 150
+Title: Gas cost changes for IO-heavy operations
+Author: Vitalik Buterin
+Type: Standard Track
+Category: Core
+Status: Final
+Created: 2016-09-24
+```
+
 ### Specification (version 1)
 
 If `block.number >= FORK_BLKNUM`, then:

From a52b4c1b21fe0f54a2b972c8250cb6106a01a12c Mon Sep 17 00:00:00 2001
From: cdetrio 
Date: Sun, 30 Apr 2017 11:49:03 -0400
Subject: [PATCH 0103/1085] consolidate to version 1c, remove version 2

---
 EIPS/eip-150.md | 47 ++++++++++++-----------------------------------
 1 file changed, 12 insertions(+), 35 deletions(-)

diff --git a/EIPS/eip-150.md b/EIPS/eip-150.md
index 6aacf91803cb3..012f76e3b2705 100644
--- a/EIPS/eip-150.md
+++ b/EIPS/eip-150.md
@@ -1,5 +1,3 @@
-UPDATE: version 1c of this spec has been implemented and is active on the mainnet as of block 2463000. Spec is kept unmodified for archival purposes.
-
 ## Preamble
 ```
 EIP: 150
@@ -11,7 +9,7 @@ Status: Final
 Created: 2016-09-24
 ```
 
-### Specification (version 1)
+### Specification
 
 If `block.number >= FORK_BLKNUM`, then:
 - Increase the gas cost of EXTCODESIZE to 700
@@ -19,64 +17,43 @@ If `block.number >= FORK_BLKNUM`, then:
 - Increase the gas cost of BALANCE to 400
 - Increase the gas cost of SLOAD to 200
 - Increase the gas cost of CALL, DELEGATECALL, CALLCODE to 700
-- Increase the gas cost of SUICIDE to 5000
+- Increase the gas cost of SELFDESTRUCT to 5000
+- If SELFDESTRUCT hits a newly created account, it triggers an additional gas cost of 25000 (similar to CALLs)
 - Increase the recommended gas limit target to 5.5 million
-- If a call asks for more gas than the maximum allowed amount, do not return an OOG error; instead, call with the maximum allowed amount of gas (this is equivalent to a version of #90)
+- Define "all but one 64th" of `N` as `N - floor(N / 64)`
+- If a call asks for more gas than the maximum allowed amount (ie. total amount of gas remaining in the parent after subtracting the gas cost of the call and memory expansion), do not return an OOG error; instead, if a call asks for more gas than all but one 64th of the maximum allowed amount, call with all but one 64th of the maximum allowed amount of gas (this is equivalent to a version of #90 plus #114). CREATE only provides all but one 64th of the parent gas to the child call.
 
 That is, substitute:
 
 ```
         extra_gas = (not ext.account_exists(to)) * opcodes.GCALLNEWACCOUNT + \
             (value > 0) * opcodes.GCALLVALUETRANSFER
-        submsg_gas = gas + opcodes.GSTIPEND * (value > 0)
         if compustate.gas < gas + extra_gas:
             return vm_exception('OUT OF GAS', needed=gas+extra_gas)
+        submsg_gas = gas + opcodes.GSTIPEND * (value > 0)
 ```
 
 With:
 
 ```
+        def max_call_gas(gas):
+          return gas - (gas // 64)
+
         extra_gas = (not ext.account_exists(to)) * opcodes.GCALLNEWACCOUNT + \
             (value > 0) * opcodes.GCALLVALUETRANSFER
         if compustate.gas < extra_gas:
             return vm_exception('OUT OF GAS', needed=extra_gas)
         if compustate.gas < gas + extra_gas:
-            gas = compustate.gas - extra_gas
+            gas = min(gas, max_call_gas(compustate.gas - extra_gas))
         submsg_gas = gas + opcodes.GSTIPEND * (value > 0)
 ```
-### Specification (version 1b)
-
-All of the above, but:
-- Define "all but one 64th" of `N` as `N - floor(N / 64)`
-- If a call asks for more gas than the maximum allowed amount (ie. total amount of gas remaining in the parent after subtracting the gas cost of the call and memory expansion), do not return an OOG error; instead, if a call asks for more gas than all but one 64th of the maximum allowed amount, call with all but one 64th of the maximum allowed amount of gas  (this is equivalent to a version of #90 plus #114). CREATE only provides all but one 64th of the parent gas  to the child call.
-### Specification (version 1c)
-
-All of the above, and:
 
-If SUICIDE hits a newly created account, it triggers an additional gas cost of 25000 (similar to CALLs)
-### Specification (version 2)
-
-If `block.number >= METROPOLIS_FORK_BLKNUM`, then:
-- Increase the gas cost of EXTCODESIZE to 4000
-- Increase the base gas cost of EXTCODECOPY to 4000
-- Increase the gas cost of BALANCE to 400
-- Increase the gas cost of SLOAD to 200
-- Increase the gas cost of CALL, CALLDELEGATE, CALLCODE to 4000
-- Increase the gas cost of SUICIDE to 5000
-- If SUICIDE hits a newly created account, it triggers an additional gas cost of 25000 (similar to CALLs)
-- Increase the recommended gas limit target to 5.5 million
-- Define "all but one 64th" of `N` as `N - floor(N / 64)`
-- If a call asks for more gas than the maximum allowed amount, do not return an OOG error; instead, if a call asks for more gas than all but one 64th of the maximum allowed amount, call with all but one 64th of the maximum allowed amount of gas (this is equivalent to a version of #90 plus #114). CREATE only provides all but one 64th of the parent gas to the child call.
-
-When executing EXTCODESIZE, EXTCODECOPY, CALL, CALLDELEGATE or CALLCODE (but NOT BALANCE), let CODELOADING_GAS be `int(400 + len(code) / 6)`. At the end of the call, refund an additional 4000 - CODELOADING_GAS (if CODELOADING < 0, refund nothing). CREATE only provides 63/64 of the parent gas to the child call.
 ### Rationale
 
 Recent denial-of-service attacks have shown that opcodes that read the state tree are under-priced relative to other opcodes. There are software changes that have been made, are being made and can be made in order to mitigate the situation; however, the fact will remain that such opcodes will be by a substantial margin the easiest known mechanism to degrade network performance via transaction spam. The concern arises because it takes a long time to read from disk, and is additionally a risk to future sharding proposals as the "attack transactions" that have so far been most successful in degrading network performance would also require tens of megabytes to provide Merkle proofs for. This EIP increases the cost of storage reading opcodes to address this concern. The costs have been derived from an updated version of the calculation table used to generate the 1.0 gas costs: https://docs.google.com/spreadsheets/d/15wghZr-Z6sRSMdmRmhls9dVXTOpxKy8Y64oy9MvDZEQ/edit#gid=0 ; the rules attempt to target a limit of 8 MB of data that needs to be read in order to process a block, and include an estimate of 500 bytes for a Merkle proof for SLOAD and 1000 for an account.
 
-The first version of the EIP aims to be simple, and adds a flat penalty of 300 gas on top of the costs calculated in this table to account for the cost of loading the code (~17-21 kb in the worst case). The second version of the EIP instead adds an explicit parameter to take into account the size of code loading. Note that this parameter is weighted ~60% below the computed weight; this is to account for the fact that loading a large contiguous of code is, on a per-byte basis, much more efficient in terms of disk seeks (which often have a minimum size of 4kb regardless of the size of the actual object) than making several Merkle queries. A worst-case contract would take 3000 gas to load; a contract 2kb in size would take ~720 gas. This also has the benefit that it prevents a potential DoS vector against precomputation-heavy JIT VMs, where an attacker calls a large contract, requires the VM to just-in-time compile its entire code, only executes for perhaps ten cycles and then leaves. Version 2b fixes a problem where EXTCODESIZE is called with a small amount of gas, so that execution tries to fetch the contract code but runs out-of-gas upon seeing its size, thereby adding a large number of bytes to the merkle proof (and required DB load unless proper caching is added) but still only costing a relatively small amount of gas.
-
-BALANCE is not affected by the per-byte changes because checking an account's balance does not require loading its code.
+This EIP aims to be simple, and adds a flat penalty of 300 gas on top of the costs calculated in this table to account for the cost of loading the code (~17-21 kb in the worst case).
 
-The EIP 90 gas mechanic is introduced because without it, all current contracts that make calls would stop working as they use an expression like `msg.gas - 40` to determine how much gas to make a call with, relying on the gas cost of calls being 40. In the more complex version, EIP 114 is introduced because, given that we are making the cost of a call higher and less predictable, we have an opportunity to do it at no extra cost to currently available guarantees, and so we also achieve the benefit of replacing the call stack depth limit with a "softer" gas-based restriction, thereby eliminating call stack depth attacks as a class of attack that contract developers have to worry about and hence increasing contract programming safety. Note that with the given parameters, the de-facto maximum call stack depth is limited to ~340 (down from ~1024), mitigating the harm caused by any further potential quadratic-complexity DoS attacks that rely on calls.
+The EIP 90 gas mechanic is introduced because without it, all current contracts that make calls would stop working as they use an expression like `msg.gas - 40` to determine how much gas to make a call with, relying on the gas cost of calls being 40. Additionally, EIP 114 is introduced because, given that we are making the cost of a call higher and less predictable, we have an opportunity to do it at no extra cost to currently available guarantees, and so we also achieve the benefit of replacing the call stack depth limit with a "softer" gas-based restriction, thereby eliminating call stack depth attacks as a class of attack that contract developers have to worry about and hence increasing contract programming safety. Note that with the given parameters, the de-facto maximum call stack depth is limited to ~340 (down from ~1024), mitigating the harm caused by any further potential quadratic-complexity DoS attacks that rely on calls.
 
 The gas limit increase is recommended so as to preserve the de-facto transactions-per-second processing capability of the system for average contracts.

From a5745270524b2cd0a2ac12ada22248aa36a17e5a Mon Sep 17 00:00:00 2001
From: Guanqun Lu 
Date: Wed, 3 May 2017 21:11:11 +0800
Subject: [PATCH 0104/1085] typo fix in README (#622)

It should be a "|" instead of "[".
---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 58fbc6bf358a2..fcf8298772df8 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP
 | [6](EIPS/eip-6.md)                                      | Renaming Suicide Opcode                                     | Hudson Jameson  | Standard  | Interface   | Final   |
 | [7](EIPS/eip-7.md)                                      | DELEGATECALL                                                | Vitalik Buterin | Standard  | Core        | Final   |
 | [8](EIPS/eip-8.md)                                      | devp2p Forward Compatibility Requirements for Homestead     | Felix Lange     | Standard  | Networking  | Final   |
-[ [141](EIPS/eip-141.md)                                  | Designated invalid EVM instruction                          | Alex Beregsazszi| Standard  | Core        | Final   |
+| [141](EIPS/eip-141.md)                                  | Designated invalid EVM instruction                          | Alex Beregsazszi| Standard  | Core        | Final   |
 | [150](https://github.com/ethereum/EIPs/issues/150)      | Gas cost changes for IO-heavy operations                    | Vitalik Buterin | Standard  | Core        | Final   |
 | [155](https://github.com/ethereum/EIPs/issues/155)      | Simple replay attack protection                             | Vitalik Buterin | Standard  | Core        | Final   |
 | [160](https://github.com/ethereum/EIPs/issues/160)      | EXP cost increase                                           | Vitalik Buterin | Standard  | Core        | Final   |

From b63f08f2017c30639d5c76f7baf24ccd007dc674 Mon Sep 17 00:00:00 2001
From: cdetrio 
Date: Wed, 3 May 2017 09:48:10 -0400
Subject: [PATCH 0105/1085] add EIP-186 to consideration table, remove Type
 column

---
 README.md | 57 ++++++++++++++++++++++++++++---------------------------
 1 file changed, 29 insertions(+), 28 deletions(-)

diff --git a/README.md b/README.md
index fcf8298772df8..84246b6254ee6 100644
--- a/README.md
+++ b/README.md
@@ -10,36 +10,37 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP
 * **Final** - an EIP that has been adopted in a previous hard fork (for Core/Consensus layer EIPs).
 * **Deferred** - an EIP that is not being considered for immediate adoption. May be reconsidered in the future for a subsequent hard fork.
 
+# EIPs under consideration
+| Number                                                  |Title                                                                                | Author                | Layer       | Status    |
+| ------------------------------------------------------  | ----------------------------------------------------------------------------------- | --------------------  | ------------| ----------|
+| [186](https://github.com/ethereum/EIPs/issues/186)      | Reduce ETH issuance before proof-of-stake                                           | Matthew Light         | Core        | Draft     |
+
 
 # Accepted EIPs (planned for adoption)
-| Number                                                  |Title                                                                                | Author                | Type      | Layer       | Status    | 
-| ------------------------------------------------------- | ----------------------------------------------------------------------------------- | --------------------  | ----------| ------------| ----------|
-| [86](https://github.com/ethereum/EIPs/pull/208)         | Abstraction of transaction origin and signature                                     | Vitalik Buterin       | Standard  | Core        | Accepted  |
-| [96](https://github.com/ethereum/EIPs/pull/210)         | Blockhash refactoring                                                               | Vitalik Buterin       | Standard  | Core        | Accepted  |
-| [98](https://github.com/ethereum/EIPs/pull/98)          | Removal of intermediate state roots from receipts                                   | Vitalik Buterin       | Standard  | Core        | Accepted  |
-| [100](https://github.com/ethereum/EIPs/issues/100)      | Change difficulty adjustment to target mean block time including uncles	            | Vitalik Buterin       | Standard  | Core        | Accepted  |
-| [140](https://github.com/ethereum/EIPs/pull/206)        | REVERT instruction in the Ethereum Virtual Machine                                  | Beregszaszi, Mushegian| Standard  | Core        | Accepted  |
-| [196](https://github.com/ethereum/EIPs/pull/213)        | Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 | Reitwiessner | Standard  | Core        | Accepted  |
-| [197](https://github.com/ethereum/EIPs/pull/212)        | Precompiled contracts for optimal Ate pairing check on the elliptic curve alt_bn128 | Buterin, Reitwiessner | Standard  | Core        | Accepted  |
-| [198](https://github.com/ethereum/EIPs/pull/198)        | Precompiled contract for bigint modular exponentiation				                      | Vitalik Buterin       | Standard  | Core        | Accepted  |
-| [211](https://github.com/ethereum/EIPs/pull/211)        | New opcodes: RETURNDATASIZE and RETURNDATACOPY                                      | Christian Reitwiessner| Standard  | Core        | Accepted     |
-| [214](https://github.com/ethereum/EIPs/pull/214)        | New opcode STATICCALL                                                               | Buterin, Reitwiessner | Standard  | Core        | Accepted     |
+| Number                                                  |Title                                                                                | Author                | Layer       | Status    |
+| ------------------------------------------------------- | ----------------------------------------------------------------------------------- | --------------------  | ------------| ----------|
+| [86](https://github.com/ethereum/EIPs/pull/208)         | Abstraction of transaction origin and signature                                     | Vitalik Buterin       | Core        | Accepted  |
+| [96](https://github.com/ethereum/EIPs/pull/210)         | Blockhash refactoring                                                               | Vitalik Buterin       | Core        | Accepted  |
+| [98](https://github.com/ethereum/EIPs/pull/98)          | Removal of intermediate state roots from receipts                                   | Vitalik Buterin       | Core        | Accepted  |
+| [100](https://github.com/ethereum/EIPs/issues/100)      | Change difficulty adjustment to target mean block time including uncles	            | Vitalik Buterin       | Core        | Accepted  |
+| [140](https://github.com/ethereum/EIPs/pull/206)        | REVERT instruction in the Ethereum Virtual Machine                                  | Beregszaszi, Mushegian| Core        | Accepted  |
+| [196](https://github.com/ethereum/EIPs/pull/213)        | Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 | Reitwiessner | Core        | Accepted  |
+| [197](https://github.com/ethereum/EIPs/pull/212)        | Precompiled contracts for optimal Ate pairing check on the elliptic curve alt_bn128 | Buterin, Reitwiessner | Core        | Accepted  |
+| [198](https://github.com/ethereum/EIPs/pull/198)        | Precompiled contract for bigint modular exponentiation				                      | Vitalik Buterin       | Core        | Accepted  |
+| [211](https://github.com/ethereum/EIPs/pull/211)        | New opcodes: RETURNDATASIZE and RETURNDATACOPY                                      | Christian Reitwiessner| Core        | Accepted  |
+| [214](https://github.com/ethereum/EIPs/pull/214)        | New opcode STATICCALL                                                               | Buterin, Reitwiessner | Core        | Accepted  |
 
 
 # Finalized EIPs (standards that have been adopted)
-| Number                                                  |Title                                                        | Author          | Type      | Layer       | Status  | 
-| ------------------------------------------------------- | ----------------------------------------------------------- | ----------------| ----------| ------------| --------|
-| [2](EIPS/eip-2.mediawiki)                               | Homestead Hard-fork Changes                                 | Vitalik Buterin | Standard  | Core        | Final   |
-| [6](EIPS/eip-6.md)                                      | Renaming Suicide Opcode                                     | Hudson Jameson  | Standard  | Interface   | Final   |
-| [7](EIPS/eip-7.md)                                      | DELEGATECALL                                                | Vitalik Buterin | Standard  | Core        | Final   |
-| [8](EIPS/eip-8.md)                                      | devp2p Forward Compatibility Requirements for Homestead     | Felix Lange     | Standard  | Networking  | Final   |
-| [141](EIPS/eip-141.md)                                  | Designated invalid EVM instruction                          | Alex Beregsazszi| Standard  | Core        | Final   |
-| [150](https://github.com/ethereum/EIPs/issues/150)      | Gas cost changes for IO-heavy operations                    | Vitalik Buterin | Standard  | Core        | Final   |
-| [155](https://github.com/ethereum/EIPs/issues/155)      | Simple replay attack protection                             | Vitalik Buterin | Standard  | Core        | Final   |
-| [160](https://github.com/ethereum/EIPs/issues/160)      | EXP cost increase                                           | Vitalik Buterin | Standard  | Core        | Final   |
-| [161](https://github.com/ethereum/EIPs/issues/161)      | State trie clearing (invariant-preserving alternative)      | Gavin Wood      | Standard  | Core        | Final   |
-| [170](https://github.com/ethereum/EIPs/issues/170)      | Contract code size limit                                    | Vitalik Buterin | Standard  | Core        | Final   |
-
-# EIPs under consideration
-| Number                                                  |Title                                                                                | Author                | Type      | Layer       | Status    | 
-| ------------------------------------------------------  | ----------------------------------------------------------------------------------- | --------------------  | ----------| ------------| ----------|
+| Number                                                  |Title                                                        | Author          | Layer       | Status  |
+| ------------------------------------------------------- | ----------------------------------------------------------- | ----------------| ------------| --------|
+| [2](EIPS/eip-2.mediawiki)                               | Homestead Hard-fork Changes                                 | Vitalik Buterin | Core        | Final   |
+| [6](EIPS/eip-6.md)                                      | Renaming Suicide Opcode                                     | Hudson Jameson  | Interface   | Final   |
+| [7](EIPS/eip-7.md)                                      | DELEGATECALL                                                | Vitalik Buterin | Core        | Final   |
+| [8](EIPS/eip-8.md)                                      | devp2p Forward Compatibility Requirements for Homestead     | Felix Lange     | Networking  | Final   |
+| [141](EIPS/eip-141.md)                                  | Designated invalid EVM instruction                          | Alex Beregsazszi| Core        | Final   |
+| [150](https://github.com/ethereum/EIPs/issues/150)      | Gas cost changes for IO-heavy operations                    | Vitalik Buterin | Core        | Final   |
+| [155](https://github.com/ethereum/EIPs/issues/155)      | Simple replay attack protection                             | Vitalik Buterin | Core        | Final   |
+| [160](https://github.com/ethereum/EIPs/issues/160)      | EXP cost increase                                           | Vitalik Buterin | Core        | Final   |
+| [161](https://github.com/ethereum/EIPs/issues/161)      | State trie clearing (invariant-preserving alternative)      | Gavin Wood      | Core        | Final   |
+| [170](https://github.com/ethereum/EIPs/issues/170)      | Contract code size limit                                    | Vitalik Buterin | Core        | Final   |

From 87f46deb658465d678daf47327c5be7fea1ddd01 Mon Sep 17 00:00:00 2001
From: Guanqun Lu 
Date: Wed, 3 May 2017 23:08:34 +0800
Subject: [PATCH 0106/1085] fix typos in EIP 1

---
 EIPS/eip-1.md | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md
index 3661248aa4cb1..6f4e038bcd2fa 100644
--- a/EIPS/eip-1.md
+++ b/EIPS/eip-1.md
@@ -28,7 +28,7 @@ There are three types of EIP:
     -   **Interface** - includes improvements around client [API/RPC] specifications and standards, and also certain language-level standards like method names ([EIP59], [EIP6]) and [contract ABIs]. The label “interface” aligns with the [interfaces repo] and discussion should primarily occur in that repository before an EIP is submitted to the EIPs repository.
     -   **ERC** - application-level standards and conventions, including contract standards such as token standards ([ERC20]), name registries ([ERC26], [ERC137]), URI schemes ([ERC67]), library/package formats ([EIP82]), and wallet formats ([EIP75], [EIP85]).
 
--   An **Informational EIP** describes a Ethereum design issue, or provides general guidelines or information to the Ethereum community, but does not propose a new feature. Informational EIPs do not necessarily represent Ethereum community consensus or a recommendation, so users and implementors are free to ignore Informational EIPs or follow their advice.
+-   An **Informational EIP** describes a Ethereum design issue, or provides general guidelines or information to the Ethereum community, but does not propose a new feature. Informational EIPs do not necessarily represent Ethereum community consensus or a recommendation, so users and implementers are free to ignore Informational EIPs or follow their advice.
 -   A **Meta EIP** describes a process surrounding Ethereum or proposes a change to (or an event in) a process. Process EIPs are like Standards Track EIPs but apply to areas other than the Ethereum protocol itself. They may propose an implementation, but not to Ethereum's codebase; they often require community consensus; unlike Informational EIPs, they are more than recommendations, and users are typically not free to ignore them. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in Ethereum development. Any meta-EIP is also considered a Process EIP.
 
 EIP Work Flow
@@ -42,13 +42,13 @@ Each EIP must have a champion - someone who writes the EIP using the style and f
 
 Vetting an idea publicly before going as far as writing a EIP is meant to save the potential author time. Asking the Ethereum community first if an idea is original helps prevent too much time being spent on something that is guaranteed to be rejected based on prior discussions (searching the Internet does not always do the trick). It also helps to make sure the idea is applicable to the entire community and not just the author. Just because an idea sounds good to the author does not mean it will work for most people in most areas where Ethereum is used. Examples of appropriate public forums to gauge interest around your EIP include [the Ethereum subreddit], [the Issues section of this repository], and [one of the Ethereum Gitter chat rooms]. In particular, [the Issues section of this repository] is an excellent place to discuss your proposal with the community and start creating more formalized language around your EIP. 
 
-Once the champion has asked the Ethereum community whether an idea has any chance of acceptance a draft EIP should be presented as a [pull request]. This gives the author a chance to coninuously edit the draft EIP for proper formatting and quality. This also allows for further public comment and the author of the EIP to address concerns about the proposal.
+Once the champion has asked the Ethereum community whether an idea has any chance of acceptance a draft EIP should be presented as a [pull request]. This gives the author a chance to continuously edit the draft EIP for proper formatting and quality. This also allows for further public comment and the author of the EIP to address concerns about the proposal.
 
-If the EIP collaborators approves, the EIP editor will assign the EIP a number (generally the issue or PR number related to the EIP), label it as Standards Track, Informational, or Meta, give it status “Draft”, and add it to the git repository. The EIP editor will not unreasonably deny an EIP. Reasons for denying EIP status include duplication of effort, being technically unsound, not providing proper motivation or addressing backwards compatibility, or not in keeping with the Ethereum philosophy.
+If the EIP collaborators approve, the EIP editor will assign the EIP a number (generally the issue or PR number related to the EIP), label it as Standards Track, Informational, or Meta, give it status “Draft”, and add it to the git repository. The EIP editor will not unreasonably deny an EIP. Reasons for denying EIP status include duplication of effort, being technically unsound, not providing proper motivation or addressing backwards compatibility, or not in keeping with the Ethereum philosophy.
 
 Standards Track EIPs consist of three parts, a design document, implementation, and finally if warranted an update to the [formal specification]. The EIP should be reviewed and accepted before an implementation is begun, unless an implementation will aid people in studying the EIP. Standards Track EIPs must be implemented in at least three viable Ethereum clients before it can be considered Final.
 
-For an EIP to be accepted it must meet certain minimum criteria. It must be a clear and complete description of the proposed enhancement. The enhancement must represent a net improvement. The proposed implementation, if applicable, must be solid and must not complicate the protocol unduly.
+For a EIP to be accepted it must meet certain minimum criteria. It must be a clear and complete description of the proposed enhancement. The enhancement must represent a net improvement. The proposed implementation, if applicable, must be solid and must not complicate the protocol unduly.
 
 Once a EIP has been accepted, the implementations must be completed. When the implementation is complete and accepted by the community, the status will be changed to “Final”.
 
@@ -203,7 +203,7 @@ If the EIP isn't ready, the editor will send it back to the author for revision,
 
 Once the EIP is ready for the repository, the EIP editor will:
 
--   Assign a EIP number (generally the PR number or, if preferred by the author, the Issue # if ther was discussion in the Issues section of this repository about this EIP)
+-   Assign a EIP number (generally the PR number or, if preferred by the author, the Issue # if there was discussion in the Issues section of this repository about this EIP)
 
 
 

From 1a0a7ef64d6d87167c0b326778f95098e5ad621a Mon Sep 17 00:00:00 2001
From: Lu Guanqun 
Date: Wed, 3 May 2017 23:10:54 -0500
Subject: [PATCH 0107/1085] use 'an EIP' instead of 'a EIP'

---
 EIPS/eip-1.md | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md
index 6f4e038bcd2fa..1299f4238d565 100644
--- a/EIPS/eip-1.md
+++ b/EIPS/eip-1.md
@@ -5,10 +5,10 @@
       Author: Martin Becze , Hudson Jameson 
       Created: 2015-10-27, 2017-02-01
 
-What is a EIP?
+What is an EIP?
 --------------
 
-EIP stands for Ethereum Improvement Proposal. A EIP is a design document providing information to the Ethereum community, or describing a new feature for Ethereum or its processes or environment. The EIP should provide a concise technical specification of the feature and a rationale for the feature. The EIP author is responsible for building consensus within the community and documenting dissenting opinions.
+EIP stands for Ethereum Improvement Proposal. An EIP is a design document providing information to the Ethereum community, or describing a new feature for Ethereum or its processes or environment. The EIP should provide a concise technical specification of the feature and a rationale for the feature. The EIP author is responsible for building consensus within the community and documenting dissenting opinions.
 
 EIP Rational
 ------------
@@ -40,7 +40,7 @@ The EIP process begins with a new idea for Ethereum. It is highly recommended th
 
 Each EIP must have a champion - someone who writes the EIP using the style and format described below, shepherds the discussions in the appropriate forums, and attempts to build community consensus around the idea.
 
-Vetting an idea publicly before going as far as writing a EIP is meant to save the potential author time. Asking the Ethereum community first if an idea is original helps prevent too much time being spent on something that is guaranteed to be rejected based on prior discussions (searching the Internet does not always do the trick). It also helps to make sure the idea is applicable to the entire community and not just the author. Just because an idea sounds good to the author does not mean it will work for most people in most areas where Ethereum is used. Examples of appropriate public forums to gauge interest around your EIP include [the Ethereum subreddit], [the Issues section of this repository], and [one of the Ethereum Gitter chat rooms]. In particular, [the Issues section of this repository] is an excellent place to discuss your proposal with the community and start creating more formalized language around your EIP. 
+Vetting an idea publicly before going as far as writing an EIP is meant to save the potential author time. Asking the Ethereum community first if an idea is original helps prevent too much time being spent on something that is guaranteed to be rejected based on prior discussions (searching the Internet does not always do the trick). It also helps to make sure the idea is applicable to the entire community and not just the author. Just because an idea sounds good to the author does not mean it will work for most people in most areas where Ethereum is used. Examples of appropriate public forums to gauge interest around your EIP include [the Ethereum subreddit], [the Issues section of this repository], and [one of the Ethereum Gitter chat rooms]. In particular, [the Issues section of this repository] is an excellent place to discuss your proposal with the community and start creating more formalized language around your EIP. 
 
 Once the champion has asked the Ethereum community whether an idea has any chance of acceptance a draft EIP should be presented as a [pull request]. This gives the author a chance to continuously edit the draft EIP for proper formatting and quality. This also allows for further public comment and the author of the EIP to address concerns about the proposal.
 
@@ -48,13 +48,13 @@ If the EIP collaborators approve, the EIP editor will assign the EIP a number (g
 
 Standards Track EIPs consist of three parts, a design document, implementation, and finally if warranted an update to the [formal specification]. The EIP should be reviewed and accepted before an implementation is begun, unless an implementation will aid people in studying the EIP. Standards Track EIPs must be implemented in at least three viable Ethereum clients before it can be considered Final.
 
-For a EIP to be accepted it must meet certain minimum criteria. It must be a clear and complete description of the proposed enhancement. The enhancement must represent a net improvement. The proposed implementation, if applicable, must be solid and must not complicate the protocol unduly.
+For an EIP to be accepted it must meet certain minimum criteria. It must be a clear and complete description of the proposed enhancement. The enhancement must represent a net improvement. The proposed implementation, if applicable, must be solid and must not complicate the protocol unduly.
 
-Once a EIP has been accepted, the implementations must be completed. When the implementation is complete and accepted by the community, the status will be changed to “Final”.
+Once an EIP has been accepted, the implementations must be completed. When the implementation is complete and accepted by the community, the status will be changed to “Final”.
 
-A EIP can also be assigned status “Deferred”. The EIP author or editor can assign the EIP this status when no progress is being made on the EIP. Once a EIP is deferred, the EIP editor can re-assign it to draft status.
+An EIP can also be assigned status “Deferred”. The EIP author or editor can assign the EIP this status when no progress is being made on the EIP. Once an EIP is deferred, the EIP editor can re-assign it to draft status.
 
-A EIP can also be “Rejected”. Perhaps after all is said and done it was not a good idea. It is still important to have a record of this fact.
+An EIP can also be “Rejected”. Perhaps after all is said and done it was not a good idea. It is still important to have a record of this fact.
 
 EIPs can also be superseded by a different EIP, rendering the original obsolete.
 
@@ -145,7 +145,7 @@ if the email address is not given.
 
 Note: The Resolution header is required for Standards Track EIPs only. It contains a URL that should point to an email message or other web resource where the pronouncement about the EIP is made.
 
-While a EIP is in private discussions (usually during the initial Draft phase), a Discussions-To header will indicate the mailing list or URL where the EIP is being discussed. No Discussions-To header is necessary if the EIP is being discussed privately with the author.
+While an EIP is in private discussions (usually during the initial Draft phase), a Discussions-To header will indicate the mailing list or URL where the EIP is being discussed. No Discussions-To header is necessary if the EIP is being discussed privately with the author.
 
 The Type header specifies the type of EIP: Standards Track, Meta, or Informational. If the track is Standards please include the subcategory (core, networking, interface, or ERC).
 
@@ -153,7 +153,7 @@ The Created header records the date that the EIP was assigned a number. Both hea
 
 EIPs may have a Requires header, indicating the EIP numbers that this EIP depends on.
 
-EIPs may also have a Superseded-By header indicating that a EIP has been rendered obsolete by a later document; the value is the number of the EIP that replaces the current document. The newer EIP must have a Replaces header containing the number of the EIP that it rendered obsolete.
+EIPs may also have a Superseded-By header indicating that an EIP has been rendered obsolete by a later document; the value is the number of the EIP that replaces the current document. The newer EIP must have a Replaces header containing the number of the EIP that it rendered obsolete.
 
 Auxiliary Files
 ---------------
@@ -163,9 +163,9 @@ EIPs may include auxiliary files such as diagrams. Such files must be named EIP-
 Transferring EIP Ownership
 --------------------------
 
-It occasionally becomes necessary to transfer ownership of EIPs to a new champion. In general, we'd like to retain the original author as a co-author of the transferred EIP, but that's really up to the original author. A good reason to transfer ownership is because the original author no longer has the time or interest in updating it or following through with the EIP process, or has fallen off the face of the 'net (i.e. is unreachable or not responding to email). A bad reason to transfer ownership is because you don't agree with the direction of the EIP. We try to build consensus around a EIP, but if that's not possible, you can always submit a competing EIP.
+It occasionally becomes necessary to transfer ownership of EIPs to a new champion. In general, we'd like to retain the original author as a co-author of the transferred EIP, but that's really up to the original author. A good reason to transfer ownership is because the original author no longer has the time or interest in updating it or following through with the EIP process, or has fallen off the face of the 'net (i.e. is unreachable or not responding to email). A bad reason to transfer ownership is because you don't agree with the direction of the EIP. We try to build consensus around an EIP, but if that's not possible, you can always submit a competing EIP.
 
-If you are interested in assuming ownership of a EIP, send a message asking to take over, addressed to both the original author and the EIP editor. If the original author doesn't respond to email in a timely manner, the EIP editor will make a unilateral decision (it's not like such decisions can't be reversed :).
+If you are interested in assuming ownership of an EIP, send a message asking to take over, addressed to both the original author and the EIP editor. If the original author doesn't respond to email in a timely manner, the EIP editor will make a unilateral decision (it's not like such decisions can't be reversed :).
 
 EIP Editors
 -----------
@@ -203,7 +203,7 @@ If the EIP isn't ready, the editor will send it back to the author for revision,
 
 Once the EIP is ready for the repository, the EIP editor will:
 
--   Assign a EIP number (generally the PR number or, if preferred by the author, the Issue # if there was discussion in the Issues section of this repository about this EIP)
+-   Assign an EIP number (generally the PR number or, if preferred by the author, the Issue # if there was discussion in the Issues section of this repository about this EIP)
 
 
 

From a0bd2416199dd1b6e3d848977fd4364f4c21b698 Mon Sep 17 00:00:00 2001
From: cdetrio 
Date: Wed, 3 May 2017 11:12:34 -0400
Subject: [PATCH 0108/1085] copy EIP-155 from issues

---
 EIPS/eip-155.md | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)
 create mode 100644 EIPS/eip-155.md

diff --git a/EIPS/eip-155.md b/EIPS/eip-155.md
new file mode 100644
index 0000000000000..e7be055ef85de
--- /dev/null
+++ b/EIPS/eip-155.md
@@ -0,0 +1,38 @@
+EDITOR NOTE: below is a copy of the EIP 155 https://github.com/ethereum/EIPs/issues/155#issue-183002027 raw text fetched on 2017-05-02.
+
+### Parameters
+- `FORK_BLKNUM`: TBA
+- `CHAIN_ID`: 1
+### Specification
+
+If `block.number >= FORK_BLKNUM` and `v = CHAIN_ID * 2 + 35` or `v = CHAIN_ID * 2 + 36`, then when computing the hash of a transaction for purposes of signing or recovering, instead of hashing only the first six elements (ie. nonce, gasprice, startgas, to, value, data), hash nine elements, with `v` replaced by `CHAIN_ID`, `r = 0` and `s = 0`. The currently existing signature scheme using `v = 27` and `v = 28` remains valid and continues to operate under the same rules as it does now.
+### Example
+
+Consider a transaction with `nonce = 9`, `gasprice = 20 * 10**9`, `startgas = 21000`, `to = 0x3535353535353535353535353535353535353535`, `value = 10**18`, `data=''` (empty).
+
+The "signing data" becomes:
+
+```
+0xec098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a764000080018080
+```
+
+The "signing hash" becomes:
+
+```
+0x2691916f9e6e5b304f135496c08f632040f02d78e36ae5bbbb38f919730c8fa0
+```
+
+If the transaction is signed with the private key `0x4646464646464646464646464646464646464646464646464646464646464646`, then the v,r,s values become:
+
+```
+(37, 11298168949998536842419725113857172427648002808790045841403298480749678639159, 26113561835810707062310182368620287328545641189938585203131842552044123671646)
+```
+
+Notice the use of 37 instead of 27. The signed tx would become:
+
+```
+0xf86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008025a028ef61340bd939bc2195fe537567866003e1a15d3c71ff63e1590620aa636276a067cbe9d8997f761aecb703304b3800ccf555c9f3dc64214b297fb1966a3b6d83
+```
+### Rationale
+
+This would provide a way to send transactions that work on ethereum without working on ETC or the Morden testnet. ETC is encouraged to adopt this EIP but replacing `CHAIN_ID` with a different value, and all future testnets, consortium chains and alt-etherea are encouraged to adopt this EIP replacing `CHAIN_ID` with a unique value.

From 2a814ea28163bd155136a06fbe95a4652330a7e3 Mon Sep 17 00:00:00 2001
From: cdetrio 
Date: Wed, 3 May 2017 11:15:14 -0400
Subject: [PATCH 0109/1085] add preamble

---
 EIPS/eip-155.md | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/EIPS/eip-155.md b/EIPS/eip-155.md
index e7be055ef85de..139508c99e60b 100644
--- a/EIPS/eip-155.md
+++ b/EIPS/eip-155.md
@@ -1,4 +1,13 @@
-EDITOR NOTE: below is a copy of the EIP 155 https://github.com/ethereum/EIPs/issues/155#issue-183002027 raw text fetched on 2017-05-02.
+## Preamble
+```
+EIP: 155
+Title: Simple replay attack protection
+Author: Vitalik Buterin
+Type: Standard Track
+Category: Core
+Status: Final
+Created: 2016-10-14
+```
 
 ### Parameters
 - `FORK_BLKNUM`: TBA

From 581ce45afc5a10e218e75cff4bb2dc21997d121b Mon Sep 17 00:00:00 2001
From: cdetrio 
Date: Thu, 4 May 2017 12:28:26 -0400
Subject: [PATCH 0110/1085] correct example values

---
 EIPS/eip-155.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/EIPS/eip-155.md b/EIPS/eip-155.md
index 139508c99e60b..01c8615f753eb 100644
--- a/EIPS/eip-155.md
+++ b/EIPS/eip-155.md
@@ -28,13 +28,13 @@ The "signing data" becomes:
 The "signing hash" becomes:
 
 ```
-0x2691916f9e6e5b304f135496c08f632040f02d78e36ae5bbbb38f919730c8fa0
+0xdaf5a779ae972f972197303d7b574746c7ef83eadac0f2791ad23db92e4c8e53
 ```
 
 If the transaction is signed with the private key `0x4646464646464646464646464646464646464646464646464646464646464646`, then the v,r,s values become:
 
 ```
-(37, 11298168949998536842419725113857172427648002808790045841403298480749678639159, 26113561835810707062310182368620287328545641189938585203131842552044123671646)
+(37, 18515461264373351373200002665853028612451056578545711640558177340181847433846, 46948507304638947509940763649030358759909902576025900602547168820602576006531)
 ```
 
 Notice the use of 37 instead of 27. The signed tx would become:

From 1dee19d34b6883372b15af9e71813882385fdbda Mon Sep 17 00:00:00 2001
From: cdetrio 
Date: Thu, 4 May 2017 12:54:24 -0400
Subject: [PATCH 0111/1085] add table of chain id's

---
 EIPS/eip-155.md | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/EIPS/eip-155.md b/EIPS/eip-155.md
index 01c8615f753eb..869a842e16004 100644
--- a/EIPS/eip-155.md
+++ b/EIPS/eip-155.md
@@ -45,3 +45,19 @@ Notice the use of 37 instead of 27. The signed tx would become:
 ### Rationale
 
 This would provide a way to send transactions that work on ethereum without working on ETC or the Morden testnet. ETC is encouraged to adopt this EIP but replacing `CHAIN_ID` with a different value, and all future testnets, consortium chains and alt-etherea are encouraged to adopt this EIP replacing `CHAIN_ID` with a unique value.
+
+
+### List of Chain ID's:
+
+| `CHAIN_ID`     | Chain(s)                                   |
+| ---------------| -------------------------------------------|
+| 1              | Ethereum mainnet                           |
+| 2              | Morden (disused), Expanse mainnet          |
+| 3              | Ropsten                                    |
+| 4              | Rinkeby                                    |
+| 30             | Rootstock mainnet                          |
+| 31             | Rootstock testnet                          |
+| 42             | Kovan                                      |
+| 61             | Ethereum Classic mainnet                   |
+| 62             | Ethereum Classic testnet                   |
+| 1337           | Geth private chains (default)              |

From b095d4dc01365138e37a5282d157849a18061c79 Mon Sep 17 00:00:00 2001
From: Greg Colvin 
Date: Fri, 5 May 2017 20:52:53 -0400
Subject: [PATCH 0112/1085] Correct formula for division.

---
 EIPS/eip-EIPS/eip-616.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/EIPS/eip-EIPS/eip-616.md b/EIPS/eip-EIPS/eip-616.md
index 91f196a55615e..46de32e3e9ef9 100644
--- a/EIPS/eip-EIPS/eip-616.md
+++ b/EIPS/eip-EIPS/eip-616.md
@@ -1,5 +1,5 @@
 ```
-EIP: 
+EIP: 616
 Title: SIMD Operations for the EVM
 Author: Greg Colvin, greg@colvin.org
 Type: Standard Track
@@ -125,7 +125,7 @@ operation | cycles | N = 2 | N = 4 | N = 8
 add | 10 _N_ + 6 | 26 | 46 | 86
 subtract | 12 _N_ + 3 |27 | 51 | 99
 multiply | 28 _N_**2 + 11 _N_ + 3 | 137 | 495 |1883
-divide | 30 _N_**2 + 119 _N_ + 111 | 469 | 1067 | 2983
+divide | 30 (_N_**2)/2 + 119 _N_ + 111 | 409 | 827 | 2023
 
 The remaining operations are of about the same complexity as addition and subtraction, or less. Given that JUMPDEST is a no-op, and is assigned a gas price of 1, this can be taken as the overhead of the interpreter.  All of the arithmetic operations are assigned the same gas price of 5, for a remaining runtime of 4.  The interpreter loop itself takes about 6 to 8 C instructions, so ADD and SUB are reasonably priced, but MUL is some 5 to 21 times slower than ADD or SUB, and DIV is some 18 to 35 times slower, so they are clearly mispriced.
 

From d31597eaa1134ba8b28e3acf2137c55c002227f2 Mon Sep 17 00:00:00 2001
From: Greg Colvin 
Date: Sat, 6 May 2017 14:55:51 -0400
Subject: [PATCH 0113/1085] Update eip-616.md

---
 EIPS/eip-EIPS/eip-616.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/EIPS/eip-EIPS/eip-616.md b/EIPS/eip-EIPS/eip-616.md
index 46de32e3e9ef9..6ed6755d754ae 100644
--- a/EIPS/eip-EIPS/eip-616.md
+++ b/EIPS/eip-EIPS/eip-616.md
@@ -125,7 +125,7 @@ operation | cycles | N = 2 | N = 4 | N = 8
 add | 10 _N_ + 6 | 26 | 46 | 86
 subtract | 12 _N_ + 3 |27 | 51 | 99
 multiply | 28 _N_**2 + 11 _N_ + 3 | 137 | 495 |1883
-divide | 30 (_N_**2)/2 + 119 _N_ + 111 | 409 | 827 | 2023
+divide | 15 _N_**2 + 119 _N_ + 111 | 409 | 827 | 2023
 
 The remaining operations are of about the same complexity as addition and subtraction, or less. Given that JUMPDEST is a no-op, and is assigned a gas price of 1, this can be taken as the overhead of the interpreter.  All of the arithmetic operations are assigned the same gas price of 5, for a remaining runtime of 4.  The interpreter loop itself takes about 6 to 8 C instructions, so ADD and SUB are reasonably priced, but MUL is some 5 to 21 times slower than ADD or SUB, and DIV is some 18 to 35 times slower, so they are clearly mispriced.
 

From 07b0caea587ec4323b639d0d0556b94352f246d5 Mon Sep 17 00:00:00 2001
From: Greg Colvin 
Date: Sat, 6 May 2017 15:09:14 -0400
Subject: [PATCH 0114/1085] Update eip-616.md

---
 EIPS/eip-EIPS/eip-616.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/EIPS/eip-EIPS/eip-616.md b/EIPS/eip-EIPS/eip-616.md
index 6ed6755d754ae..df54888a51607 100644
--- a/EIPS/eip-EIPS/eip-616.md
+++ b/EIPS/eip-EIPS/eip-616.md
@@ -127,7 +127,7 @@ subtract | 12 _N_ + 3 |27 | 51 | 99
 multiply | 28 _N_**2 + 11 _N_ + 3 | 137 | 495 |1883
 divide | 15 _N_**2 + 119 _N_ + 111 | 409 | 827 | 2023
 
-The remaining operations are of about the same complexity as addition and subtraction, or less. Given that JUMPDEST is a no-op, and is assigned a gas price of 1, this can be taken as the overhead of the interpreter.  All of the arithmetic operations are assigned the same gas price of 5, for a remaining runtime of 4.  The interpreter loop itself takes about 6 to 8 C instructions, so ADD and SUB are reasonably priced, but MUL is some 5 to 21 times slower than ADD or SUB, and DIV is some 18 to 35 times slower, so they are clearly mispriced.
+The remaining operations are of about the same complexity as addition and subtraction, or less. Given that JUMPDEST is a no-op, and is assigned a gas price of 1, this can be taken as the overhead of the interpreter.  All of the arithmetic operations are assigned the same gas price of 5, for a remaining runtime of 4.  The interpreter loop itself takes about 6 to 8 C instructions, so ADD and SUB are reasonably priced, but MUL is some 5 to 21 times slower than ADD or SUB, and DIV is some 15 to 23 times slower, so they are clearly mispriced.
 
 By comparison, on most [Intel](https://software.intel.com/sites/landingpage/IntrinsicsGuide) and [ARM](https://developer.arm.com/docs/100166_0001/latest/programmers-model/instruction-set-summary/table-of-processor-instructions) SIMD units instructions take approximately the following cycle counts, independent of register width.
 

From 1e27d718bfd0a8d425cca3902ac47b1abb281c26 Mon Sep 17 00:00:00 2001
From: Vlad 
Date: Mon, 8 May 2017 19:03:04 +0200
Subject: [PATCH 0115/1085] whisper link fixed

---
 EIPS/eip-1.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md
index 1299f4238d565..fade7c120db5b 100644
--- a/EIPS/eip-1.md
+++ b/EIPS/eip-1.md
@@ -237,7 +237,7 @@ February 1, 2016: EIP 1 has added editors, made draft improvements to process, a
   [devp2p]: https://github.com/ethereum/wiki/wiki/%C3%90%CE%9EVp2p-Wire-Protocol
   [EIP8]: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-8.md
   [Light Ethereum Subprotocol]: https://github.com/ethereum/wiki/wiki/Light-client-protocol
-  [whisper]: https://gist.github.com/gluk256/4654922ca45eb9d0846d941d7ca326f4
+  [whisper]: https://github.com/ethereum/go-ethereum/wiki/Whisper-Overview
   [swarm]: https://github.com/ethereum/go-ethereum/pull/2959
   [API/RPC]: https://github.com/ethereum/wiki/wiki/JSON-RPC
   [EIP59]: https://github.com/ethereum/EIPs/issues/59

From 0dd5a4114c35c5e3c4964d3fd2117f90fe1b46b7 Mon Sep 17 00:00:00 2001
From: maurelian 
Date: Thu, 11 May 2017 06:44:58 -0400
Subject: [PATCH 0116/1085] Transfer from issues #162 as is

---
 EIPS/eip-ens-initial-registrar.md | 180 ++++++++++++++++++++++++++++++
 1 file changed, 180 insertions(+)
 create mode 100644 EIPS/eip-ens-initial-registrar.md

diff --git a/EIPS/eip-ens-initial-registrar.md b/EIPS/eip-ens-initial-registrar.md
new file mode 100644
index 0000000000000..a923d876e99ad
--- /dev/null
+++ b/EIPS/eip-ens-initial-registrar.md
@@ -0,0 +1,180 @@
+**Some of the parameters and mechanisms in this document are outdated with respect to the version deployed on the main net. Until this notice is removed or updated, please refer to [ReadTheDocs](http://docs.ens.domains/en/latest/userguide.html?highlight=auction#registering-a-name-with-the-auction-registrar) or natspec comments in the [deployed code](https://github.com/ethereum/ens/blob/mainnet/contracts/HashRegistrarSimplified.sol).**
+
+```
+EIP: Draft
+Title: Initial ENS Hash Registrar
+Author: J. Maurelian and Nick Johnson
+Status: Draft
+Type: Informational
+Created: 2016-10-25
+```
+## Contents
+- Abstract
+- Motivations
+- Specification
+  - Initial restrictions
+  - Name format for hash registration
+  - Auctioning names
+  - Deeds
+  - Deployment and Upgrade process
+  - Registrar Interface
+- Rationale
+  - Not committing to a permanent registrar at the outset
+  - Valid names >= 7 characters
+  - Restricting TLD to `.eth`
+  - Holding ether as collateral
+- Prior work
+
+
+## Abstract
+
+This ERC describes the implementation of a registrar contract to govern the allocation of names in the Ethereum Name Service (ENS). For background, refer to [EIP 137](https://github.com/ethereum/EIPs/issues/137).
+
+> Registrars are responsible for allocating domain names to users of the system, and are the only entities capable of updating the ENS; the owner of a node in the ENS registry is its registrar. Registrars may be contracts or externally owned accounts, though it is expected that the root and top-level registrars, at a minimum, will be implemented as contracts.
+>
+> \- EIP 137
+
+A well designed and governed registrar is essential to the success of the ENS described in EIP 137, but is described separately in this document as it is external to the core ENS protocol.
+
+In order to maximize utility and adoption of a new namespace, the registrar should mitigate speculation and "name squatting", however the best approach for mitigation is unclear. Thus an "initial" registrar is proposed, which implements a simple approach to name allocation. During the initial period, the available namespace will be significantly restricted to the `.eth` top level domain, and subdomain shorter than 7 characters in length disallowed. This specification largely describes @alexvandesande's [hash registrar implementation](https://github.com/Arachnid/ens/blob/master/HashRegistrarSimplified.sol) in order to facilitate discussion. His [design mockups](https://projects.invisionapp.com/share/FE93G2K3Y#/screens/200024092) are also very helpful for understanding the flow
+
+This Initial Registrar contract will be replaced with a permanent registrar contract. The Permanent Registrar will increase the available namespace, and incorporate lessons learned from the performance of the Initial Registrar. This upgrade is expected to take place within approximately 2 years of initial deployment.
+## Motivations
+
+The following factors should be considered in order to optimize for adoption of the ENS, and good governance of the Initial Registrar's namespace.
+
+**Upgradability:** The Initial Registrar should be safely upgradeable, so that knowledge gained during its deployment can be used to replace it with an improved and permanent registrar.
+
+**Effective allocation:** Newly released namespaces often create a land grab situation, resulting in many potentially valuable names being purchased but unused, with the hope of re-selling at a profit. This reduces the availability of the most useful names, in turn decreasing the utility of the name service to end users.
+
+Achieving an effective allocation may or may not require human intervention for dispute resolution and other forms of curation. The Initial Registrar should not aim to create to most effective possible allocation, but instead limit the cost of misallocation in the long term.
+
+**Security:** The registrar will hold a balance of ether without an explicit limit. It must be designed securely.
+
+**Simplicity:** The ENS specification itself emphasizes a separation of concerns, allowing the most essential element, the registry to be as simple as possible. The interim registrar in turn should be as simple as possible while still meeting its other design goals.
+
+**Adoption:** Successful standards become more successful due to network effects. The registrar should consider what strategies will encourage the adoption of the ENS in general, and the namespace it controls in particular.
+## Specification
+### Initial restrictions
+
+The Initial Registrar is expected to be in service for approximately two years, prior to upgrading. This should be sufficient time to learn, observe, and design an updated system.
+
+During the initial two year period, the available name space will be restricted to the `.eth` TLD.
+
+This restriction is not implemented by the registrar, but rather by the owner of the ENS root node who should not assign any nodes other than `.eth` to the Initial Registrar. The ENS's root node should be controlled by multiple parties using a multisig contract.
+
+The Initial Registrar will also prohibit registration of names shorter than the `minNameLength` parameter. The value of `minNameLength` will be 7 initially. This value will be reducible by a call from owner of the ENS's root node.
+### Name format for hash registration
+
+Names submitted to the initial registrar must be hashed using Ethereum's sha3 function. Note that the hashes submitted to the registrar are the hash of the subdomain label being registered, not the namehash as defined in EIP 137.
+
+For example, in order to register `abcdefg.eth`, one should submit `sha3('abcdefg')`, not `sha3('abcdefg', sha3('eth', 0))`.
+### Auctioning names
+
+The registrar will allocate the available names through a Vickrey auction:
+
+> A Vickrey auction is a type of sealed-bid auction. Bidders submit written bids without knowing the bid of the other people in the auction. The highest bidder wins but the price paid is the second-highest bid. This type of auction... gives bidders an incentive to bid their true value.
+>
+> \- [Vickrey Auction, Wikipedia](https://en.wikipedia.org/wiki/Vickrey_auction)
+
+The timeline of the auction will be implemented as follows:
+1. The hash of the desired name is submitted to the Initial Registrar, and bidding is opened on the hash.
+2. The auction will last 5 days, except for auctions started during the first 3 weeks after deployment of the Initial Registrar, which will last until the end of the 4th week.
+3. Bidders submit a payment of ether, along with sealed bids as a hash of `sha3(bytes32 hash, address owner, uint value, bytes32 salt)`. The transaction can obfuscate the true bid value by sending a greater amount of ether.
+4. All bids must be received before the start of the final 48 hours of the auction, which is the reveal period. During this time, bidders must submit the true parameters of their sealed bid. As bids are revealed, ether payments are returned according to the schedule of "refund ratios" outlined in the table below.
+5. After the 48 hour reveal period has finished, the Initial Registrar's `finalizeAuction` function can be called, which then calls the ENS's `setSubnodeOwner` function, recording the winning bidder's address as the owner of the hash of the name.
+
+### Deeds
+
+The Initial Registrar contract does not hold a balance itself. All ether sent to the Registrar will be held in separate deed contracts. Deeds are initially associated with a bidder and their sealed bid. After an auction is completed and a hash is registered, the deed for the winning bid is held in exchange for ownership of the hash.
+
+After 1 year of registration, the owner of a hash may choose to relinquish ownership and have the value of the deed returned to them. A deed for an owned hash may also be transferred to another account by its owner.
+
+Deeds for non-winning bid can be closed by various methods, at which time any ether held will either be returned to the bidder, burnt, or sent to someone else as a reward for actions which help the registrar.
+
+The following table outlines what portion of the balance held in a deed contract will be returned upon closure, and to whom. The remaining balance will be burnt.
+
+| Reason for Deed closure | Refund Recipient | Refund Percentage |
+| --- | --- | --- |
+| A valid non-winning bid is unsealed. | Bidder | 99.9% |
+| An invalid bid is unsealed. | Bidder | 1% |
+| A sealed bid is cancelled. 1 | Canceler | 0.5% |
+| An registered hash is reported as invalid. 2 | Reporter | 10% |
+##### Notes:
+1. Bids which remain sealed for at least 12 weeks may be cancelled by anyone to collect a small reward.
+2. Since names are hashed before auctioning and registration, the Initial Registrar is unable to enforce character length restrictions independently. A reward is therefore provided for reporting invalid names.
+### Deployment and Upgrade process
+
+The Initial Registrar requires the ENS's address as a contructor, and should be deployed after the ENS. The multisig account owning the root node in the ENS should then set the Initial Registrar's address as owner of the `eth` node.
+
+The Initial Registrar is expected to be replaced by a Permanent Registrar approximately 2 years after deployment. The following process should be used for the upgrade:
+1. The Permanent Registrar contract will be deployed.
+2. The multisig account owning the root node in the ENS will assign ownership of the `.eth` node to the Permanent Registrar.
+3. Owners of hashes in the Initial Registrar will be responsible for registering their deeds to the Permanent Registrar. A couple options are considered here:
+   1. Require owners to transfer their ownership prior to a cutoff date in order to maintain ownership and/or continue name resolution services.
+   2. Have the Permanent Registrar query the Initial Registrar for ownership if it is lacking an entry.
+
+### Planned deactivation
+
+In order to limit dependence on the Initial Registrar, new auctions will stop after 4 years, and all ether held in deeds after 8 years will become unreachable.
+
+### Registrar Interface
+
+`function startAuction(bytes32 _hash);`
+- Starts an auction for an available hash. If the hash is already allocated, or there is an ongoing auction,  `startAuction` will throw.
+
+`function startAuctions(bytes32[] _hashes);`
+- Starts multiple auctions on an array of hashes. This enables someone to open up an auction for a number of dummy hashes when they are only really interested in bidding for one. This will increase the cost for an attacker to simply bid blindly on all new auctions. Dummy auctions that are open but not bid on are closed after a week.
+
+`function shaBid(bytes32 hash, address owner, uint value, bytes32 salt) constant returns (bytes32 sealedBid);`
+- Takes the parameters of a bid, and returns the sealedBid hash value required to participate in the bidding for an auction. This obfuscates the parameters in order to mimic the mechanics of placing a bid in an envelope.
+
+`function newBid(bytes32 sealedBid);`
+- Bids are sent by sending a message to the main contract with a sealedBid hash and an amount of ether. The hash contains information about the bid, including the bidded name hash, the bid value, and a random salt. Bids are not tied to any one auction until they are revealed. The value of the bid itself can be masqueraded by sending more than the value of your actual bid. This is followed by a 48h reveal period. Bids revealed after this period will be burned and the ether unrecoverable. Since this is an auction, it is expected that most public hashes, like known domains and common dictionary  words, will have multiple bidders pushing the price up.
+
+`function unsealBid(bytes32 _hash, address _owner, uint _value, bytes32 _salt);`
+- Once the bidding period is completed, there is a reveal period during with the properties of a bid are submitted to reveal them. The registrar hashes these properties using the `shaBid()` function above to verify that they match a pre-existing sealed bid. If the unsealedBid is the new best bid, the old best bid is returned to its bidder.
+
+`function cancelBid(bytes32 seal);`
+- Cancels an unrevealed bid, forfeiting  the funds.
+
+`function finalizeAuction(bytes32 _hash);`
+
+After the registration date has passed, this function can be called to finalize the auction, which then calls the ENS function `setSubnodeOwner()`  updating the ENS record to set the winning bidder as owner of the node.
+
+`function transfer(bytes32 _hash, address newOwner);`
+- Update the owner of the ENS node corresponding to the submitted hash to a new owner. This function must be callable only by the current owner.
+
+`function releaseDeed(bytes32 _hash);`
+- After some time, the owner can release the property and get their ether back.
+
+`function invalidateName(string unhashedName);`
+- Since registration is done on the hash of a name, the registrar itself cannot validate names. This function can be used to report a name which is 6 characters long or less. If it has been registered, the submitter will earn 10% of the deed value. We are purposefully handicapping the simplified registrar as a way to force it into being restructured in a few years.
+
+`function transferRegistrars(bytes32 _hash) onlyOwner(_hash);`
+- Used during the upgrade process to a permanent registrar. If this registrar is no longer the owner of the its root node in the ENS, this function will transfers the deed to the current owner, which should be a new registrar. This function throws if this registrar still owns its root node.
+## Rationale
+### Starting with a temporary registrar
+
+Anticipating and designing for all the potential issues of name allocation names is unlikely to succeed. This approach chooses not to be concerned with getting it perfect, but allows us to observe and learn with training wheels on, and implement improvements before expanding the available namespace to shorter names or another TLD.
+### Valid names >= 7 characters
+
+Preserving the shortest, and often most valuable, domain names for the upgraded registrar provides the opportunity to implement processes for dispute resolution (assuming they are found to be necessary).
+### Restricting TLD to `.eth`
+
+Choosing a single TLD helps to maximize network effects by focusing on one namespace.
+
+A three letter TLD is a pattern made familiar by it's common usage in internet domain names. This familiarity significantly increases the potential of the ENS to be integrated into pre-existing DNS systems, and reserved as a [special-use domain name](http://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml#special-use-domain).  A recent precedent for this is the [reservation of the `.onion` domain](https://tools.ietf.org/html/rfc7686).
+### Holding ether as collateral
+
+This approach is simpler than the familiar model of requiring owners to make recurring payments to retain ownership of a domain name. It also makes the initial registrar a revenue neutral service, and creates a new business model on Ethereum, by enabling owners to rent names as a service.
+## Prior work
+
+This document borrows heavily from several sources:
+- [EIP 137](https://github.com/ethereum/EIPs/issues/137) outlines the initial implementation of the Registry Contract (ENS.sol) and associated Resolver contracts.
+- [ERC 26](https://github.com/ethereum/EIPs/issues/26) was the first ERC to propose a name service at the contract layer
+- @alexvandesande's current implementation of the [HashRegistrar](https://github.com/Arachnid/ens/blob/master/HashRegistrarSimplified.sol)
+### Edits:
+- 2016-10-26 Added link Alex's design in abstract
+- 2016-11-01 change 'Planned deactivation' to h3'
+- 2017-03-13 Update timelines for bidding and reveal periods

From e784c0f050f574327eeea28e918c9426c1b3c5d2 Mon Sep 17 00:00:00 2001
From: maurelian 
Date: Thu, 11 May 2017 10:32:01 -0400
Subject: [PATCH 0117/1085] Updated to describe the main net deployment

---
 EIPS/eip-ens-initial-registrar.md | 113 +++++++++++++++++++++++-------
 1 file changed, 88 insertions(+), 25 deletions(-)

diff --git a/EIPS/eip-ens-initial-registrar.md b/EIPS/eip-ens-initial-registrar.md
index a923d876e99ad..0c7fb513f0e12 100644
--- a/EIPS/eip-ens-initial-registrar.md
+++ b/EIPS/eip-ens-initial-registrar.md
@@ -1,13 +1,12 @@
-**Some of the parameters and mechanisms in this document are outdated with respect to the version deployed on the main net. Until this notice is removed or updated, please refer to [ReadTheDocs](http://docs.ens.domains/en/latest/userguide.html?highlight=auction#registering-a-name-with-the-auction-registrar) or natspec comments in the [deployed code](https://github.com/ethereum/ens/blob/mainnet/contracts/HashRegistrarSimplified.sol).**
-
 ```
 EIP: Draft
 Title: Initial ENS Hash Registrar
-Author: J. Maurelian and Nick Johnson
+Author: Maurelian and Nick Johnson
 Status: Draft
 Type: Informational
 Created: 2016-10-25
 ```
+
 ## Contents
 - Abstract
 - Motivations
@@ -26,9 +25,12 @@ Created: 2016-10-25
 - Prior work
 
 
+
 ## Abstract
 
-This ERC describes the implementation of a registrar contract to govern the allocation of names in the Ethereum Name Service (ENS). For background, refer to [EIP 137](https://github.com/ethereum/EIPs/issues/137).
+This ERC describes the implementation, as deployed to the main ethereum network on 2017-05-04, of a registrar contract to govern the allocation of names in the Ethereum Name Service (ENS). The corresponding source code is [here](https://github.com/ethereum/ens/blob/mainnet/contracts/HashRegistrarSimplified.sol).
+
+For more background, refer to [EIP 137](https://github.com/ethereum/EIPs/issues/137).
 
 > Registrars are responsible for allocating domain names to users of the system, and are the only entities capable of updating the ENS; the owner of a node in the ENS registry is its registrar. Registrars may be contracts or externally owned accounts, though it is expected that the root and top-level registrars, at a minimum, will be implemented as contracts.
 >
@@ -36,9 +38,10 @@ This ERC describes the implementation of a registrar contract to govern the allo
 
 A well designed and governed registrar is essential to the success of the ENS described in EIP 137, but is described separately in this document as it is external to the core ENS protocol.
 
-In order to maximize utility and adoption of a new namespace, the registrar should mitigate speculation and "name squatting", however the best approach for mitigation is unclear. Thus an "initial" registrar is proposed, which implements a simple approach to name allocation. During the initial period, the available namespace will be significantly restricted to the `.eth` top level domain, and subdomain shorter than 7 characters in length disallowed. This specification largely describes @alexvandesande's [hash registrar implementation](https://github.com/Arachnid/ens/blob/master/HashRegistrarSimplified.sol) in order to facilitate discussion. His [design mockups](https://projects.invisionapp.com/share/FE93G2K3Y#/screens/200024092) are also very helpful for understanding the flow
+In order to maximize utility and adoption of a new namespace, the registrar should mitigate speculation and "name squatting", however the best approach for mitigation is unclear. Thus an "initial" registrar is proposed, which implements a simple approach to name allocation. During the initial period, the available namespace will be significantly restricted to the `.eth` top level domain, and subdomain shorter than 7 characters in length disallowed. This specification largely describes @alexvandesande and @arachnid's [hash registrar implementation](https://github.com/Arachnid/ens/blob/master/HashRegistrarSimplified.sol) in order to facilitate discussion.
+
+The intent is to replace the Initial Registrar contract with a permanent registrar contract. The Permanent Registrar will increase the available namespace, and incorporate lessons learned from the performance of the Initial Registrar. This upgrade is expected to take place within approximately 2 years of initial deployment.
 
-This Initial Registrar contract will be replaced with a permanent registrar contract. The Permanent Registrar will increase the available namespace, and incorporate lessons learned from the performance of the Initial Registrar. This upgrade is expected to take place within approximately 2 years of initial deployment.
 ## Motivations
 
 The following factors should be considered in order to optimize for adoption of the ENS, and good governance of the Initial Registrar's namespace.
@@ -54,21 +57,25 @@ Achieving an effective allocation may or may not require human intervention for
 **Simplicity:** The ENS specification itself emphasizes a separation of concerns, allowing the most essential element, the registry to be as simple as possible. The interim registrar in turn should be as simple as possible while still meeting its other design goals.
 
 **Adoption:** Successful standards become more successful due to network effects. The registrar should consider what strategies will encourage the adoption of the ENS in general, and the namespace it controls in particular.
+
 ## Specification
+
 ### Initial restrictions
 
 The Initial Registrar is expected to be in service for approximately two years, prior to upgrading. This should be sufficient time to learn, observe, and design an updated system.
 
 During the initial two year period, the available name space will be restricted to the `.eth` TLD.
 
-This restriction is not implemented by the registrar, but rather by the owner of the ENS root node who should not assign any nodes other than `.eth` to the Initial Registrar. The ENS's root node should be controlled by multiple parties using a multisig contract.
+This restriction is enforced by the owner of the ENS root node who should not assign any nodes other than `.eth` to the Initial Registrar. The ENS's root node should be controlled by multiple parties using a multisig contract.
+
+The Initial Registrar will also prohibit registration of names 6 characters or less in length.
 
-The Initial Registrar will also prohibit registration of names shorter than the `minNameLength` parameter. The value of `minNameLength` will be 7 initially. This value will be reducible by a call from owner of the ENS's root node.
 ### Name format for hash registration
 
 Names submitted to the initial registrar must be hashed using Ethereum's sha3 function. Note that the hashes submitted to the registrar are the hash of the subdomain label being registered, not the namehash as defined in EIP 137.
 
 For example, in order to register `abcdefg.eth`, one should submit `sha3('abcdefg')`, not `sha3('abcdefg', sha3('eth', 0))`.
+
 ### Auctioning names
 
 The registrar will allocate the available names through a Vickrey auction:
@@ -77,32 +84,53 @@ The registrar will allocate the available names through a Vickrey auction:
 >
 > \- [Vickrey Auction, Wikipedia](https://en.wikipedia.org/wiki/Vickrey_auction)
 
-The timeline of the auction will be implemented as follows:
-1. The hash of the desired name is submitted to the Initial Registrar, and bidding is opened on the hash.
-2. The auction will last 5 days, except for auctions started during the first 3 weeks after deployment of the Initial Registrar, which will last until the end of the 4th week.
-3. Bidders submit a payment of ether, along with sealed bids as a hash of `sha3(bytes32 hash, address owner, uint value, bytes32 salt)`. The transaction can obfuscate the true bid value by sending a greater amount of ether.
-4. All bids must be received before the start of the final 48 hours of the auction, which is the reveal period. During this time, bidders must submit the true parameters of their sealed bid. As bids are revealed, ether payments are returned according to the schedule of "refund ratios" outlined in the table below.
-5. After the 48 hour reveal period has finished, the Initial Registrar's `finalizeAuction` function can be called, which then calls the ENS's `setSubnodeOwner` function, recording the winning bidder's address as the owner of the hash of the name.
+The auction lifecycle of a name has 5 possible states, or Modes.
+
+1. **Not-yet-available:** The majority of names will be initially unavailable for auction, and will become available some time during the 8 weeks after launch.
+2. **Open:** The earliest availability for a name is determined by the most significant byte of its sha3 hash. `0x00` would become available immediately, `0xFF` would become available after 8 weeks, and the availability of other names is distributed accordingly. Once a name is available, it is possible to start an auction on it.
+3. **Auction:** Once the auction for a name has begun, there is a 72 hour bidding period. Bidders must submit a payment of ether, along with sealed bids as a hash of `sha3(bytes32 hash, address owner, uint value, bytes32 salt)`. The bidder may obfuscate the true bid value by sending a greater amount of ether.
+4. **Reveal:** After the bidding period, a 48 hour reveal period commences. During this time, bidders must reveal the true parameters of their sealed bid. As bids are revealed, ether payments are returned according to the schedule of "refund ratios" outlined in the table below. If no bids are revealed, the name will return to the Open state.
+5. **Owned:** After the reveal period has finished, the winning bidder must submit a transaction to finalize the auction, which then calls the ENS's `setSubnodeOwner` function, recording the winning bidder's address as the owner of the hash of the name.
+
+
+
 
 ### Deeds
 
-The Initial Registrar contract does not hold a balance itself. All ether sent to the Registrar will be held in separate deed contracts. Deeds are initially associated with a bidder and their sealed bid. After an auction is completed and a hash is registered, the deed for the winning bid is held in exchange for ownership of the hash.
+The Initial Registrar contract does not hold a balance itself. All ether sent to the Registrar will be held in a separate `Deed` contracts. A deed contract is first created and funded when a sealed bid is submitted. After an auction is completed and a hash is registered, the deed for the winning bid is held in exchange for ownership of the hash. Non-winning bids are refunded.
 
-After 1 year of registration, the owner of a hash may choose to relinquish ownership and have the value of the deed returned to them. A deed for an owned hash may also be transferred to another account by its owner.
+A deed for an owned name may be transferred to another account by its owner, thus transferring ownership and control of the name.
 
-Deeds for non-winning bid can be closed by various methods, at which time any ether held will either be returned to the bidder, burnt, or sent to someone else as a reward for actions which help the registrar.
+After 1 year of registration, the owner of a hash may choose to relinquish ownership and have the value of the deed returned to them.
+
+Deeds for non-winning bids can be closed by various methods, at which time any ether held will either be returned to the bidder, burnt, or sent to someone else as a reward for actions which help the registrar.
 
 The following table outlines what portion of the balance held in a deed contract will be returned upon closure, and to whom. The remaining balance will be burnt.
 
+#### Refund schedule
+
 | Reason for Deed closure | Refund Recipient | Refund Percentage |
 | --- | --- | --- |
-| A valid non-winning bid is unsealed. | Bidder | 99.9% |
-| An invalid bid is unsealed. | Bidder | 1% |
-| A sealed bid is cancelled. 1 | Canceler | 0.5% |
-| An registered hash is reported as invalid. 2 | Reporter | 10% |
+| A valid non-winning bid is revealed. | Bidder | 99.5% |
+| A bid submitted after the auction period is revealed. | Bidder | 99.5% |
+| An otherwise valid bid is revealed on an owned name. 1 | Bidder | %0.5 |
+| An expired sealed bid is cancelled. 2 | Canceler | 0.5% |
+| A registered hash is reported as invalid. 3 | Reporter | 50% |
+| A registered hash is reported as invalid. 3 | Owner | 50% |
+
 ##### Notes:
-1. Bids which remain sealed for at least 12 weeks may be cancelled by anyone to collect a small reward.
+
+1. This is to prevent an extortion attack on the current highest bidder, by threatening to reveal a new second highest bid. This forces all bids to be revealed.
+2. A bid which remains sealed after more than 2 weeks and 5 days may be cancelled by anyone to collect a small reward.
 2. Since names are hashed before auctioning and registration, the Initial Registrar is unable to enforce character length restrictions independently. A reward is therefore provided for reporting invalid names.
+
 ### Deployment and Upgrade process
 
 The Initial Registrar requires the ENS's address as a contructor, and should be deployed after the ENS. The multisig account owning the root node in the ENS should then set the Initial Registrar's address as owner of the `eth` node.
@@ -120,8 +148,25 @@ In order to limit dependence on the Initial Registrar, new auctions will stop af
 
 ### Registrar Interface
 
+`function state(bytes32 _hash) constant returns (Mode)`
+- Implements a state machine returning the current state of a name
+
+`function entries(bytes32 _hash) constant returns (Mode, address, uint, uint, uint)`
+- Returns the following information regarding a registered name:
+  * state
+  * deed address
+  * registration date
+  * balance of the deed
+  * highest value bid at auction
+
+`function getAllowedTime(bytes32 _hash) constant returns (uint timestamp)`
+- Returns the time at which the hash will no longer be in the initial `not-yet-available` state.
+
+`function isAllowed(bytes32 _hash, uint _timestamp) constant returns (bool allowed)`
+- Takes a hash and a time, returns true if and only if it has passed the initial `not-yet-available` state.
+
 `function startAuction(bytes32 _hash);`
-- Starts an auction for an available hash. If the hash is already allocated, or there is an ongoing auction,  `startAuction` will throw.
+- Moves the state of a hash from Open to Auction. Throws if state is not Open.
 
 `function startAuctions(bytes32[] _hashes);`
 - Starts multiple auctions on an array of hashes. This enables someone to open up an auction for a number of dummy hashes when they are only really interested in bidding for one. This will increase the cost for an attacker to simply bid blindly on all new auctions. Dummy auctions that are open but not bid on are closed after a week.
@@ -132,11 +177,15 @@ In order to limit dependence on the Initial Registrar, new auctions will stop af
 `function newBid(bytes32 sealedBid);`
 - Bids are sent by sending a message to the main contract with a sealedBid hash and an amount of ether. The hash contains information about the bid, including the bidded name hash, the bid value, and a random salt. Bids are not tied to any one auction until they are revealed. The value of the bid itself can be masqueraded by sending more than the value of your actual bid. This is followed by a 48h reveal period. Bids revealed after this period will be burned and the ether unrecoverable. Since this is an auction, it is expected that most public hashes, like known domains and common dictionary  words, will have multiple bidders pushing the price up.
 
+`function startAuctionsAndBid(bytes32[] hashes, bytes32 sealedBid)`
+- A utility function allowing a call to `startAuctions` followed by `newBid` in a single transaction.
+
+
 `function unsealBid(bytes32 _hash, address _owner, uint _value, bytes32 _salt);`
 - Once the bidding period is completed, there is a reveal period during with the properties of a bid are submitted to reveal them. The registrar hashes these properties using the `shaBid()` function above to verify that they match a pre-existing sealed bid. If the unsealedBid is the new best bid, the old best bid is returned to its bidder.
 
 `function cancelBid(bytes32 seal);`
-- Cancels an unrevealed bid, forfeiting  the funds.
+- Cancels an unrevealed bid according to the rules described in the notes on the refund schedule above.
 
 `function finalizeAuction(bytes32 _hash);`
 
@@ -151,29 +200,43 @@ After the registration date has passed, this function can be called to finalize
 `function invalidateName(string unhashedName);`
 - Since registration is done on the hash of a name, the registrar itself cannot validate names. This function can be used to report a name which is 6 characters long or less. If it has been registered, the submitter will earn 10% of the deed value. We are purposefully handicapping the simplified registrar as a way to force it into being restructured in a few years.
 
+`function eraseNode(bytes32[] labels)`
+- Allows anyone to delete the owner and resolver records for a subdomain of a name that is not currently owned in the registrar. For instance, to zero `foo.bar.eth` on a registrar that owns `.eth`, pass an array containing `[sha3('foo'), sha3('bar')]`.
+
 `function transferRegistrars(bytes32 _hash) onlyOwner(_hash);`
 - Used during the upgrade process to a permanent registrar. If this registrar is no longer the owner of the its root node in the ENS, this function will transfers the deed to the current owner, which should be a new registrar. This function throws if this registrar still owns its root node.
+
 ## Rationale
+
 ### Starting with a temporary registrar
 
 Anticipating and designing for all the potential issues of name allocation names is unlikely to succeed. This approach chooses not to be concerned with getting it perfect, but allows us to observe and learn with training wheels on, and implement improvements before expanding the available namespace to shorter names or another TLD.
+
 ### Valid names >= 7 characters
 
 Preserving the shortest, and often most valuable, domain names for the upgraded registrar provides the opportunity to implement processes for dispute resolution (assuming they are found to be necessary).
+
+### Delayed release of names
+
+A slower release allows for extra time to identify, and address any issues which may arise after launch.
+
 ### Restricting TLD to `.eth`
 
 Choosing a single TLD helps to maximize network effects by focusing on one namespace.
 
 A three letter TLD is a pattern made familiar by it's common usage in internet domain names. This familiarity significantly increases the potential of the ENS to be integrated into pre-existing DNS systems, and reserved as a [special-use domain name](http://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml#special-use-domain).  A recent precedent for this is the [reservation of the `.onion` domain](https://tools.ietf.org/html/rfc7686).
+
 ### Holding ether as collateral
 
-This approach is simpler than the familiar model of requiring owners to make recurring payments to retain ownership of a domain name. It also makes the initial registrar a revenue neutral service, and creates a new business model on Ethereum, by enabling owners to rent names as a service.
+This approach is simpler than the familiar model of requiring owners to make recurring payments to retain ownership of a domain name. It also makes the initial registrar a revenue neutral service.
+
 ## Prior work
 
 This document borrows heavily from several sources:
 - [EIP 137](https://github.com/ethereum/EIPs/issues/137) outlines the initial implementation of the Registry Contract (ENS.sol) and associated Resolver contracts.
 - [ERC 26](https://github.com/ethereum/EIPs/issues/26) was the first ERC to propose a name service at the contract layer
 - @alexvandesande's current implementation of the [HashRegistrar](https://github.com/Arachnid/ens/blob/master/HashRegistrarSimplified.sol)
+
 ### Edits:
 - 2016-10-26 Added link Alex's design in abstract
 - 2016-11-01 change 'Planned deactivation' to h3'

From c38848b9762f8ba0fc4fc5b40ab4d46faf3af7af Mon Sep 17 00:00:00 2001
From: Nick Johnson 
Date: Sat, 13 May 2017 16:51:44 +0100
Subject: [PATCH 0118/1085] Create ENS EIP

---
 EIPS/eip-137.md | 382 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 382 insertions(+)
 create mode 100644 EIPS/eip-137.md

diff --git a/EIPS/eip-137.md b/EIPS/eip-137.md
new file mode 100644
index 0000000000000..1b3a44b976cd5
--- /dev/null
+++ b/EIPS/eip-137.md
@@ -0,0 +1,382 @@
+
+  EIP: draft
+  Title: Ethereum Domain Name Service - Specification
+  Author: Nick Johnson 
+  Status: Draft
+  Type: Informational
+  Created: 2016-04-04
+
+ +# Abstract + +This draft EIP describes the details of the Ethereum Name Service, a proposed protocol and ABI definition that provides flexible resolution of short, human-readable names to service and resource identifiers. This permits users and developers to refer to human-readable and easy to remember names, and permits those names to be updated as necessary when the underlying resource (contract, content-addressed data, etc) changes. + +The goal of domain names is to provide stable, human-readable identifiers that can be used to specify network resources. In this way, users can enter a memorable string, such as 'vitalik.wallet' or 'www.mysite.swarm', and be directed to the appropriate resource. The mapping between names and resources may change over time, so a user may change wallets, a website may change hosts, or a swarm document may be updated to a new version, without the domain name changing. Further, a domain need not specify a single resource; different record types allow the same domain to reference different resources. For instance, a browser may resolve 'mysite.swarm' to the IP address of its server by fetching its A (address) record, while a mail client may resolve the same address to a mail server by fetching its MX (mail exchanger) record. +# Motivation + +Existing [specifications](https://github.com/ethereum/wiki/wiki/Registrar-ABI) and [implementations](https://ethereum.gitbooks.io/frontier-guide/content/registrar_services.html) for name resolution in Ethereum provide basic functionality, but suffer several shortcomings that will significantly limit their long-term usefulness: +- A single global namespace for all names with a single 'centralised' resolver. +- Limited or no support for delegation and sub-names/sub-domains. +- Only one record type, and no support for associating multiple copies of a record with a domain. +- Due to a single global implementation, no support for multiple different name allocation systems. +- Conflation of responsibilities: Name resolution, registration, and whois information. + +Use-cases that these features would permit include: +- Support for subnames/sub-domains - eg, live.mysite.tld and forum.mysite.tld. +- Multiple services under a single name, such as a DApp hosted in Swarm, a Whisper address, and a mail server. +- Support for DNS record types, allowing blockchain hosting of 'legacy' names. This would permit an Ethereum client such as Mist to resolve the address of a traditional website, or the mail server for an email address, from a blockchain name. +- DNS gateways, exposing ENS domains via the Domain Name Service, providing easier means for legacy clients to resolve and connect to blockchain services. + +The first two use-cases, in particular, can be observed everywhere on the present-day internet under DNS, and we believe them to be fundamental features of a name service that will continue to be useful as the Ethereum platform develops and matures. + +The normative parts of this document does not specify an implementation of the proposed system; its purpose is to document a protocol that different resolver implementations can adhere to in order to facilitate consistent name resolution. An appendix provides sample implementations of resolver contracts and libraries, which should be treated as illustrative examples only. + +Likewise, this document does not attempt to specify how domains should be registered or updated, or how systems can find the owner responsible for a given domain. Registration is the responsibility of registrars, and is a governance matter that will necessarily vary between top-level domains. + +Updating of domain records can also be handled separately from resolution. Some systems, such as swarm, may require a well defined interface for updating domains, in which event we anticipate the development of a standard for this. +# Specification +## Overview + +The ENS system comprises three main parts: +- The ENS registry +- Resolvers +- Registrars + +The registry is a single contract that provides a mapping from any registered name to the resolver responsible for it, and permits the owner of a name to set the resolver address, and to create subdomains, potentially with different owners to the parent domain. + +Resolvers are responsible for performing resource lookups for a name - for instance, returning a contract address, a content hash, or IP address(es) as appropriate. The resolver specification, defined here and extended in other EIPs, defines what methods a resolver may implement to support resolving different types of records. + +Registrars are responsible for allocating domain names to users of the system, and are the only entities capable of updating the ENS; the owner of a node in the ENS registry is its registrar. Registrars may be contracts or externally owned accounts, though it is expected that the root and top-level registrars, at a minimum, will be implemented as contracts. + +Resolving a name in ENS is a two-step process. First, the ENS registry is called with the name to resolve, after hashing it using the procedure described below. If the record exists, the registry returns the address of its resolver. Then, the resolver is called, using the method appropriate to the resource being requested. The resolver then returns the desired result. + +For example, suppose you wish to find the address of the token contract associated with 'beercoin.eth'. First, get the resolver: + +``` +var node = namehash("beercoin.eth"); +var resolver = ens.resolver(node); +``` + +Then, ask the resolver for the address for the contract: + +``` +var hash = resolver.addr(node); +``` + +Because the `namehash` procedure depends only on the name itself, this can be precomputed and inserted into a contract, removing the need for string manipulation, and permitting O(1) lookup of ENS records regardless of the number of components in the raw name. +## Name Syntax + +ENS names must conform to the following syntax: + +
<domain> ::= <label> | <domain> "." <label>
+<label> ::= any valid string label per [UTS46](http://unicode.org/reports/tr46/)
+
+ +In short, names consist of a series of dot-separated labels. Each label must be a valid normalised label as described in [UTS46](http://unicode.org/reports/tr46/) with the options `transitional=false` and `useSTD3AsciiRules=true`. For Javascript implementations, a [library](https://www.npmjs.com/package/idna-uts46) is available that normalises and checks names. + +Note that while upper and lower case letters are allowed in names, the UTS46 normalisation process case-folds labels before hashing them, so two names with different case but identical spelling will produce the same namehash. + +Labels and domains may be of any length, but for compatibility with legacy DNS, it is recommended that labels be restricted to no more than 64 characters each, and complete ENS names to no more than 255 characters. For the same reason, it is recommended that labels do not start or end with hyphens, or start with digits. + +## namehash algorithm + +Before being used in ENS, names are hashed using the 'namehash' algorithm. This algorithm recursively hashes components of the name, producing a unique, fixed-length string for any valid input domain. The output of namehash is referred to as a 'node'. + +Pseudocode for the namehash algorithm is as follows: + +``` +def namehash(name): + if name == '': + return '\0' * 32 + else: + label, _, remainder = name.partition('.') + return sha3(namehash(remainder) + sha3(label)) +``` + +Informally, the name is split into labels, each label is hashed. Then, starting with the last component, the previous output is concatenated with the label hash and hashed again. The first component is concatenated with 32 '0' bytes. Thus, 'mysite.swarm' is processed as follows: + +``` +node = '\0' * 32 +node = sha3(node + sha3('swarm')) +node = sha3(node + sha3('mysite')) +``` + +Implementations should conform to the following test vectors for namehash: + + namehash('') = 0x0000000000000000000000000000000000000000000000000000000000000000 + namehash('eth') = 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae + namehash('foo.eth') = 0xde9b09fd7c5f901e23a3f19fecc54828e9c848539801e86591bd9801b019f84f + +## Registry specification + +The ENS registry contract exposes the following functions: + +``` +function owner(bytes32 node) constant returns (address); +``` + +Returns the owner (registrar) of the specified node. + +``` +function resolver(bytes32 node) constant returns (address); +``` + +Returns the resolver for the specified node. + +``` +function ttl(bytes32 node) constant returns (uint64); +``` + +Returns the time-to-live (TTL) of the node; that is, the maximum duration for which a node's information may be cached. + +``` +function setOwner(bytes32 node, address owner); +``` + +Transfers ownership of a node to another registrar. This function may only be called by the current owner of `node`. A successful call to this function logs the event `Transfer(bytes32 indexed, address)`. + +``` +function setSubnodeOwner(bytes32 node, bytes32 label, address owner); +``` + +Creates a new node, `sha3(node, label)` and sets its owner to `owner`, or updates the node with a new owner if it already exists. This function may only be called by the current owner of `node`. A successful call to this function logs the event `NewOwner(bytes32 indexed, bytes32 indexed, address)`. + +``` +function setResolver(bytes32 node, address resolver); +``` + +Sets the resolver address for `node`. This function may only be called by the owner of `node`. A successful call to this function logs the event `NewResolver(bytes32 indexed, address)`. + +``` +function setTTL(bytes32 node, uint64 ttl); +``` + +Sets the TTL for a node. A node's TTL applies to the 'owner' and 'resolver' records in the registry, as well as to any information returned by the associated resolver. +## Resolver specification + +Resolvers may implement any subset of the record types specified here. Where a record types specification requires a resolver to provide multiple functions, the resolver MUST implement either all or none of them. Resolvers MUST specify a fallback function that throws. + +Resolvers have one mandatory function: + +``` +function supportsInterface(bytes4 interfaceID) constant returns (bool) +``` + +The `supportsInterface` function is documented in [EIP 165](https://github.com/ethereum/EIPs/issues/165), and returns true if the resolver implements the interface specified by the provided 4 byte identifier. An interface identifier consists of the XOR of the function signature hashes of the functions provided by that interface; in the degenerate case of single-function interfaces, it is simply equal to the signature hash of that function. If a resolver returns `true` for `supportsInterface()`, it must implement the functions specified in that interface. + +`supportsInterface` must always return true for `0x01ffc9a7`, which is the interface ID of `supportsInterface` itself. + + Currently standardised resolver interfaces are specified in the table below. + +The following interfaces are defined: + +| Interface name | Interface hash | Specification | +| --- | --- | --- | +| `addr` | 0x3b3b57de | [Contract address](#addr) | +| `name` | 0x691f3431 | #181 | +| `ABI` | 0x2203ab56 | #205 | +| `pubkey` | 0xc8690233 | #619 | + +EIPs may define new interfaces to be added to this registry. +###
Contract Address Interface + +Resolvers wishing to support contract address resources must provide the following function: + +``` +function addr(bytes32 node) constant returns (address); +``` + +If the resolver supports `addr` lookups but the requested node does not have a record, the resolver MUST return the zero address. + +Changes to an address MUST trigger the following event: + +``` +event AddrChanged(bytes32 indexed node, address a); +``` +# Appendix A: Registry Implementation + +``` +contract ENS { + struct Record { + address owner; + address resolver; + uint64 ttl; + } + + mapping(bytes32=>Record) records; + + event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner); + event Transfer(bytes32 indexed node, address owner); + event NewResolver(bytes32 indexed node, address resolver); + + modifier only_owner(bytes32 node) { + if(records[node].owner != msg.sender) throw; + _ + } + + function ENS(address owner) { + records[0].owner = owner; + } + + function owner(bytes32 node) constant returns (address) { + return records[node].owner; + } + + function resolver(bytes32 node) constant returns (address) { + return records[node].resolver; + } + + function ttl(bytes32 node) constant returns (uint64) { + return records[node].ttl; + } + + function setOwner(bytes32 node, address owner) only_owner(node) { + Transfer(node, owner); + records[node].owner = owner; + } + + function setSubnodeOwner(bytes32 node, bytes32 label, address owner) only_owner(node) { + var subnode = sha3(node, label); + NewOwner(node, label, owner); + records[subnode].owner = owner; + } + + function setResolver(bytes32 node, address resolver) only_owner(node) { + NewResolver(node, resolver); + records[node].resolver = resolver; + } + + function setTTL(bytes32 node, uint64 ttl) only_owner(node) { + NewTTL(node, ttl); + records[node].ttl = ttl; + } +} +``` +# Appendix B: Sample Resolver Implementations +### Built-in resolver + +The simplest possible resolver is a contract that acts as its own name resolver by implementing the contract address resource profile: + +``` +contract DoSomethingUseful { + // Other code + + function addr(bytes32 node) constant returns (address) { + return this; + } + + function supportsInterface(bytes4 interfaceID) constant returns (bool) { + return interfaceID == 0x3b3b57de || interfaceID == 0x01ffc9a7; + } + + function() { + throw; + } +} +``` + +Such a contract can be inserted directly into the ENS registry, eliminating the need for a separate resolver contract in simple use-cases. However, the requirement to 'throw' on unknown function calls may interfere with normal operation of some types of contract. + +### Standalone resolver + +A basic resolver that implements the contract address profile, and allows only its owner to update records: + +``` +contract Resolver { + event AddrChanged(bytes32 indexed node, address a); + + address owner; + mapping(bytes32=>address) addresses; + + modifier only_owner() { + if(msg.sender != owner) throw; + _ + } + + function Resolver() { + owner = msg.sender; + } + + function addr(bytes32 node) constant returns(address) { + return addresses[node]; + } + + function setAddr(bytes32 node, address addr) only_owner { + addresses[node] = addr; + AddrChanged(node, addr); + } + + function supportsInterface(bytes4 interfaceID) constant returns (bool) { + return interfaceID == 0x3b3b57de || interfaceID == 0x01ffc9a7; + } + + function() { + throw; + } +} +``` + +After deploying this contract, use it by updating the ENS registry to reference this contract for a name, then calling `setAddr()` with the same node to set the contract address it will resolve to. +### Public resolver + +Similar to the resolver above, this contract only supports the contract address profile, but uses the ENS registry to determine who should be allowed to update entries: + +``` +contract PublicResolver { + event AddrChanged(bytes32 indexed node, address a); + event ContentChanged(bytes32 indexed node, bytes32 hash); + + ENS ens; + mapping(bytes32=>address) addresses; + + modifier only_owner(bytes32 node) { + if(ens.owner(node) != msg.sender) throw; + _ + } + + function PublicResolver(address ensAddr) { + ens = ENS(ensAddr); + } + + function addr(bytes32 node) constant returns (address ret) { + ret = addresses[node]; + } + + function setAddr(bytes32 node, address addr) only_owner(node) { + addresses[node] = addr; + AddrChanged(node, addr); + } + + function supportsInterface(bytes4 interfaceID) constant returns (bool) { + return interfaceID == 0x3b3b57de || interfaceID == 0x01ffc9a7; + } + + function() { + throw; + } +} +``` +# Appendix C: Sample Registrar Implementation + +This registrar allows users to register names at no cost if they are the first to request them. + +``` +contract FIFSRegistrar { + ENS ens; + bytes32 rootNode; + + function FIFSRegistrar(address ensAddr, bytes32 node) { + ens = ENS(ensAddr); + rootNode = node; + } + + function register(bytes32 subnode, address owner) { + var node = sha3(rootNode, subnode); + var currentOwner = ens.owner(node); + if(currentOwner != 0 && currentOwner != msg.sender) + throw; + + ens.setSubnodeOwner(rootNode, subnode, owner); + } +} +``` From 0df8363fc6773ee7a50c69d440c6b58eae82e240 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Sat, 13 May 2017 16:53:40 +0100 Subject: [PATCH 0119/1085] ERC: Ethereum Name Service reverse resolution support --- EIPS/eip-181.md | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 EIPS/eip-181.md diff --git a/EIPS/eip-181.md b/EIPS/eip-181.md new file mode 100644 index 0000000000000..66b08a23e4f83 --- /dev/null +++ b/EIPS/eip-181.md @@ -0,0 +1,104 @@ +
+  EIP: 181
+  Title: ENS support for reverse resolution of Ethereum addresses
+  Author: Nick Johnson 
+  Status: Draft
+  Type: Informational
+  Created: 2016-12-01
+
+ +# Abstract +This EIP specifies a TLD, registrar, and resolver interface for reverse resolution of Ethereum addresses using ENS. This permits associating a human-readable name with any Ethereum blockchain address. Resolvers can be certain that the reverse record was published by the owner of the Ethereum address in question. + +# Motivation +While name services are mostly used for forward resolution - going from human-readable identifiers to machine-readable ones - there are many use-cases in which reverse resolution is useful as well: + + - Applications that allow users to monitor accounts benefit from showing the name of an account instead of its address, even if it was originally added by address. + - Attaching metadata such as descriptive information to an address allows retrieving this information regardless of how the address was originally discovered. + - Anyone can configure a name to resolve to an address, regardless of ownership of that address. Reverse records allow the owner of an address to claim a name as authoritative for that address. + +# Specification +Reverse ENS records are stored in the ENS hierarchy in the same fashion as regular records, under a reserved domain, `addr.reverse`. To generate the ENS name for a given account's reverse records, convert the account to hexadecimal representation in lower-case, and append `addr.reverse`. For instance, the ENS registry's address at `0x112234455c3a32fd11230c42e7bccd4a84e02010` has any reverse records stored at `112234455c3a32fd11230c42e7bccd4a84e02010.addr.reverse`. + +Note that this means that contracts wanting to do dynamic reverse resolution of addresses will need to perform hex encoding in the contract. + +## Registrar +The owner of the `addr.reverse` domain will be a registrar that permits the caller to take ownership of +the reverse record for their own address. It provides the following method: + + function claim(address owner) returns (bytes32 node); + +When called by account `x` it will instruct the ENS registry to transfer ownership of the name `hex(x) + '.addr.reverse'` to the provided address, and return the namehash of the ENS record thus transferred. + +Allowing the caller to specify an owner other than themselves for the relevant node facilitates contracts that need accurate reverse ENS entries delegating this to their creators with a minimum of code inside their constructor: + + reverseRegistrar.claim(msg.sender) + +## Resolver interface +A new resolver interface is defined, consisting of the following method: + + function name(bytes32 node) constant returns (string); + +Resolvers that implement this interface must return a valid ENS name for the requested node, or the empty string if no name is defined for the requested node. + +The interface ID of this interface is 0x691f3431. + +Future EIPs may specify more record types appropriate to reverse ENS records. + +# Appendix 1: Registrar implementation + +This registrar, written in Solidity, implements the specifications outlined above. + + pragma solidity ^0.4.0; + + import 'interface.sol'; + + contract ReverseRegistrar { + AbstractENS public ens; + bytes32 public rootNode; + + /** + * @dev Constructor + * @param ensAddr The address of the ENS registry. + * @param node The node hash that this registrar governs. + */ + function ReverseRegistrar(address ensAddr, bytes32 node) { + ens = AbstractENS(ensAddr); + rootNode = node; + } + + /** + * @dev Transfers ownership of the reverse ENS record associated with the + * calling account. + * @param owner The address to set as the owner of the reverse record in ENS. + * @return The ENS node hash of the reverse record. + */ + function claim(address owner) returns (bytes32 node) { + var label = sha3HexAddress(msg.sender); + ens.setSubnodeOwner(rootNode, label, owner); + return sha3(rootNode, label); + } + + /** + * @dev An optimised function to compute the sha3 of the lower-case + * hexadecimal representation of an Ethereum address. + * @param addr The address to hash + * @return The SHA3 hash of the lower-case hexadecimal encoding of the + * input address. + */ + function sha3HexAddress(address addr) constant returns (bytes32 ret) { + assembly { + let lookup := 0x3031323334353637383961626364656600000000000000000000000000000000 + let i := 40 + loop: + i := sub(i, 1) + mstore8(i, byte(and(addr, 0xf), lookup)) + addr := div(addr, 0x10) + i := sub(i, 1) + mstore8(i, byte(and(addr, 0xf), lookup)) + addr := div(addr, 0x10) + jumpi(loop, i) + ret := sha3(0, 40) + } + } + } From afe7d07eb17126efbaddfef72985eb3d76f5f90d Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Sun, 14 May 2017 09:13:12 +0100 Subject: [PATCH 0120/1085] Update metadata --- EIPS/eip-181.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-181.md b/EIPS/eip-181.md index 66b08a23e4f83..bbd0f48e6ba2c 100644 --- a/EIPS/eip-181.md +++ b/EIPS/eip-181.md @@ -2,8 +2,9 @@ EIP: 181 Title: ENS support for reverse resolution of Ethereum addresses Author: Nick Johnson - Status: Draft - Type: Informational + Status: Final + Type: Standard Track + Category: ERC Created: 2016-12-01
From 4e36eebfc33be9cf28c3ffe25dbe100214e32603 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Sun, 14 May 2017 09:14:24 +0100 Subject: [PATCH 0121/1085] Update metadata. --- EIPS/eip-137.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-137.md b/EIPS/eip-137.md index 1b3a44b976cd5..7c0aeb2121f9c 100644 --- a/EIPS/eip-137.md +++ b/EIPS/eip-137.md @@ -1,9 +1,10 @@
-  EIP: draft
+  EIP: Final
   Title: Ethereum Domain Name Service - Specification
   Author: Nick Johnson 
-  Status: Draft
-  Type: Informational
+  Status: Final
+  Type: Standards Track
+  Category: ERC
   Created: 2016-04-04
 
From b9cc4f3ca2929d5968e2b56eacaa191d56c27bb0 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Sun, 14 May 2017 09:14:41 +0100 Subject: [PATCH 0122/1085] Update EIP number --- EIPS/eip-137.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-137.md b/EIPS/eip-137.md index 7c0aeb2121f9c..fa8cdc1ca87bc 100644 --- a/EIPS/eip-137.md +++ b/EIPS/eip-137.md @@ -1,5 +1,5 @@
-  EIP: Final
+  EIP: 137
   Title: Ethereum Domain Name Service - Specification
   Author: Nick Johnson 
   Status: Final

From 640b20772adfc3d59b6bf2f2d0a2c95fdfa51493 Mon Sep 17 00:00:00 2001
From: maurelian 
Date: Mon, 15 May 2017 11:02:17 -0400
Subject: [PATCH 0123/1085] Remove forbidden status

---
 EIPS/eip-ens-initial-registrar.md | 1 -
 1 file changed, 1 deletion(-)

diff --git a/EIPS/eip-ens-initial-registrar.md b/EIPS/eip-ens-initial-registrar.md
index 0c7fb513f0e12..e8a4c1f35e5bd 100644
--- a/EIPS/eip-ens-initial-registrar.md
+++ b/EIPS/eip-ens-initial-registrar.md
@@ -91,7 +91,6 @@ The auction lifecycle of a name has 5 possible states, or Modes.
 3. **Auction:** Once the auction for a name has begun, there is a 72 hour bidding period. Bidders must submit a payment of ether, along with sealed bids as a hash of `sha3(bytes32 hash, address owner, uint value, bytes32 salt)`. The bidder may obfuscate the true bid value by sending a greater amount of ether.
 4. **Reveal:** After the bidding period, a 48 hour reveal period commences. During this time, bidders must reveal the true parameters of their sealed bid. As bids are revealed, ether payments are returned according to the schedule of "refund ratios" outlined in the table below. If no bids are revealed, the name will return to the Open state.
 5. **Owned:** After the reveal period has finished, the winning bidder must submit a transaction to finalize the auction, which then calls the ENS's `setSubnodeOwner` function, recording the winning bidder's address as the owner of the hash of the name.
-
 
 
+#### Registrar Parameters
+
+|        Name        |                                            Description                                             |   Value    |
+|--------------------|----------------------------------------------------------------------------------------------------|------------|
+| totalAuctionLength | The full time period from start of auction to end of the reveal period.                            | 5 days     |
+| revealPeriod       | The length of the time period during which bidding is no longer allowed, and bids must be revealed. | 48 hours   |
+| launchLength       | The time period during which all names will become available for auction.                          | 8 weeks    |
+| minPrice           | The minimum amount of ether which must be locked up in exchange for ownership of a name.           | 0.01 ether |
 
 ### Deeds
 

From 4ef40edbdf20ac01d14ba6bf35699287ba285264 Mon Sep 17 00:00:00 2001
From: maurelian 
Date: Mon, 15 May 2017 16:34:03 -0400
Subject: [PATCH 0126/1085] Updates per @arachnid's review on PR #632:

---
 EIPS/eip-ens-initial-registrar.md | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/EIPS/eip-ens-initial-registrar.md b/EIPS/eip-ens-initial-registrar.md
index a20a88a6d3449..33a879370cf67 100644
--- a/EIPS/eip-ens-initial-registrar.md
+++ b/EIPS/eip-ens-initial-registrar.md
@@ -1,8 +1,8 @@
 ```
-EIP: Draft
+EIP: 162
 Title: Initial ENS Hash Registrar
 Author: Maurelian and Nick Johnson
-Status: Draft
+Status: Final
 Type: Informational
 Created: 2016-10-25
 ```
@@ -74,7 +74,7 @@ The Initial Registrar will also prohibit registration of names 6 characters or l
 
 Names submitted to the initial registrar must be hashed using Ethereum's sha3 function. Note that the hashes submitted to the registrar are the hash of the subdomain label being registered, not the namehash as defined in EIP 137.
 
-For example, in order to register `abcdefg.eth`, one should submit `sha3('abcdefg')`, not `sha3('abcdefg', sha3('eth', 0))`.
+For example, in order to register `abcdefg.eth`, one should submit `sha3('abcdefg')`, not `sha3(sha3(0, 'eth'), 'abcdefg')`.
 
 ### Auctioning names
 

From e07cff53904063012eb77a577bc9ab595feacf93 Mon Sep 17 00:00:00 2001
From: chriseth 
Date: Thu, 18 May 2017 11:50:03 +0200
Subject: [PATCH 0127/1085] Change codes to 0x3d and 0x3e

---
 EIPS/returndatacopy.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/EIPS/returndatacopy.md b/EIPS/returndatacopy.md
index 66bbd3e17ddca..07635c84d2f4e 100644
--- a/EIPS/returndatacopy.md
+++ b/EIPS/returndatacopy.md
@@ -33,12 +33,12 @@ Add two new opcodes and amend the semantics of any opcode that creates a new cal
 
 As an optimization, it is possible to share the return data buffer across call frames because only one will be non-empty at any time.
 
-`RETURNDATASIZE`: `0xd`
+`RETURNDATASIZE`: `0x3d`
 
 Pushes the size of the return data buffer onto the stack.
 Gas costs: 2 (same as `CALLDATASIZE`)
 
-`RETURNDATACOPY`: `0xe`
+`RETURNDATACOPY`: `0x3e`
 
 This opcode has similar semantics to `CALLDATACOPY`, but instead of copying data from the call data, it copies data from the return data buffer. If the return data buffer is accessed beyond its size, it is considered to be filled with zeros.
 

From 71ace16fcd34e962096a49d7dc81af2315d5f199 Mon Sep 17 00:00:00 2001
From: chriseth 
Date: Thu, 18 May 2017 15:05:11 +0200
Subject: [PATCH 0128/1085] Added CREATE2

---
 EIPS/returndatacopy.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/EIPS/returndatacopy.md b/EIPS/returndatacopy.md
index 07635c84d2f4e..9689f459e8d69 100644
--- a/EIPS/returndatacopy.md
+++ b/EIPS/returndatacopy.md
@@ -29,7 +29,7 @@ Note that this proposal also makes the EIP that proposes to allow to return data
 
 ## Specification
 
-Add two new opcodes and amend the semantics of any opcode that creates a new call frame (like `CALL`, `CREATE`, `DELEGATECALL`, ...) called call-like opcodes in the following. It is assumed that the EVM (to be more specific: an EVM call frame) has a new internal buffer of variable size, called the return data buffer. This buffer is created empty for each new call frame. Upon executing any call-like opcode, the buffer is cleared (its size is set to zero). After executing a call-like opcode, the complete return data (or failure data, see EIP [206](https://github.com/ethereum/EIPs/pull/206)) of the call is stored in the return data buffer (of the caller), and its size changed accordingly. As an exception, `CREATE` is considered to return the empty buffer in the success case and the failure data in the failure case. 
+Add two new opcodes and amend the semantics of any opcode that creates a new call frame (like `CALL`, `CREATE`, `DELEGATECALL`, ...) called call-like opcodes in the following. It is assumed that the EVM (to be more specific: an EVM call frame) has a new internal buffer of variable size, called the return data buffer. This buffer is created empty for each new call frame. Upon executing any call-like opcode, the buffer is cleared (its size is set to zero). After executing a call-like opcode, the complete return data (or failure data, see EIP [206](https://github.com/ethereum/EIPs/pull/206)) of the call is stored in the return data buffer (of the caller), and its size changed accordingly. As an exception, `CREATE` and `CREATE2` are considered to return the empty buffer in the success case and the failure data in the failure case. 
 
 As an optimization, it is possible to share the return data buffer across call frames because only one will be non-empty at any time.
 

From bee45153fa4291a4f42aba3e4b75a9f4613796fd Mon Sep 17 00:00:00 2001
From: chriseth 
Date: Thu, 18 May 2017 15:35:34 +0200
Subject: [PATCH 0129/1085] Some clarifications and extensions.

---
 EIPS/static_call.md | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/EIPS/static_call.md b/EIPS/static_call.md
index aab771f3db8a7..fb36b9335eb5e 100644
--- a/EIPS/static_call.md
+++ b/EIPS/static_call.md
@@ -1,6 +1,6 @@
 ## Preamble
 
-    EIP: to be assigned
+    EIP: 214
     Title: New opcode STATICCALL
     Author: Vitalik Buterin , Christian Reitwiessner ;
     Type: Standard Track
@@ -14,15 +14,23 @@ To increase smart contract security, this proposal adds a new opcode that can be
 
 ## Abstract
 
+This proposal adds a new opcode that can be used to call another contract (or itself) while disallowing any modifications to the state during the call (and its subcalls, if present). Any opcode that attempts to perform such a modification (see below for details) will result in an exception instead of performing the modification.
 
 ## Motivation
 
+Currently, there is no restriction about what a called contract can do, as long as the computation can be performed with the amount of gas provided. This poses certain difficulties about smart contract engineers: After a regular call, unless you know the called contract, you cannot make any assumptions about the state of the contracts. Furthermore, because you cannot know the order of transactions before they are confirmed by miners, not even an outside observer can be sure about that in all cases.
+
+This EIP adds a way to call other contracts and restrict what they can do in the simplest way. It can be safely assumed that the state of all contracts is the same before and after a static call.
 
 ## Specification
 
+Introduce a new `STATIC` flag to the virtual machine. This flag is set to `false` initially. Its value is always copied to sub-calls or sub-creates with an exception for the new opcode below.
+
 Opcode: `0xfa`.
 
-`STATICCALL` functions equivalently to a `CALL`, except it takes 6 arguments not including value, and calls the child with a `STATIC` flag on. Any calls, static or otherwise, made by an execution instance with a `STATIC` flag on will also have a `STATIC` flag on. Any attempts to make state-changing operations inside an execution instance with a `STATIC` flag on will instead throw an exception. These operations include nonzero-value calls, creates, `LOG` calls, `SSTORE`, `SSTOREBYTES` and `SUICIDE`.
+`STATICCALL` functions equivalently to a `CALL`, except it takes 6 arguments not including value, and calls the child with the `STATIC` flag set to `true`.
+
+Any attempts to make state-changing operations inside an execution instance with `STATIC` set to `true` will instead throw an exception. These operations include `CREATE`, `CREATE2`, `LOG`, `SSTORE`, `SSTOREBYTES` and `SELFDESTRUCT`. They also include `CALL` and `DELEGATECALL` with a non-zero value. As an exception, `CALLCODE` is not considered state-changing, even with a non-zero value.
 
 ## Rationale
 
@@ -30,7 +38,7 @@ This allows contracts to make calls that are clearly non-state-changing, reassur
 
 ## Backwards Compatibility
 
-This proposal adds a new opcode but does not modify the behaviour of other opcodes and thus is backwards compatible for old contracts that do not use the new opcode.
+This proposal adds a new opcode but does not modify the behaviour of other opcodes and thus is backwards compatible for old contracts that do not use the new opcode and are not called via the new opcode.
 
 ## Test Cases
 

From ffcee11782d0fd1830eea9a73d7bcf9b949943f0 Mon Sep 17 00:00:00 2001
From: chriseth 
Date: Thu, 18 May 2017 16:02:15 +0200
Subject: [PATCH 0130/1085] Clarifications and first gas cost suggestion.

---
 EIPS/pairings.md | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/EIPS/pairings.md b/EIPS/pairings.md
index 9f8941168082c..509a86e9c5ce2 100644
--- a/EIPS/pairings.md
+++ b/EIPS/pairings.md
@@ -45,11 +45,13 @@ Output: If the length of the input is incorrect or any of the inputs are not ele
         (in F_q) and zero else.
 ```
 
-Note that k is determined from the length of the input. k == 0 is valid and results in returning one.
+Note that `k` is determined from the length of the input. `k == 0` is valid and results in returning one.
+
+In order to check that an input is an element of `G_1`, verifying the encoding of the coordinates and checking that they satisfy the curve equation (or is the encoding of infinity) is sufficient. For `G_2`, in addition to that, the order of the element has to be checked to be equal to the group order `q = 21888242871839275222246405745257275088548364400416034343698204186575808495617`.
 
 ### Definition of the groups
 
-The groups `G_1` and `G_2` are cyclic groups of prime order `q` on the elliptic curve `alt_bn128` defined by the curve equation
+The groups `G_1` and `G_2` are cyclic groups of prime order `q = 21888242871839275222246405745257275088548364400416034343698204186575808495617` on the elliptic curve `alt_bn128` defined by the curve equation
 `Y^2 = X^3 + 3`.
 
 The group `G_1` is a cyclic group on the above curve over the field `F_p` with `p = 21888242871839275222246405745257275088696311157297823662689037894645226208583` with generator `P1 = (1, 2)`.
@@ -79,7 +81,15 @@ The length of the returned data is always exactly 32 bytes and encoded as a 32 b
 
 ### Gas costs
 
-To be determined. 
+[Benchmarks run on cpp-ethereum](https://gist.github.com/chriseth/4168b56bfe638cae8da1945dd988600b)
+
+suggest the following gas formula:
+
+`60000 * k + 40000`
+
+if we target 20000 gas per millisecond.
+
+Awaiting benchmarks from other implementations.
 
 ## Rationale
 

From db6cd44d00addb61758d7cfd5aff4d3083904665 Mon Sep 17 00:00:00 2001
From: ethers 
Date: Thu, 18 May 2017 21:12:01 -0400
Subject: [PATCH 0131/1085] Clearer explanation of revealing a bid late

---
 EIPS/eip-ens-initial-registrar.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/EIPS/eip-ens-initial-registrar.md b/EIPS/eip-ens-initial-registrar.md
index 33a879370cf67..a69ee232b17f3 100644
--- a/EIPS/eip-ens-initial-registrar.md
+++ b/EIPS/eip-ens-initial-registrar.md
@@ -121,14 +121,14 @@ The following table outlines what portion of the balance held in a deed contract
 | --- | --- | --- |
 | A valid non-winning bid is revealed. | Bidder | 99.5% |
 | A bid submitted after the auction period is revealed. | Bidder | 99.5% |
-| An otherwise valid bid is revealed on an owned name. 1 | Bidder | %0.5 |
+| A bid is revealed after the reveal period. 1 | Bidder | 0.5% |
 | An expired sealed bid is cancelled. 2 | Canceler | 0.5% |
 | A registered hash is reported as invalid. 3 | Reporter | 50% |
 | A registered hash is reported as invalid. 3 | Owner | 50% |
 
 ##### Notes:
 
-1. This is to prevent an extortion attack on the current highest bidder, by threatening to reveal a new second highest bid. This forces all bids to be revealed.
+1. This incentivizes all bids to be revealed in time. If bids could be revealed late, an extortion attack on the current highest bidder could be made by threatening to reveal a new second highest bid.
 2. A bid which remains sealed after more than 2 weeks and 5 days may be cancelled by anyone to collect a small reward.
 2. Since names are hashed before auctioning and registration, the Initial Registrar is unable to enforce character length restrictions independently. A reward is therefore provided for reporting invalid names.
 

From e8355d2809207cce837a9c03d05e27aa4ed398b3 Mon Sep 17 00:00:00 2001
From: Nick Johnson 
Date: Mon, 22 May 2017 12:30:06 +0100
Subject: [PATCH 0132/1085] Rename eip-ens-initial-registrar.md to eip-162.md

---
 EIPS/{eip-ens-initial-registrar.md => eip-162.md} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename EIPS/{eip-ens-initial-registrar.md => eip-162.md} (100%)

diff --git a/EIPS/eip-ens-initial-registrar.md b/EIPS/eip-162.md
similarity index 100%
rename from EIPS/eip-ens-initial-registrar.md
rename to EIPS/eip-162.md

From c5c0c4d2077899ea98e1868c81edc6a7c22e8045 Mon Sep 17 00:00:00 2001
From: Nick Johnson 
Date: Mon, 22 May 2017 12:30:20 +0100
Subject: [PATCH 0133/1085] Delete eip-XXX.md

---
 EIPS/eip-XXX.md | 526 ------------------------------------------------
 1 file changed, 526 deletions(-)
 delete mode 100644 EIPS/eip-XXX.md

diff --git a/EIPS/eip-XXX.md b/EIPS/eip-XXX.md
deleted file mode 100644
index dfbfe5a0ab130..0000000000000
--- a/EIPS/eip-XXX.md
+++ /dev/null
@@ -1,526 +0,0 @@
-
-  EIP: draft
-  Title: Ethereum Domain Name Service - Specification
-  Author: Nick Johnson 
-  Status: Draft
-  Type: Informational
-  Created: 2016-04-04
-
- -Abstract -======== -This draft EIP describes the details of the Ethereum Name Service, a proposed protocol and ABI definition that provides flexible resolution of short, human-readable names to service and resource identifiers. This permits users and developers to refer to human-readable and easy to remember names, and permits those names to be updated as necessary when the underlying resource (contract, content-addressed data, etc) changes. - -The goal of domain names is to provide stable, human-readable identifiers that can be used to specify network resources. In this way, users can enter a memorable string, such as 'vitalik.wallet' or 'www.mysite.swarm', and be directed to the appropriate resource. The mapping between names and resources may change over time, so a user may change wallets, a website may change hosts, or a swarm document may be updated to a new version, without the domain name changing. Further, a domain need not specify a single resource; different record types allow the same domain to reference different resources. For instance, a browser may resolve 'mysite.swarm' to the IP address of its server by fetching its A (address) record, while a mail client may resolve the same address to a mail server by fetching its MX (mail exchanger) record. - -Motivation -========== -Existing [specifications](https://github.com/ethereum/wiki/wiki/Registrar-ABI) and [implementations](https://ethereum.gitbooks.io/frontier-guide/content/registrar_services.html) for name resolution in Ethereum provide basic functionality, but suffer several shortcomings that will significantly limit their long-term usefulness: - - - A single global namespace for all names with a single 'centralised' resolver. - - Limited or no support for delegation and sub-names/sub-domains. - - Only one record type, and no support for associating multiple copies of a record with a domain. - - Due to a single global implementation, no support for multiple different name allocation systems. - - Conflation of responsibilities: Name resolution, registration, and whois information. - -Use-cases that these features would permit include: - - - Support for subnames/sub-domains - eg, live.mysite.tld and forum.mysite.tld. - - Multiple services under a single name, such as a DApp hosted in Swarm, a Whisper address, and a mail server. - - Support for DNS record types, allowing blockchain hosting of 'legacy' names. This would permit an Ethereum client such as Mist to resolve the address of a traditional website, or the mail server for an email address, from a blockchain name. - - DNS gateways, exposing ENS domains via the Domain Name Service, providing easier means for legacy clients to resolve and connect to blockchain services. - - Programmatic name definition and resolution - for example, providing a service that resolves <content hash>.swarm.tld to a swarm node that can return the content. - -The first two use-cases, in particular, can be observed everywhere on the present-day internet under DNS, and we believe them to be fundamental features of a name service that will continue to be useful as the Ethereum platform develops and matures. - -We propose to draw lessons from the design of the [DNS](https://www.ietf.org/rfc/rfc1035.txt) system, which has been providing name resolution to the internet for over 30 years. Many features apply well to Etherum and can be adapted; others are inapplicable or unwanted and should be discarded. - -The normative parts of this document does not specify an implementation of the proposed system; its purpose is to document a protocol that different resolver implementations can adhere to in order to facilitate consistent name resolution. An appendix provides sample implementations of resolver contracts and libraries, which should be treated as illustrative examples only. - -Likewise, this document does not attempt to specify how domains should be registered or updated, or how systems can find the owner responsible for a given domain. Registration is the responsibility of registrars, and is a governance matter that will necessarily vary between top-level domains. We propose a design for the governance of the top level resolver in a separate document (TBD). - -Updating of domain records can also be handled separately from resolution. Some systems, such as swarm, may require a well defined interface for updating domains, in which event we anticipate the development of a standard for this. Finally, finding the responsible parties of a domain is the task of a whois system, which can be specified separately, even if resolvers typically implement both protocols. - -Specification -============= -Overview --------- -The ENS, or Ethereum Name Service, proposed here, borrows where appropriate from the Domain Name System used to resolve domain names on the internet. This is done both because their requirements are similar, and thus we can take advantage of lessons learned from 30 years of accumulated experience serving as the Internet's name resolution system, and because it permits easier interoperability between the two systems. - -Although this document aims to be as self contained as possible, in the interest of avoiding duplication, we make references to features of the DNS specification. [RFC1035](https://www.ietf.org/rfc/rfc1035.txt), which provides the basic definition of the domain name system, may prove useful reading alongside this document. - -ENS is hierarchial, with more general parts on the left, and more specific parts on the right. In the domain 'www.example.com', 'com' is the top-level domain, while 'www' specifies a sub-domain. Unlike DNS, names are relative; each resolver is passed one label to resolve, and it performs a lookup and returns its record for that label. This means that rather than forming a tree, the set of deployed names may form a graph; nodes can link to each other at any depth in the hierarchy. The resolution process is described in detail below. - -Although we expect most users to converge on a common root-level resolver, the system permits the existence of 'alternate roots', which provide their own set of top-level domains, which may potentially overlap with those exposed by other root resolvers. Due to the relative nature of name resolution in ENS, users may point to a "local resolver"; a name that resolves internally as "mysite.corp" may be exposed to external users as "mysite.corp.company.com". - -Resolvers exist as contracts in the Ethereum blockchain; this allows contracts to perform name resolution, in addition to allowing use by DApps. We expect both to use ENS for resolving names to contracts and to content hashes. - -Name Syntax ------------ -ENS names must conform to the following syntax: - -
<domain> ::= <label> | <domain> "." <label>
-<label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
-<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
-<let-dig-hyp> ::= <let-dig> | "-"
-<let-dig> ::= <letter> | <digit>
-<letter> ::= any one of the 52 alphabetic characters A through Z in
-upper case and a through z in lower case
-<digit> ::= any one of the ten digits 0 through 9
-
- -In short, names consist of a series of dot-separated labels. Each label must start with a letter, and end with a letter or a digit. Intermediate letters may be letters, digits, or hyphens. - -Note that while upper and lower case letters are allowed in names, no significance is attached to case. Two names with different case but identical spelling should be treated as identical. - -Labels and domains may be of any length, but for compatibility with legacy DNS, it is recommended that labels be restricted to no more than 64 characters each, and complete ENS names to no more than 255 characters. - -Names are restricted to ASCII on the basis that the existing punycode and nameprep systems exist to allow browsers and other tools to support unicode domain names. Although it is tempting to fully support UTF-8 directly in the system, this would require resolvers to implement generalized unicode case folding, which imposes an undue burden on contracts, which have to limit their gas consumption for callers. - -ENS Structure -------------- -The ENS hierarchy is conceptually structured as a tree. Each node in the tree represents a part of a name. A tree node may have child nodes, representing subdomains, and resource records (RRs), containing mapping information from names to other resources. - -A (simple) example tree might look something like this: - - (root node) - - "swarm" - - "mysite" - - RR: "CHASH" => "0x12345678" - - "othersite" - - RR: "CHASH" => "0x23456789" - - "subdomain" - - RR: "CHASH" => "0x34567890" - - "eth - - "bob" - - RR: "HA" => "0x45678901" - - RR: "HA" => "0x56789012" - - RR: "CHASH" => "0x67890123" - -Each node is uniquely identified by a Node ID and a resolver address. Node IDs are allocated arbitrarily by resolvers, and make it possible to resolve many different parts of the ENS hierarchy using a single resolver instance. Any of the above nodes may be hosted by separate resolvers; resolvers host "glue records" that allow clients to follow the links from one resolver to another when resolving a name. - -Since any node can point to any other node, the ENS hierarchy is in fact a graph rather than a tree; it can even be cyclic, though in practical cases will generally not be. The structure of ENS makes it easy for organisations to define their own name (sub-)hierarchies, delegating parts of the namespace as they see fit. - -Resolution Process ------------------- -Before being passed to resolvers, ENS names are preprocessed. The name is divided into labels, starting with the rightmost one, and each label is first folded to lower-case, then hashed with SHA3-256. So, the domain "subdomain.othersite.swarm", after processing, becomes the sequence of labels [sha3("swarm"), sha3("othersite"), sha3("subdomain")]. - -Name resolution is performed iteratively. The client first performs `findResolver` query on the root resolver, passing it the hash of the rightmost label. The root resolver looks up its internal node for the last domain component, sha3("swarm") in this example. If the record, which consists of a (node ID, resolver address) tuple exists, it returns it, and the client repeats the process for the resolver specified in that record with the next part of the domain. If at any point the record does not exist, an immediate response of NXDOMAIN (No such domain) is returned. - -Once this procedure has been executed for all domain components, the final resolver is sent a `resolve` query for the requested record type. - -Resolvers are specified with a 160 bit address, specifying the address of the Ethereum contract acting as the resolver, and a 96 bit node ID. Node IDs are local to each resolver, and allow resolvers to host multiple independent subtrees. By convention, a root resolver's main tree has node ID of 0, but this is not mandatory. - -RR Definitions --------------- -### Format -A Resource Record is the base unit of storage and retrieval in the ENS. Each resource record consists of: - - NAME - the name to which this record pertains. - - TYPE - one of the RR type codes, specifying the type of resource being addressed. - - TTL - the duration, in seconds, that the record may be cached. - - RDATA - the data associated with this record, whose format depends on TYPE and (potentially) CLASS. - -### TYPE values -TYPE fields specify the nature of the record. ENS uses the same definitions of types as DNS, a registry of which can be seen [here](http://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4). - -Until standardized TYPE values are assigned, the following temporary TYPEs are employed for new record types: - - CHASH - Provides the content-hash of a document, retrievable using a content-addressed storage system. - - HA - Provides the hash-based address of an entity, such as a blockchain account address. - -Unlike DNS, which uses type IDs from a 16 bit range to identify record types, ENS encodes types directly as ASCII strings in a bytes32 argument. Strings are left-aligned and padded with 0 bytes. - -### QTYPE values -QTYPE fields appear in the question part of a query. QTYPES are a superset of TYPEs, hence all TYPEs are valid QTYPEs. EIP defines the same set of QTYPEs as DNS. - -New RRs -------- -### CHASH RDATA format -
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-|                                               |
-/                                               /
-/                   Hash value                  /
-|                                               |
-+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- -Where: - - Hash value - the binary value of a hash function applied to the content being referenced. - -A CHASH record serves as a means to identify a document by its hash, permitting lookup in hash-named datastores such as Swarm. - -### HA RDATA format -
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-|                                               |
-/                                               /
-/                   Hash value                  /
-|                                               |
-+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- -Where: - - Hash value - the binary value of the hash-based address. - -A HA record specifies a hash-based address, such as an Ethereum wallet address. - -API ---- -### findResolver -This method requests that the resolver return the address and Node ID of the resolver responsible for the specified label. - -An ENS resolver must implement an API conforming to the following signature, under the standard [Contract ABI](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI): - -
function findResolver(bytes12 node, bytes32 label) returns (uint16 rcode, uint32 ttl, bytes12 rnode, address raddress);
- -Where: - - node - The 96-bit node ID from which to begin the query. By convention, root resolvers start their main tree at node 0. - - label - The sha3 hash of a domain label, as described in "Resolution Process". - - rcode - Response code, as defined in DNS. - - ttl - Duration in seconds that this record may be cached. - - rnode - The Node ID of the resolver. - - raddress - The address of the resolver. - -`ttl` specifies the maximum amount of time a record may be cached for. This is used only by local resolvers and DNS gateways. Contracts that need to resolve names may choose to ignore caching and fetch the record afresh each time the need it, if they expect to handle name resolutions infrequently compared to the expected TTL. - -### resolve -This method requests that the resolver return a name record of the specified record type. - -An ENS resolver must implement an API conforming to the following signature, under the standard [Contract ABI](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI): - -
function resolve(bytes12 node, bytes16 qtype, uint16 index) returns (uint16 rcode, bytes16 rtype, uint32 ttl, uint16 len, bytes32 data);
- -Where: - - node - The 96-bit node ID from which to begin the query. By convention, root resolvers start their main tree at node 0. - - qtype - The query type, a left-aligned zero-padded byte string, as specified by DNS and amended with the CHASH and RA types. - - index - Specifies the index into the array of results to return. Specifying an index that is out of bounds will result in a 0-length response. - - rcode - Response code, as defined in DNS. - - rtype - The DNS TYPE of the returned record. - - ttl - Duration in seconds that this record may be cached. - - len - Length of the returned result, see below. - - data - Result data. - -`qtype` specifies the query type of the query. Unlike DNS, which uses numerical query types, ENS uses the name of the type, such as 'A', 'CHASH', etc. Query types are encoded as ASCII and left aligned (stored in the most significant bits of the 32 byte field). - -`ttl` specifies the maximum amount of time a record may be cached for. This is used only by local resolvers and DNS gateways. Contracts that need to resolve names may choose to ignore caching and fetch the record afresh each time the need it, if they expect to handle name resolutions infrequently compared to the expected TTL. - -`index` permits iteration over multiple records. If a request is made with an index that is out of bounds, a response with a `len` of 0 is returned. Resolvers may return records in an arbitrary order, but the order MUST be consistent within a single block. - -If `len` is 32 or less, the complete record is returned in `data`. If `len` is greater than 32, the result is too large to fit in a bytes32, and `data` instead contains a unique identifier. To fetch the complete record, call `getExtended` (described below) with the identifier. Values with `len` less than 32 are left-aligned (most significant bytes; higher array indexes when treated as an array in Solidity). Since numeric values such as addresses are right-aligned in Solidity, these should be treated as having a length of 32 bytes, regardless of the original data length. - -### getExtended -When a record exceeds 32 bytes in length, an alternative mechanism is provided for fetching the result data, as described above in the description of `resolve`. - -If a resolver can ever return a result of length greater than 32 bytes, it MUST implement getExtended. Resolvers that limit their record size, or only implement record types of fixed length no longer than 32 bytes, need not provide this function. - -
function getExtended(bytes32 id) returns (bytes data);
- -Where: - - id - The unique record identifier returned by a previous call to `resolve`. - - data - The full contents of the requested extended record. - -If the id provided does not exist in the database, the resolver returns an empty byte string. - -Rationale -========= -Gas costs ---------- -Ethereum contracts operate under a very constrained VM, with substantial costs for allocating memory and copying data. This drove a number of tradeoffs designed to retain as much flexibility as possible, while eliminating overhead that would be unnecessary in common name resolution situations: - - `resolve` returns fixed-length records, with a separate API for fetching longer records. This avoids the need to dynamically allocate large buffers, when most common results (to A, CHASH, HA, etc records) will fit in a small fixed-length buffer. - - Name components are preparsed and hashed. This allows name parsing to be done once in common cases, at contract instantiation time, avoiding the high overhead of string manipulation in the EVM, and also permitting names of arbitrary length without the overhead of variable length types. - - DNS's distinction between 'answer records', 'authority records' and 'additional records' has been eliminated, in favor of returning a single record with each call, of whichever type is appropriate, to eliminate unnecessary overhead and repeated calls. - -Complexity reduction --------------------- -Most contracts and DApps have fairly straightforward needs for name resolution. However, past experience with DNS has shown that adding new functionality once widely deployed is difficult to impossible; the immutability of contracts in Ethereum may serve to make this even harder. Thus, we seek to find an acceptable tradeoff, with enough flexibility to allow more sophisticated uses and to provide for future expandability, while not unduly complicating simple use-cases. - -Several features are designed with this in mind. The `getExtended` function call is required only if a resolver may return records greater than 32 bytes in length. Since common record types, such as account/contract addresses and content hashes fit within this size, common resolver implementations may choose to simply not support longer records, reducing implementation complexity. Likewise, local resolvers that do not need to provide the facility to retrieve longer records may choose not to implement this functionality, returning an error if a record is too long. - -Finally, we expect local resolver implementations to mask complexity from the user. Common interfaces will include simple "lookup" functions that parse names into lists of hashes, and potentially cache records internally. Root resolvers may additionally decide to offer simple interfaces compatible with current practice. - -Elimination of DNS CLASS ------------------------- -In addition to TYPE, DNS also defines CLASS, which specifies the type of network the record is for. In practice, this is almost universally 'IN' (Internet). Since we expect this to always be the case for Ethereum-based resolvers, we have omitted CLASS from the nameservice definition. Gateways to the DNS system should assume this value is always 'IN'. - -Caching -------- -Because all resolvers exist as contracts in the blockchain, and all parts of the blockchain state are equally 'close' to each other and to the user, there is little point in supporting recursive lookup by resolvers and local caching for latency reasons. For this reason, and for others outlined above in 'Gas costs', ENS does not support recursive lookups. A `ttl` field is provided because limited caching is still useful in some cases: a contract that is called frequently and always needs to resolve a name may choose to cache it in local storage to reduce the overhead of calling the resolver contracts, and DApps and gateways existing outside the blockchain may find it useful to cache results locally. - -Implementation -============== -Authoritative Resolver ----------------------- -This contract implements a minimal authoritative resolver. The contract 'Resolver' implements the name resolution functionality, while 'OwnedRegistrar' adds functionality allowing the owner to set HA and CHASH records, following the ABI defined for existing global resolvers. It will happily act as authoritative resolver for any domain that's added to it, though naturally those domains will not resolve unless the relevant glue records are present in higher level resolvers. - -A more complete implementation of a leaf authoritative resolver would add support for unsupported features (long records, CNAME) and provide a more sophisticated API for managing the resolver's database, including setting TTLs, multiple records, and other types than HA and CHASH. - -``` -/** - * Basic authoritative resolver implementation. - * - * This resolver supports basic functionality required to conform to the - * ENS specification, but no advanced features. Not supported: - * - Data payloads of over 32 bytes (and thus, the getExtended() call). - */ -contract Resolver { - bytes32 constant TYPE_STAR = "*"; - - // Response codes. - uint16 constant RCODE_OK = 0; - uint16 constant RCODE_FORMAT_ERR = 1; - uint16 constant RCODE_SRVFAIL = 2; - uint16 constant RCODE_NXDOMAIN = 3; - uint16 constant RCODE_NOT_IMPLEMENTED = 4; - uint16 constant RCODE_REFUSED = 5; - - struct RR { - bytes16 rtype; - uint32 ttl; - uint16 len; - bytes32 data; - } - - struct ResolverAddress { - bytes12 nodeId; - address addr; - uint32 ttl; - } - - struct Node { - bool exists; - mapping (bytes32=>ResolverAddress) subnodes; - RR[] records; - } - - mapping (bytes12=>Node) nodes; - - function findResolver(bytes12 nodeId, bytes32 label) - returns (uint16 rcode, uint32 ttl, bytes12 rnode, address raddress) - { - var subnode = nodes[nodeId].subnodes[label]; - if (subnode.addr == address(0)) { - rcode = RCODE_NXDOMAIN; - return; - } - - ttl = subnode.ttl; - rnode = subnode.nodeId; - raddress = subnode.addr; - } - - function resolve(bytes12 nodeId, bytes32 qtype, uint16 index) - returns (uint16 rcode, bytes16 rtype, uint32 ttl, uint16 len, - bytes32 data) - { - var node = nodes[nodeId]; - if (!node.exists) { - rcode = RCODE_NXDOMAIN; - return; - } - - for(uint i = 0; i < node.records.length; i++) { - var record = node.records[i]; - if (qtype == TYPE_STAR || qtype == record.rtype) { - if (index > 0) { - index--; - continue; - } - - rtype = record.rtype; - ttl = record.ttl; - len = record.len; - data = record.data; - return; - } - } - - // Returns with rcode=RCODE_OK and len=0, indicates record not found. - return; - } -} - -/** - * Authoritative resolver that allows its owner to insert and update records. - */ -contract OwnedRegistrar is Resolver { - address _owner; - uint96 nextNodeId = 0; - - modifier owner_only { if (msg.sender != _owner) throw; _ } - - function OwnedRegistrar() { - _owner = msg.sender; - } - - function setOwner(address owner) owner_only { - _owner = owner; - } - - /** - * @dev Allocates a new node and returns its ID. - * @return nodeId The ID of the newly created (empty) node. - */ - function createNode() owner_only returns (bytes12 nodeId) { - nodeId = bytes12(nextNodeId++); - nodes[nodeId].exists = true; - } - - /** - * @dev Sets a subnode record on the specified node. - * @param nodeId The ID of the node to set a subnode on. - * @param label The label to set the subnode for. - * @param subnodeId The Node ID of the subnode to set. - * @param addr The address of the resolver for this subnode. - * @return An RCODE indicating the status of the operation. - */ - function setSubnode(bytes12 nodeId, bytes32 label, bytes12 subnodeId, - address addr, uint32 ttl) - owner_only returns (uint16 rcode) - { - var node = nodes[nodeId]; - if (!node.exists) - return RCODE_NXDOMAIN; - - node.subnodes[label].nodeId = subnodeId; - node.subnodes[label].addr = addr; - node.subnodes[label].ttl = ttl; - return RCODE_OK; - } - - /** - * @dev Convenience function to create and return a subnode. Equivalent to - * calling `createNode` followed by `setSubnode`. - * @param nodeId The ID of the node to create a subnode on. - * @param label The label to set the subnode for. - * @return An RCODE indicating the status of the operation, and the ID of - * the newly created subnode. - */ - function createSubnode(bytes12 nodeId, bytes32 label, uint32 ttl) - owner_only returns (uint16 rcode, bytes12 subnodeId) - { - subnodeId = createNode(); - rcode = setSubnode(nodeId, label, subnodeId, address(this), ttl); - } - - /** - * @dev Appends a new resource record to the specified node. - * @param nodeId The ID of the node to append an RR to. - * @param rtype The RR type. - * @param ttl The TTL of the provided RR. - * @param len The length of the provided RR. - * @param data The data to append. - * @return RCODE_OK on success, or RCODE_NXDOMAIN if the node does not exist. - */ - function appendRR(bytes12 nodeId, bytes16 rtype, uint32 ttl, uint16 len, - bytes32 data) - owner_only returns (uint16 rcode) - { - var node = nodes[nodeId]; - if (!node.exists) - return RCODE_NXDOMAIN; - - node.records.length += 1; - var record = node.records[node.records.length - 1]; - record.rtype = rtype; - record.ttl = ttl; - record.len = len; - record.data = data; - - return RCODE_OK; - } - - /** - * @dev Deletes the specified resource record. Ordering of remaining records - * is not guaranteed to be preserved unless deleting the last record. - * @param nodeId The ID of the node to delete an RR from. - * @param idx The index of the RR to delete. - * @return RCODE_OK on success, RCODE_NXDOMAIN if the node does not exist, - * RCODE_REFUSED if the index is out of bounds. - */ - function deleteRR(bytes12 nodeId, uint16 idx) - owner_only returns (uint16 rcode) - { - var node = nodes[nodeId]; - if (!node.exists) - return RCODE_NXDOMAIN; - - if (idx >= node.records.length) - return RCODE_REFUSED; - - if (idx != node.records.length - 1) { - node.records[idx] = node.records[node.records.length - 1]; - } - node.records.length--; - - return RCODE_OK; - } -} -``` - -Local Resolver Library ----------------------- -This library code implements a basic local resolver. It supports CNAME resolution, but not extended records or caching. - -``` -import 'github.com/arachnid/solidity-stringutils/StringUtils.sol'; - -contract Resolver { - function findResolver(bytes12 nodeId, bytes32 label) - returns (uint16 rcode, uint32 ttl, bytes12 rnode, address raddress); - function resolve(bytes12 nodeId, bytes32 qtype, uint16 index) - returns (uint16 rcode, bytes16 rtype, uint32 ttl, uint16 len, - bytes32 data); -} - -contract LocalResolver is StringUtils { - // Response codes. - uint8 constant RCODE_OK = 0; - uint8 constant RCODE_NXDOMAIN = 3; - - Resolver private root; - - function LocalResolver(address _root) { - root = Resolver(_root); - } - - function findResolver(string name) - returns (uint16 rcode, Resolver resolver, bytes12 nodeId) - { - resolver = root; - var lastIdx = int(bytes(name).length - 1); - while (lastIdx > 0) { - var idx = strrstr(name, ".", uint(lastIdx)) + 1; - var label = sha3_substring(name, uint(idx), uint(lastIdx - idx) + 1); - uint32 ttl; - address addr; - (rcode, ttl, nodeId, addr) = resolver.findResolver(nodeId, label); - if (rcode != RCODE_OK) - return; - resolver = Resolver(addr); - lastIdx = idx - 2; - } - } - - function resolveOne(string name, bytes16 qtype) - returns (uint16 rcode, bytes16 rtype, uint16 len, bytes32 data) - { - Resolver resolver; - bytes12 nodeId; - (rcode, resolver, nodeId) = findResolver(name); - - uint32 ttl; - (rcode, rtype, ttl, len, data) = resolver.resolve(nodeId, qtype, 0); - } - - /** - * Implements the legacy registrar addr() function. - */ - function addr(string name) returns (address) { - var (rcode, rtype, len, data) = resolveOne(name, "HA"); - return address(data); - } - - /** - * Implements the legacy registrar content() function. - */ - function content(string name) returns (address) { - var (rcode, rtype, len, data) = resolveOne(name, "CHASH"); - return address(data); - } -} -``` From 5e0c5f38bb6d8483200582ba3bd5e3fa44d4bfa9 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 1 Jun 2017 10:08:38 +0200 Subject: [PATCH 0134/1085] Clarify resetting the static flag. --- EIPS/static_call.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/static_call.md b/EIPS/static_call.md index fb36b9335eb5e..0331c1e05ec8c 100644 --- a/EIPS/static_call.md +++ b/EIPS/static_call.md @@ -28,7 +28,7 @@ Introduce a new `STATIC` flag to the virtual machine. This flag is set to `false Opcode: `0xfa`. -`STATICCALL` functions equivalently to a `CALL`, except it takes 6 arguments not including value, and calls the child with the `STATIC` flag set to `true`. +`STATICCALL` functions equivalently to a `CALL`, except it takes 6 arguments not including value, and calls the child with the `STATIC` flag set to `true` for the execution of the child. Once this call returns, the flag is reset to its value before the call. Any attempts to make state-changing operations inside an execution instance with `STATIC` set to `true` will instead throw an exception. These operations include `CREATE`, `CREATE2`, `LOG`, `SSTORE`, `SSTOREBYTES` and `SELFDESTRUCT`. They also include `CALL` and `DELEGATECALL` with a non-zero value. As an exception, `CALLCODE` is not considered state-changing, even with a non-zero value. From 5785324724757070a19c3a6995b73e9bf3eb7c53 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 1 Jun 2017 10:16:05 +0200 Subject: [PATCH 0135/1085] Clarify too long input. --- EIPS/ecopts.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/ecopts.md b/EIPS/ecopts.md index d4b70b84df879..57f1f05ebdcda 100644 --- a/EIPS/ecopts.md +++ b/EIPS/ecopts.md @@ -1,6 +1,6 @@ ## Preamble - EIP: + EIP: 213 Title: Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 Author: Christian Reitwiessner @@ -44,7 +44,7 @@ Field elements and scalars are encoded as 32 byte big-endian numbers. Curve poin Tuples of objects are encoded as their concatenation. -For both precompiled contracts, if the input is shorter than expected, it is assumed to be virtually padded with zeros at the end (i.e. compatible with the semantics of the `CALLDATALOAD` opcode). +For both precompiled contracts, if the input is shorter than expected, it is assumed to be virtually padded with zeros at the end (i.e. compatible with the semantics of the `CALLDATALOAD` opcode). If the input is longer than expected, surplus bytes at the end are ignored. The length of the returned data is always as specified (i.e. it is not "unpadded"). From 350c8b5a915f5d1db57a53998e567a3bc451174b Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 1 Jun 2017 10:20:31 +0200 Subject: [PATCH 0136/1085] Update external links. --- EIPS/ecopts.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/ecopts.md b/EIPS/ecopts.md index 57f1f05ebdcda..d9cebd8f8c3d9 100644 --- a/EIPS/ecopts.md +++ b/EIPS/ecopts.md @@ -93,12 +93,12 @@ Inputs to test: Implementation of these primitives are available here: - - [libsnark](https://github.com/scipr-lab/libsnark/blob/master/src/algebra/curves/alt_bn128/alt_bn128_g1.hpp) (C++) + - [libff](https://github.com/scipr-lab/libff/blob/master/src/algebra/curves/alt_bn128/alt_bn128_g1.cpp) (C++) - [bn](https://github.com/zcash/bn/blob/master/src/groups/mod.rs) (Rust) In both codebases, a specific group on the curve alt_bn128 is used and is called G1. - - [Python](https://github.com/ethereum/research/blob/master/zksnark/bn128_curve.py) - probably most self-contained and best readable. + - [Python](https://github.com/ethereum/research/blob/master/zksnark/py_pairing/py_pairing/bn128_curve.py) - probably most self-contained and best readable. ## Copyright From 28f1709777cbd99dc96dcdbbef8c532674bfbc86 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 6 Jun 2017 14:58:32 +0200 Subject: [PATCH 0137/1085] Fail on access beyond end. --- EIPS/returndatacopy.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/EIPS/returndatacopy.md b/EIPS/returndatacopy.md index 9689f459e8d69..11c80fba689a5 100644 --- a/EIPS/returndatacopy.md +++ b/EIPS/returndatacopy.md @@ -40,9 +40,7 @@ Gas costs: 2 (same as `CALLDATASIZE`) `RETURNDATACOPY`: `0x3e` -This opcode has similar semantics to `CALLDATACOPY`, but instead of copying data from the call data, it copies data from the return data buffer. If the return data buffer is accessed beyond its size, it is considered to be filled with zeros. - -ALTERNATIVE: If the return data is accessed beyond its size, results in failure. +This opcode has similar semantics to `CALLDATACOPY`, but instead of copying data from the call data, it copies data from the return data buffer. Furthermore, accessing the return data buffer beyond its size results in a failure, i.e. if `start + length` overflows or results in a value larger than `RETURNDATASIZE`, the current call stops in an out-of-gas condition. Gas costs: `3 + 3 * ceil(amount / 32)` (same as `CALLDATACOPY`) From aeaffcca26fa688f5015da7ce059c886e90ef374 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 6 Jun 2017 17:04:58 +0200 Subject: [PATCH 0138/1085] Clarified reading from the end. --- EIPS/returndatacopy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/returndatacopy.md b/EIPS/returndatacopy.md index 11c80fba689a5..1201df21e4954 100644 --- a/EIPS/returndatacopy.md +++ b/EIPS/returndatacopy.md @@ -40,7 +40,7 @@ Gas costs: 2 (same as `CALLDATASIZE`) `RETURNDATACOPY`: `0x3e` -This opcode has similar semantics to `CALLDATACOPY`, but instead of copying data from the call data, it copies data from the return data buffer. Furthermore, accessing the return data buffer beyond its size results in a failure, i.e. if `start + length` overflows or results in a value larger than `RETURNDATASIZE`, the current call stops in an out-of-gas condition. +This opcode has similar semantics to `CALLDATACOPY`, but instead of copying data from the call data, it copies data from the return data buffer. Furthermore, accessing the return data buffer beyond its size results in a failure, i.e. if `start + length` overflows or results in a value larger than `RETURNDATASIZE`, the current call stops in an out-of-gas condition. In particular, reading 0 bytes from the end of the buffer will read 0 bytes; reading 0 bytes from one-byte out of the buffer causes an exception. Gas costs: `3 + 3 * ceil(amount / 32)` (same as `CALLDATACOPY`) From 2a7e44538f9a12560a3bf48e2969ac0b9497877a Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 16 Jun 2017 16:59:56 +0200 Subject: [PATCH 0139/1085] Small fixes. --- EIPS/static_call.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/static_call.md b/EIPS/static_call.md index 0331c1e05ec8c..6de5ed7d6b093 100644 --- a/EIPS/static_call.md +++ b/EIPS/static_call.md @@ -24,13 +24,13 @@ This EIP adds a way to call other contracts and restrict what they can do in the ## Specification -Introduce a new `STATIC` flag to the virtual machine. This flag is set to `false` initially. Its value is always copied to sub-calls or sub-creates with an exception for the new opcode below. +Introduce a new `STATIC` flag to the virtual machine. This flag is set to `false` initially. Its value is always copied to sub-calls with an exception for the new opcode below. Opcode: `0xfa`. `STATICCALL` functions equivalently to a `CALL`, except it takes 6 arguments not including value, and calls the child with the `STATIC` flag set to `true` for the execution of the child. Once this call returns, the flag is reset to its value before the call. -Any attempts to make state-changing operations inside an execution instance with `STATIC` set to `true` will instead throw an exception. These operations include `CREATE`, `CREATE2`, `LOG`, `SSTORE`, `SSTOREBYTES` and `SELFDESTRUCT`. They also include `CALL` and `DELEGATECALL` with a non-zero value. As an exception, `CALLCODE` is not considered state-changing, even with a non-zero value. +Any attempts to make state-changing operations inside an execution instance with `STATIC` set to `true` will instead throw an exception. These operations include `CREATE`, `CREATE2`, `LOG1`, `LOG2`, `LOG3`, `LOG4`, `SSTORE`, and `SELFDESTRUCT`. They also include `CALL` with a non-zero value. As an exception, `CALLCODE` is not considered state-changing, even with a non-zero value. ## Rationale From 4d3d19ea7e7a98e2c916480c865bd0e384c9ca0e Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 16 Jun 2017 18:34:36 +0200 Subject: [PATCH 0140/1085] eip-615: BEGINDATA instruction finishes the analysis --- EIPS/eip-615.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-615.md b/EIPS/eip-615.md index cca829b0723ab..b78f1391ff2e4 100644 --- a/EIPS/eip-615.md +++ b/EIPS/eip-615.md @@ -298,7 +298,7 @@ The basic approach is to call `validate_subroutine(i, 0, 0)`, for _i_ equal to t if SP > 1024 return false - if instruction is STOP, RETURN, or SUICIDE + if instruction is STOP, RETURN, SUICIDE or BEGINDATA return true // violates single entry From 38521eb093042962d7af03936f4655b05cb65cab Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 16 Jun 2017 15:28:39 +0200 Subject: [PATCH 0141/1085] eip-165: when the first loop hits BEGINDATA, the second loop should still run --- EIPS/eip-615.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-615.md b/EIPS/eip-615.md index b78f1391ff2e4..8cf1a61081fe4 100644 --- a/EIPS/eip-615.md +++ b/EIPS/eip-615.md @@ -217,7 +217,7 @@ Validating that jumps are to valid addresses takes two sequential passes over th if instruction is invalid return false if instruction is BEGINDATA - return true + break if instruction is BEGINSUB is_sub[PC] = true current_sub = PC From f7ec295146cacdc1bdf17e6938b15c307c92592b Mon Sep 17 00:00:00 2001 From: cdetrio Date: Fri, 23 Jun 2017 13:16:55 +0200 Subject: [PATCH 0142/1085] rename eip-2.mediawiki to eip-2.md --- EIPS/{eip-2.mediawiki => eip-2.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename EIPS/{eip-2.mediawiki => eip-2.md} (100%) diff --git a/EIPS/eip-2.mediawiki b/EIPS/eip-2.md similarity index 100% rename from EIPS/eip-2.mediawiki rename to EIPS/eip-2.md From 5615bc52f904c339fbb4b6ce45d55343bde936b1 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Fri, 23 Jun 2017 13:27:01 +0200 Subject: [PATCH 0143/1085] use markdown format and fix broken links --- EIPS/eip-2.md | 66 ++++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/EIPS/eip-2.md b/EIPS/eip-2.md index 3ac2a3fc29290..d31f61d29c1fa 100644 --- a/EIPS/eip-2.md +++ b/EIPS/eip-2.md @@ -1,49 +1,51 @@ -
-  EIP: 2
-  Title: Homestead Hard-fork Changes
-  Author: Vitalik Buterin 
-  Status: Final
-  Type: Standard
-  Layer: Consensus (hard-fork)
-  Created: 2015-11-15
-
+``` +EIP: 2 +Title: Homestead Hard-fork Changes +Author: Vitalik Buterin +Status: Final +Type: Standard Track +Category: Core +Created: 2015-11-15 +``` -==Specification== +# Specification -If block.number >= HOMESTEAD_FORK_BLKNUM (e.g., 1.150.000 on livenet, 494.000 on Morden and 0 on future testnets), do the following: +If `block.number >= HOMESTEAD_FORK_BLKNUM` (e.g., 1.150.000 on livenet, 494.000 on Morden and 0 on future testnets), do the following: -# The gas cost ''for creating contracts via a transaction'' is increased from 21000 to 53000, ie. if you send a transaction and the to address is the empty string, the initial gas subtracted is 53000 plus the gas cost of the tx data, rather than 21000 as is currently the case. Contract creation from a contract using the CREATE opcode is unaffected. -# All transaction signatures whose s-value is greater than secp256k1n/2 are now considered invalid. The ECDSA recover precompiled contract remains unchanged and will keep accepting high s-values - this is useful if e.g. a contract recovers old Bitcoin signatures. -# If contract creation does not have enough gas to pay for the final gas fee for adding the contract code to the state, the contract creation fails (ie. goes out-of-gas) rather than leaving an empty contract. -# Change the difficulty adjustment algorithm from the current formula: block_diff = parent_diff + parent_diff // 2048 * (1 if block_timestamp - parent_timestamp < 13 else -1) + int(2**((block.number // 100000) - 2)) (where the + int(2**((block.number // 100000) - 2)) represents the exponential difficulty adjustment component) to block_diff = parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99) + int(2**((block.number // 100000) - 2)), where // is the integer division operator, eg. 6 // 2 = 3, 7 // 2 = 3, 8 // 2 = 4. The `minDifficulty` still defines the minimum difficulty allowed and no adjustment may take it below this. +1. The gas cost *for creating contracts via a transaction* is increased from 21000 to 53000, ie. if you send a transaction and the to address is the empty string, the initial gas subtracted is 53000 plus the gas cost of the tx data, rather than 21000 as is currently the case. Contract creation from a contract using the `CREATE` opcode is unaffected. +2. All transaction signatures whose s-value is greater than `secp256k1n/2` are now considered invalid. The ECDSA recover precompiled contract remains unchanged and will keep accepting high s-values - this is useful if e.g. a contract recovers old Bitcoin signatures. +3. If contract creation does not have enough gas to pay for the final gas fee for adding the contract code to the state, the contract creation fails (ie. goes out-of-gas) rather than leaving an empty contract. +4. Change the difficulty adjustment algorithm from the current formula: `block_diff = parent_diff + parent_diff // 2048 * (1 if block_timestamp - parent_timestamp < 13 else -1) + int(2**((block.number // 100000) - 2))` (where the ` + int(2**((block.number // 100000) - 2))` represents the exponential difficulty adjustment component) to `block_diff = parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99) + int(2**((block.number // 100000) - 2))`, where `//` is the integer division operator, eg. `6 // 2 = 3`, `7 // 2 = 3`, `8 // 2 = 4`. The `minDifficulty` still defines the minimum difficulty allowed and no adjustment may take it below this. -==Rationale== +# Rationale Currently, there is an excess incentive to create contracts via transactions, where the cost is 21000, rather than contracts, where the cost is 32000. Additionally, with the help of suicide refunds, it is currently possible to make a simple ether value transfer using only 11664 gas; the code for doing this is as follows: -> from ethereum import tester as t -> from ethereum import utils -> s = t.state() -> c = s.abi_contract('def init():\n suicide(0x47e25df8822538a8596b28c637896b4d143c351e)', endowment=10**15) -> s.block.get_receipts()[-1].gas_used +```python +from ethereum import tester as t +> from ethereum import utils +> s = t.state() +> c = s.abi_contract('def init():\n suicide(0x47e25df8822538a8596b28c637896b4d143c351e)', endowment=10**15) +> s.block.get_receipts()[-1].gas_used 11664 -> s.block.get_balance(utils.normalize_address(0x47e25df8822538a8596b28c637896b4d143c351e)) -1000000000000000 +> s.block.get_balance(utils.normalize_address(0x47e25df8822538a8596b28c637896b4d143c351e)) +1000000000000000 +``` This is not a particularly serious problem, but is nevertheless arguably a bug. -Allowing transactions with any s value with 0 < s < secp256k1n, as is currently the case, opens a transaction malleability concern, as one can take any transaction, flip the s value from s to secp256k1n - s, flip the v value (27 -> 28, 28 -> 27), and the resulting signature would still be valid. This is not a serious security flaw, especially since Ethereum uses addresses and not transaction hashes as the input to an ether value transfer or other transaction, but it nevertheless creates a UI inconvenience as an attacker can cause the transaction that gets confirmed in a block to have a different hash from the transaction that any user sends, interfering with user interfaces that use transaction hashes as tracking IDs. Preventing high s values removes this problem. +Allowing transactions with any s value with `0 < s < secp256k1n`, as is currently the case, opens a transaction malleability concern, as one can take any transaction, flip the s value from `s` to `secp256k1n - s`, flip the v value (`27 -> 28`, `28 -> 27`), and the resulting signature would still be valid. This is not a serious security flaw, especially since Ethereum uses addresses and not transaction hashes as the input to an ether value transfer or other transaction, but it nevertheless creates a UI inconvenience as an attacker can cause the transaction that gets confirmed in a block to have a different hash from the transaction that any user sends, interfering with user interfaces that use transaction hashes as tracking IDs. Preventing high s values removes this problem. -Making contract creation go out-of-gas if there is not enough gas to pay for the final gas fee has the benefits that (i) it creates a more intuitive "success or fail" distinction in the result of a contract creation process, rather than the current "success, fail, or empty contract" trichotomy, (ii) makes failures more easily detectable, as unless contract creation fully succeeds then no contract account will be created at all, and (iii) makes contract creation safer in the case where there is an endowment, as there is a guarantee that either the entire initiation process happens or the transaction fails and the endowment is refunded. +Making contract creation go out-of-gas if there is not enough gas to pay for the final gas fee has the benefits that (i) it creates a more intuitive "success or fail" distinction in the result of a contract creation process, rather than the current "success, fail, or empty contract" trichotomy, (ii) makes failures more easily detectable, as unless contract creation fully succeeds then no contract account will be created at all, and (iii) makes contract creation safer in the case where there is an endowment, as there is a guarantee that either the entire initiation process happens or the transaction fails and the endowment is refunded. -The difficulty adjustment change conclusively solves a problem that the Ethereum protocol saw two months ago where an excessive number of miners were mining blocks that contain a timestamp equal to parent_timestamp + 1; this skewed the block time distribution, and so the current block time algorithm, which targets a ''median'' of 13 seconds, continued to target the same median but the mean started increasing. If 51% of miners had started mining blocks in this way, the mean would have increased to infinity. The proposed new formula is roughly based on targeting the mean; one can prove that with the formula in use an average block time longer than 24 seconds is mathematically impossible in the long term. +The difficulty adjustment change conclusively solves a problem that the Ethereum protocol saw two months ago where an excessive number of miners were mining blocks that contain a timestamp equal to `parent_timestamp + 1`; this skewed the block time distribution, and so the current block time algorithm, which targets a *median* of 13 seconds, continued to target the same median but the mean started increasing. If 51% of miners had started mining blocks in this way, the mean would have increased to infinity. The proposed new formula is roughly based on targeting the mean; one can prove that with the formula in use an average block time longer than 24 seconds is mathematically impossible in the long term. -The use of (block_timestamp - parent_timestamp) // 10 as the main input variable rather than the time difference directly serves to maintain the coarse-grained nature of the algorithm, preventing an excessive incentive to set the timestamp difference to exactly 1 in order to create a block that has slightly higher difficulty and that will thus be guaranteed to beat out any possible forks. The cap of -99 simply serves to ensure that the difficulty does not fall extremely far if two blocks happen to be very far apart in time due to a client security bug or other black-swan issue. +The use of `(block_timestamp - parent_timestamp) // 10` as the main input variable rather than the time difference directly serves to maintain the coarse-grained nature of the algorithm, preventing an excessive incentive to set the timestamp difference to exactly 1 in order to create a block that has slightly higher difficulty and that will thus be guaranteed to beat out any possible forks. The cap of -99 simply serves to ensure that the difficulty does not fall extremely far if two blocks happen to be very far apart in time due to a client security bug or other black-swan issue. -==Implementation== +# Implementation This is implemented in Python here: -# https://github.com/ethereum/pyethereum/blob/develop/ethereum/processblock.py#L130 -# https://github.com/ethereum/pyethereum/blob/develop/ethereum/processblock.py#L129 -# https://github.com/ethereum/pyethereum/blob/develop/ethereum/processblock.py#L304 -# https://github.com/ethereum/pyethereum/blob/develop/ethereum/blocks.py#L42 +1. https://github.com/ethereum/pyethereum/blob/d117c8f3fd93359fc641fd850fa799436f7c43b5/ethereum/processblock.py#L130 +2. https://github.com/ethereum/pyethereum/blob/d117c8f3fd93359fc641fd850fa799436f7c43b5/ethereum/processblock.py#L129 +3. https://github.com/ethereum/pyethereum/blob/d117c8f3fd93359fc641fd850fa799436f7c43b5/ethereum/processblock.py#L304 +4. https://github.com/ethereum/pyethereum/blob/d117c8f3fd93359fc641fd850fa799436f7c43b5/ethereum/blocks.py#L42 From dbeebd780f2a13587de579f67c320a444081d075 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Fri, 23 Jun 2017 13:37:01 +0200 Subject: [PATCH 0144/1085] only core EIPs in Homestead hard fork --- EIPS/eip-draft_hfmeta_homestead.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/EIPS/eip-draft_hfmeta_homestead.md b/EIPS/eip-draft_hfmeta_homestead.md index 4aa33d4df908d..968155401b594 100644 --- a/EIPS/eip-draft_hfmeta_homestead.md +++ b/EIPS/eip-draft_hfmeta_homestead.md @@ -22,9 +22,7 @@ This specifies the changes included in the hard fork named Homestead. - Block >= 0 on future testnets - Included EIPs: - EIP 2 (Homestead Hard-fork Changes) - - EIP 6 (Renaming Suicide Opcode) - EIP 7 (DELEGATECALL) - - EIP 8 (devp2p Forward Compatibility Requirements for Homestead) ## Copyright From 0ab7d52abaaa7e8dcbf305acc448944fe539e1e2 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Fri, 23 Jun 2017 13:54:34 +0200 Subject: [PATCH 0145/1085] create files for eip-158 and 161 --- EIPS/eip-158.md | 28 ++++++++++++++++++++++++++++ EIPS/eip-161.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 EIPS/eip-158.md create mode 100644 EIPS/eip-161.md diff --git a/EIPS/eip-158.md b/EIPS/eip-158.md new file mode 100644 index 0000000000000..0fee2ffa34460 --- /dev/null +++ b/EIPS/eip-158.md @@ -0,0 +1,28 @@ +EDITOR NOTE: below is a copy of the EIP 158 https://github.com/ethereum/EIPs/issues/158#issue-183264659 raw text fetched on 2017-06-23. + +# Specification + +For all blocks where `block.number >= FORK_BLKNUM` (TBA): +1. In all cases where a state change is made to an account, and this state change results in the account state being saved with nonce = 0, balance = 0, code empty, storage empty (hereinafter "empty account"), the account is instead deleted. +2. If a address is "touched" and that address contains an empty account, then it is deleted. A "touch" is defined as any situation where if the account at the given address were nonexistent it would be created. +3. Whenever the EVM checks if an account exists, emptiness is treated as equivalent to nonexistence. Particularly, note that this implies that, once this change is enabled, there is no longer a meaningful difference between emptiness and nonexistence from the point of view of EVM execution. +4. Zero-value calls and zero-value suicides no longer consume the 25000 account creation gas cost in any circumstance + +The cases where a "touch" takes place can be enumerated as follows: +- Zero-value-bearing CALLs +- CREATEs (if the code that is ultimately saved is empty and there is no ether remaining in the account when it is saved) +- Zero-value-bearing SUICIDEs +- Transaction recipients +- Contracts created in contract creation transactions +- Miners receiving transaction fees (note the case where the gasprice is zero, and the account does not yet exist because it only receives the block/uncle/nephew rewards _after_ processing every transaction) +### Specification (1b) + +When the EVM checks for emptiness (for the purpose of possibly applying the 25000 gas cost), emptiness is defined by `is_empty(acct): return get_balance(acct) == 0 and get_code(acct) == "" and get_nonce(acct) == 0`; emptiness of storage does not matter. This simplifies client implementation because there is no need to add extra complexity to make caches enumerable in the correct way and does not significantly affect the intended result, as the cases where balance/code/nonce are empty but storage is nonempty where this change would lead to an extra 25000 gas being paid are pathological and have no real use value. +### Specification (1c) + +Do not implement point 2 above (ie. no new empty accounts can be created, but existing ones are not automatically destroyed unless their state is actually _changed_). Instead, during each block starting from (and including) N and ending when there are no null accounts left, select the 1000 null accounts that are left-most in order of sha3(address), and delete them (ordering by hash is necessary so as to allow the accounts to be easily found by iterating the tree). +# Rationale + +This removes a large number of empty accounts that have been put in the state at very low cost due to flaws in earlier versions of the Ethereum protocol, thereby greatly reducing state size and hence both reducing the hard disk load of a full client and reducing the time for a fast sync. Additionally, it simplifies the protocol in the long term, as once all "empty" objects are cleared out there is no longer any meaningful distinction between an account being empty and being nonexistent, and indeed one can simply view nonexistence as a compact representation of emptiness. + +Note that this proposal does introduce a **temporary** breaking of existing guarantees, in that by repeatedly zero-value-calling already existing empty accounts one can create a state change at a cost of 700 gas per account instead of the usual 5000 per gas minimum (with SUICIDE refunds this goes down further to 350 gas per account). Allowing such a large number of state writes per block will lead to heightened block processing times and increase uncle rates in the short term while the existing empty accounts are being cleared, and eventually once all empty accounts are cleared this issue will no longer exist. diff --git a/EIPS/eip-161.md b/EIPS/eip-161.md new file mode 100644 index 0000000000000..8d6e93db9ed71 --- /dev/null +++ b/EIPS/eip-161.md @@ -0,0 +1,43 @@ +EDITOR NOTE: below is a copy of the EIP 161 https://github.com/ethereum/EIPs/issues/161#issue-184805822 raw text fetched on 2017-06-23. + +# Specification + +a. Account creation transactions and the `CREATE` operation SHALL, prior to the execution of the initialisation code, **increment** the **nonce** over and above its normal starting value by **one** (for normal networks, this will be simply 1, however test-nets with non-zero default starting nonces will be different). + +b. Whereas `CALL` and `SUICIDE` would charge 25,000 gas when the destination is non-existent, now the charge SHALL **only** be levied if the operation transfers **more than zero value** and the destination account is _dead_. + +c. No account may _change state_ from non-existent to existent-but-_empty_. If an operation would do this, the account SHALL instead remain non-existent. + +d. _At the end of the transaction_, any account _touched_ by the execution of that transaction which is now _empty_ SHALL instead become non-existent (i.e. **deleted**). + +Where: + +An account is considered to be _touched_ when it is involved in any potentially _state-changing_ operation. This includes, but is not limited to, being the recipient of a **transfer of zero value**. + +An account is considered _empty_ when it has **no code** and **zero nonce** and **zero balance**. + +An account is considered _dead_ when either it is non-existent or it is _empty_. + +_At the end of the transaction_ is immediately following the execution of the suicide list, prior to the determination of the state trie root for receipt population. + +An account _changes state_ when: +- it is the target or refund of a `SUICIDE` operation for **zero or more** value; +- it is the source or destination of a `CALL` operation or message-call transaction transferring **zero or more** value; +- it is the source or newly-creation of a `CREATE` operation or contract-creation transaction endowing **zero or more** value; +- as the block author ("miner") it is recipient of block-rewards or transaction-fees of **zero or more**. + +## Notes + +In the present Ethereum protocol, it should be noted that very few state changes can ultimately result in accounts that are empty following the execution of the transaction. In fact there are only four contexts that current implementations need track: +- an empty account has zero value transferred to it through `CALL`; +- an empty account has zero value transferred to it through `SUICIDE`; +- an empty account has zero value transferred to it through a message-call transaction; +- an empty account has zero value transferred to it through a zero-gas-price fees transfer. + +# Rationale + +Same as #158 except that several edge cases are avoided since we do not break invariants: +- ~~that an account can go from having code and storage to not having code or storage mid-way through the execution of a transaction;~~ [corrected] +- that a newly created account cannot be deleted prior to being deployed. + +`CREATE` avoids zero in the nonce to avoid any suggestion of the oddity of `CREATE`d accounts being reaped half-way through their creation. From c032393cc0f716af07115fe0b89e1c5614d10a37 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Fri, 23 Jun 2017 13:58:23 +0200 Subject: [PATCH 0146/1085] add preambles for eip-158 and 161 --- EIPS/eip-158.md | 11 ++++++++++- EIPS/eip-161.md | 10 +++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-158.md b/EIPS/eip-158.md index 0fee2ffa34460..a0241b65c7a87 100644 --- a/EIPS/eip-158.md +++ b/EIPS/eip-158.md @@ -1,4 +1,13 @@ -EDITOR NOTE: below is a copy of the EIP 158 https://github.com/ethereum/EIPs/issues/158#issue-183264659 raw text fetched on 2017-06-23. +``` +EIP: 158 +Title: State clearing +Author: Vitalik Buterin +Type: Standard Track +Category: Core +Status: Superseded +Created: 2016-10-16 +Superseded-By: 161 +``` # Specification diff --git a/EIPS/eip-161.md b/EIPS/eip-161.md index 8d6e93db9ed71..c65eb37d4187a 100644 --- a/EIPS/eip-161.md +++ b/EIPS/eip-161.md @@ -1,4 +1,12 @@ -EDITOR NOTE: below is a copy of the EIP 161 https://github.com/ethereum/EIPs/issues/161#issue-184805822 raw text fetched on 2017-06-23. +``` +EIP: 161 +Title: State trie clearing (invariant-preserving alternative) +Author: Gavin Wood +Type: Standard Track +Category: Core +Status: Final +Created: 2016-10-24 +``` # Specification From 81b0dcb275dc9163e7f0c75bfce7e77c4d34a122 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Fri, 23 Jun 2017 14:48:49 +0200 Subject: [PATCH 0147/1085] add references for EIPs 158 and 161 --- EIPS/eip-158.md | 5 +++++ EIPS/eip-161.md | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/EIPS/eip-158.md b/EIPS/eip-158.md index a0241b65c7a87..46b945dc30758 100644 --- a/EIPS/eip-158.md +++ b/EIPS/eip-158.md @@ -35,3 +35,8 @@ Do not implement point 2 above (ie. no new empty accounts can be created, but ex This removes a large number of empty accounts that have been put in the state at very low cost due to flaws in earlier versions of the Ethereum protocol, thereby greatly reducing state size and hence both reducing the hard disk load of a full client and reducing the time for a fast sync. Additionally, it simplifies the protocol in the long term, as once all "empty" objects are cleared out there is no longer any meaningful distinction between an account being empty and being nonexistent, and indeed one can simply view nonexistence as a compact representation of emptiness. Note that this proposal does introduce a **temporary** breaking of existing guarantees, in that by repeatedly zero-value-calling already existing empty accounts one can create a state change at a cost of 700 gas per account instead of the usual 5000 per gas minimum (with SUICIDE refunds this goes down further to 350 gas per account). Allowing such a large number of state writes per block will lead to heightened block processing times and increase uncle rates in the short term while the existing empty accounts are being cleared, and eventually once all empty accounts are cleared this issue will no longer exist. + +# References + +1. EIP-158 issue and discussion: https://github.com/ethereum/EIPs/issues/158 +2. EIP-161 issue and discussion: https://github.com/ethereum/EIPs/issues/161 diff --git a/EIPS/eip-161.md b/EIPS/eip-161.md index c65eb37d4187a..e9364563ef2c9 100644 --- a/EIPS/eip-161.md +++ b/EIPS/eip-161.md @@ -49,3 +49,8 @@ Same as #158 except that several edge cases are avoided since we do not break in - that a newly created account cannot be deleted prior to being deployed. `CREATE` avoids zero in the nonce to avoid any suggestion of the oddity of `CREATE`d accounts being reaped half-way through their creation. + +# References + +1. EIP-158 issue and discussion: https://github.com/ethereum/EIPs/issues/158 +2. EIP-161 issue and discussion: https://github.com/ethereum/EIPs/issues/161 From 5458ef37352ed8ef5a4f5547d682f13d692b0262 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Fri, 23 Jun 2017 14:59:52 +0200 Subject: [PATCH 0148/1085] create file for EIP-170 --- EIPS/eip-170.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 EIPS/eip-170.md diff --git a/EIPS/eip-170.md b/EIPS/eip-170.md new file mode 100644 index 0000000000000..d77f78c44c76a --- /dev/null +++ b/EIPS/eip-170.md @@ -0,0 +1,11 @@ +EDITOR NOTE: below is a copy of the EIP 170 https://github.com/ethereum/EIPs/issues/170#issue-187221797 raw text fetched on 2017-06-23. + +### Specification + +If `block.number >= FORK_BLKNUM`, then if contract creation initialization returns data with length of **at least** 24000 bytes, contract creation fails. Equivalently, one could describe this change as saying that the contract initialization gas cost is changed from `200 * len(code)` to `200 * len(code) if len(code) < 24000 else 2**256 - 1`. + +### Rationale + +Currently, there remains one slight quadratic vulnerability in ethereum: when a contract is called, even though the call takes a constant amount of gas, the call can trigger O(n) cost in terms of reading the code from disk, preprocessing the code for VM execution, and also adding O(n) data to the Merkle proof for the block's proof-of-validity. At current gas levels, this is acceptable even if suboptimal. At the higher gas levels that could be triggered in the future, possibly very soon due to dynamic gas limit rules, this would become a greater concern - not nearly as serious as recent denial of service attacks, but still inconvenient especially for future light clients verifying proofs of validity or invalidity. The solution is to put a hard cap on the size of an object that can be saved to the blockchain, and do so non-disruptively by setting the cap at a value slightly higher than what is feasible with current gas limits (an pathological worst-case contract can be created with ~23200 bytes using 4.7 million gas, and a normally created contract can go up to ~18 kb). + +If this is to be added, it should be added as soon as possible, or at least before any periods of higher than 4.7 million gas usage allow potential attackers to create contracts larger than 24000 bytes. From 43c554bf1351674b371aba38cf49e0e7389ac71a Mon Sep 17 00:00:00 2001 From: cdetrio Date: Fri, 23 Jun 2017 15:02:54 +0200 Subject: [PATCH 0149/1085] add EIP-170 preamble and reference --- EIPS/eip-170.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-170.md b/EIPS/eip-170.md index d77f78c44c76a..1b3da2c77c114 100644 --- a/EIPS/eip-170.md +++ b/EIPS/eip-170.md @@ -1,4 +1,12 @@ -EDITOR NOTE: below is a copy of the EIP 170 https://github.com/ethereum/EIPs/issues/170#issue-187221797 raw text fetched on 2017-06-23. +``` +EIP: 170 +Title: Contract code size limit +Author: Vitalik Buterin +Type: Standard Track +Category: Core +Status: Draft +Created: 2016-11-04 +``` ### Specification @@ -9,3 +17,7 @@ If `block.number >= FORK_BLKNUM`, then if contract creation initialization retur Currently, there remains one slight quadratic vulnerability in ethereum: when a contract is called, even though the call takes a constant amount of gas, the call can trigger O(n) cost in terms of reading the code from disk, preprocessing the code for VM execution, and also adding O(n) data to the Merkle proof for the block's proof-of-validity. At current gas levels, this is acceptable even if suboptimal. At the higher gas levels that could be triggered in the future, possibly very soon due to dynamic gas limit rules, this would become a greater concern - not nearly as serious as recent denial of service attacks, but still inconvenient especially for future light clients verifying proofs of validity or invalidity. The solution is to put a hard cap on the size of an object that can be saved to the blockchain, and do so non-disruptively by setting the cap at a value slightly higher than what is feasible with current gas limits (an pathological worst-case contract can be created with ~23200 bytes using 4.7 million gas, and a normally created contract can go up to ~18 kb). If this is to be added, it should be added as soon as possible, or at least before any periods of higher than 4.7 million gas usage allow potential attackers to create contracts larger than 24000 bytes. + +### References + +1. EIP-170 issue and discussion: https://github.com/ethereum/EIPs/issues/170 From a448eb3c258cea215420f1d43f3a266d7073a3bf Mon Sep 17 00:00:00 2001 From: cdetrio Date: Fri, 23 Jun 2017 15:16:26 +0200 Subject: [PATCH 0150/1085] update EIP-170 spec to the finalized version --- EIPS/eip-170.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/EIPS/eip-170.md b/EIPS/eip-170.md index 1b3da2c77c114..2dcd7a5899754 100644 --- a/EIPS/eip-170.md +++ b/EIPS/eip-170.md @@ -4,20 +4,19 @@ Title: Contract code size limit Author: Vitalik Buterin Type: Standard Track Category: Core -Status: Draft +Status: Final Created: 2016-11-04 ``` ### Specification -If `block.number >= FORK_BLKNUM`, then if contract creation initialization returns data with length of **at least** 24000 bytes, contract creation fails. Equivalently, one could describe this change as saying that the contract initialization gas cost is changed from `200 * len(code)` to `200 * len(code) if len(code) < 24000 else 2**256 - 1`. +If `block.number >= FORK_BLKNUM`, then if contract creation initialization returns data with length of **more than** `0x6000` (`2**14 + 2**13`) bytes, contract creation fails with an out of gas error. ### Rationale -Currently, there remains one slight quadratic vulnerability in ethereum: when a contract is called, even though the call takes a constant amount of gas, the call can trigger O(n) cost in terms of reading the code from disk, preprocessing the code for VM execution, and also adding O(n) data to the Merkle proof for the block's proof-of-validity. At current gas levels, this is acceptable even if suboptimal. At the higher gas levels that could be triggered in the future, possibly very soon due to dynamic gas limit rules, this would become a greater concern - not nearly as serious as recent denial of service attacks, but still inconvenient especially for future light clients verifying proofs of validity or invalidity. The solution is to put a hard cap on the size of an object that can be saved to the blockchain, and do so non-disruptively by setting the cap at a value slightly higher than what is feasible with current gas limits (an pathological worst-case contract can be created with ~23200 bytes using 4.7 million gas, and a normally created contract can go up to ~18 kb). - -If this is to be added, it should be added as soon as possible, or at least before any periods of higher than 4.7 million gas usage allow potential attackers to create contracts larger than 24000 bytes. +Currently, there remains one slight quadratic vulnerability in ethereum: when a contract is called, even though the call takes a constant amount of gas, the call can trigger O(n) cost in terms of reading the code from disk, preprocessing the code for VM execution, and also adding O(n) data to the Merkle proof for the block's proof-of-validity. At current gas levels, this is acceptable even if suboptimal. At the higher gas levels that could be triggered in the future, possibly very soon due to dynamic gas limit rules, this would become a greater concern - not nearly as serious as recent denial of service attacks, but still inconvenient especially for future light clients verifying proofs of validity or invalidity. The solution is to put a hard cap on the size of an object that can be saved to the blockchain, and do so non-disruptively by setting the cap at a value slightly higher than what is feasible with current gas limits. ### References 1. EIP-170 issue and discussion: https://github.com/ethereum/EIPs/issues/170 +2. pyethereum implementation: https://github.com/ethereum/pyethereum/blob/5217294871283d8dc4fb3ca9d8a78c7d416490e8/ethereum/messages.py#L397 From a1df940f3855fd82859485dcd715cfacd5be0ee1 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Sat, 24 Jun 2017 12:13:19 +0200 Subject: [PATCH 0151/1085] create file for EIP-55 --- EIPS/eip-55.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 EIPS/eip-55.md diff --git a/EIPS/eip-55.md b/EIPS/eip-55.md new file mode 100644 index 0000000000000..05836d3590525 --- /dev/null +++ b/EIPS/eip-55.md @@ -0,0 +1,29 @@ +EDITOR NOTE: below is a copy of the EIP 55 https://github.com/ethereum/eips/issues/55#issue-126609688 raw text fetched on 2017-06-24. + +Code: + +``` python +def checksum_encode(addr): # Takes a 20-byte binary address as input + o = '' + v = utils.big_endian_to_int(utils.sha3(addr)) + for i, c in enumerate(addr.encode('hex')): + if c in '0123456789': + o += c + else: + o += c.upper() if (v & (2**(255 - i))) else c.lower() + return '0x'+o +``` + +In English, convert the address to hex, but if the ith digit is a letter (ie. it's one of `abcdef`) print it in uppercase if the ith bit of the hash of the address (in binary form) is 1 otherwise print it in lowercase. + +Benefits: +- Backwards compatible with many hex parsers that accept mixed case, allowing it to be easily introduced over time +- Keeps the length at 40 characters +- ~~The average address will have 60 check bits, and less than 1 in 1 million addresses will have less than 32 check bits; this is stronger performance than nearly all other check schemes. Note that the very tiny chance that a given address will have very few check bits is dwarfed by the chance in any scheme that a bad address will randomly pass a check~~ + +UPDATE: I was actually wrong in my math above. I forgot that the check bits are per-hex-character, not per-bit (facepalm). On average there will be 15 check bits per address, and the net probability that a randomly generated address if mistyped will accidentally pass a check is 0.0247%. This is a ~50x improvement over ICAP, but not as good as a 4-byte check code. + +Examples: +- `0xCd2a3d9f938e13Cd947eC05ABC7fe734df8DD826` (the "cow" address) +- `0x9Ca0e998dF92c5351cEcbBb6Dba82Ac2266f7e0C` +- `0xcB16D0E54450Cdd2368476E762B09D147972b637` From 75ba147f1d912606bf10b6df7188a65b8176101e Mon Sep 17 00:00:00 2001 From: cdetrio Date: Sat, 24 Jun 2017 12:16:06 +0200 Subject: [PATCH 0152/1085] add preamble for EIP-55 --- EIPS/eip-55.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-55.md b/EIPS/eip-55.md index 05836d3590525..01e18f332a879 100644 --- a/EIPS/eip-55.md +++ b/EIPS/eip-55.md @@ -1,4 +1,14 @@ -EDITOR NOTE: below is a copy of the EIP 55 https://github.com/ethereum/eips/issues/55#issue-126609688 raw text fetched on 2017-06-24. +``` +EIP: 55 +Title: Mixed-case checksum address encoding +Author: Vitalik Buterin +Type: Standard Track +Category: ERC +Status: Draft +Created: 2016-01-14 +``` + +# Specification Code: From 74e4ec3ec2f7d97f1c6dc3cdc56ecc9c04b6f58b Mon Sep 17 00:00:00 2001 From: cdetrio Date: Sat, 24 Jun 2017 12:44:46 +0200 Subject: [PATCH 0153/1085] use python example of the accepted EIP-55 spec --- EIPS/eip-55.md | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/EIPS/eip-55.md b/EIPS/eip-55.md index 01e18f332a879..fef1723e3439e 100644 --- a/EIPS/eip-55.md +++ b/EIPS/eip-55.md @@ -4,7 +4,7 @@ Title: Mixed-case checksum address encoding Author: Vitalik Buterin Type: Standard Track Category: ERC -Status: Draft +Status: Accepted Created: 2016-01-14 ``` @@ -13,27 +13,36 @@ Created: 2016-01-14 Code: ``` python +from ethereum import utils + def checksum_encode(addr): # Takes a 20-byte binary address as input o = '' - v = utils.big_endian_to_int(utils.sha3(addr)) - for i, c in enumerate(addr.encode('hex')): + v = utils.big_endian_to_int(utils.sha3(addr.hex())) + for i, c in enumerate(addr.hex()): if c in '0123456789': o += c else: - o += c.upper() if (v & (2**(255 - i))) else c.lower() + o += c.upper() if (v & (2**(255 - 4*i))) else c.lower() return '0x'+o + +def test(addrstr): + assert(addrstr == checksum_encode2(bytes.fromhex(addrstr[2:]))) + +test('0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed') +test('0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359') +test('0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB') +test('0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb') + ``` -In English, convert the address to hex, but if the ith digit is a letter (ie. it's one of `abcdef`) print it in uppercase if the ith bit of the hash of the address (in binary form) is 1 otherwise print it in lowercase. +In English, convert the address to hex, but if the `i`th digit is a letter (ie. it's one of `abcdef`) print it in uppercase if the `4*i`th bit of the hash of the address is 1 otherwise print it in lowercase. Benefits: - Backwards compatible with many hex parsers that accept mixed case, allowing it to be easily introduced over time - Keeps the length at 40 characters -- ~~The average address will have 60 check bits, and less than 1 in 1 million addresses will have less than 32 check bits; this is stronger performance than nearly all other check schemes. Note that the very tiny chance that a given address will have very few check bits is dwarfed by the chance in any scheme that a bad address will randomly pass a check~~ +- On average there will be 15 check bits per address, and the net probability that a randomly generated address if mistyped will accidentally pass a check is 0.0247%. This is a ~50x improvement over ICAP, but not as good as a 4-byte check code. -UPDATE: I was actually wrong in my math above. I forgot that the check bits are per-hex-character, not per-bit (facepalm). On average there will be 15 check bits per address, and the net probability that a randomly generated address if mistyped will accidentally pass a check is 0.0247%. This is a ~50x improvement over ICAP, but not as good as a 4-byte check code. +# References -Examples: -- `0xCd2a3d9f938e13Cd947eC05ABC7fe734df8DD826` (the "cow" address) -- `0x9Ca0e998dF92c5351cEcbBb6Dba82Ac2266f7e0C` -- `0xcB16D0E54450Cdd2368476E762B09D147972b637` +1. EIP 55 issue and discussion https://github.com/ethereum/eips/issues/55 +2. Python example by @Recmo https://github.com/ethereum/eips/issues/55#issuecomment-261521584 From 0b0d1ca375ccf0e3fdb6caf451d9a1d5adf9df44 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Sat, 24 Jun 2017 13:06:16 +0200 Subject: [PATCH 0154/1085] add EIP-55 javascript implementation --- EIPS/eip-55.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/EIPS/eip-55.md b/EIPS/eip-55.md index fef1723e3439e..b7749ad0dbb44 100644 --- a/EIPS/eip-55.md +++ b/EIPS/eip-55.md @@ -37,6 +37,43 @@ test('0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb') In English, convert the address to hex, but if the `i`th digit is a letter (ie. it's one of `abcdef`) print it in uppercase if the `4*i`th bit of the hash of the address is 1 otherwise print it in lowercase. +# Implementation + +In javascript: + +```js +const createKeccakHash = require('keccak') + +function toChecksumAddress (address) { + address = address.toLowerCase().replace('0x',''); + var hash = createKeccakHash('keccak256').update(address).digest('hex') + var ret = '0x' + + for (var i = 0; i < address.length; i++) { + if (parseInt(hash[i], 16) >= 8) { + ret += address[i].toUpperCase() + } else { + ret += address[i] + } + } + + return ret +} +``` + +``` +> toChecksumAddress('0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359') +'0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359' +``` + +Note that the input to the Keccak256 hash is the lowercase hexadecimal string (i.e. the hex address encoded as ASCII): + +``` + var hash = createKeccakHash('keccak256').update(Buffer.from(address.toLowerCase(), 'ascii')).digest() +``` + +# Rationale + Benefits: - Backwards compatible with many hex parsers that accept mixed case, allowing it to be easily introduced over time - Keeps the length at 40 characters @@ -46,3 +83,4 @@ Benefits: 1. EIP 55 issue and discussion https://github.com/ethereum/eips/issues/55 2. Python example by @Recmo https://github.com/ethereum/eips/issues/55#issuecomment-261521584 +3. Ethereumjs-util implementation https://github.com/ethereumjs/ethereumjs-util/blob/75f529458bc7dc84f85fd0446d0fac92d991c262/index.js#L452-L466 From 0bf49ff7121861f697308b05dbe6b73073fe852c Mon Sep 17 00:00:00 2001 From: cdetrio Date: Sat, 24 Jun 2017 13:09:51 +0200 Subject: [PATCH 0155/1085] add EIP-55 adoption table --- EIPS/eip-55.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/EIPS/eip-55.md b/EIPS/eip-55.md index b7749ad0dbb44..bc8ea794a05de 100644 --- a/EIPS/eip-55.md +++ b/EIPS/eip-55.md @@ -79,6 +79,27 @@ Benefits: - Keeps the length at 40 characters - On average there will be 15 check bits per address, and the net probability that a randomly generated address if mistyped will accidentally pass a check is 0.0247%. This is a ~50x improvement over ICAP, but not as good as a 4-byte check code. +# Adoption + +| Wallet | displays checksummed addresses | rejects invalid mixed-case | rejects too short | rejects too long | +|--------------------------|--------------------------------|----------------------------|-------------------|------------------| +| Jaxx 1.2.17 | No | Yes | Yes | Yes | +| MetaMask 3.7.8 | Yes | Yes | Yes | Yes | +| Mist 0.8.10 | Yes | Yes | Yes | Yes | +| MyEtherWallet v3.9.4 | Yes | Yes | Yes | Yes | +| Parity 1.6.6-beta (UI) | Yes | Yes | Yes | Yes | + +### Exchange support for mixed-case address checksums, as of 2017-05-27: + +| Exchange | displays checksummed deposit addresses | rejects invalid mixed-case | rejects too short | rejects too long | +|--------------|----------------------------------------|----------------------------|-------------------|------------------| +| Bitfinex | No | Yes | Yes | Yes | +| Coinbase | Yes | No | Yes | Yes | +| GDAX | Yes | Yes | Yes | Yes | +| Kraken | No | No | Yes | Yes | +| Poloniex | No | No | Yes | Yes | +| Shapeshift | No | No | Yes | Yes | + # References 1. EIP 55 issue and discussion https://github.com/ethereum/eips/issues/55 From 4b8732e18220106768749f3631d177560de6d6d2 Mon Sep 17 00:00:00 2001 From: Piper Merriam Date: Tue, 27 Jun 2017 16:53:43 -0600 Subject: [PATCH 0156/1085] Add reference to EIP-55 implementation in ethereum-utils library --- EIPS/eip-55.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-55.md b/EIPS/eip-55.md index bc8ea794a05de..fd432e1b206cb 100644 --- a/EIPS/eip-55.md +++ b/EIPS/eip-55.md @@ -104,4 +104,5 @@ Benefits: 1. EIP 55 issue and discussion https://github.com/ethereum/eips/issues/55 2. Python example by @Recmo https://github.com/ethereum/eips/issues/55#issuecomment-261521584 -3. Ethereumjs-util implementation https://github.com/ethereumjs/ethereumjs-util/blob/75f529458bc7dc84f85fd0446d0fac92d991c262/index.js#L452-L466 +3. Python implementation in [`ethereum-utils`](https://github.com/pipermerriam/ethereum-utils#to_checksum_addressvalue---text) +4. Ethereumjs-util implementation https://github.com/ethereumjs/ethereumjs-util/blob/75f529458bc7dc84f85fd0446d0fac92d991c262/index.js#L452-L466 From e394281ff84b25d98bc6713b85e4aca2c92aa692 Mon Sep 17 00:00:00 2001 From: John Manoogian III Date: Wed, 28 Jun 2017 20:36:42 -0700 Subject: [PATCH 0157/1085] fix link to EIP-2 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 84246b6254ee6..f2e38c991b83a 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP # Finalized EIPs (standards that have been adopted) | Number |Title | Author | Layer | Status | | ------------------------------------------------------- | ----------------------------------------------------------- | ----------------| ------------| --------| -| [2](EIPS/eip-2.mediawiki) | Homestead Hard-fork Changes | Vitalik Buterin | Core | Final | +| [2](EIPS/eip-2.md) | Homestead Hard-fork Changes | Vitalik Buterin | Core | Final | | [6](EIPS/eip-6.md) | Renaming Suicide Opcode | Hudson Jameson | Interface | Final | | [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Core | Final | | [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Networking | Final | From ff3716b9656156efad89ae4ceecec5538d2a2986 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Thu, 29 Jun 2017 16:39:10 -0400 Subject: [PATCH 0158/1085] clarify EIP-55 spec --- EIPS/eip-55.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-55.md b/EIPS/eip-55.md index fd432e1b206cb..468fb0c5d77df 100644 --- a/EIPS/eip-55.md +++ b/EIPS/eip-55.md @@ -35,7 +35,7 @@ test('0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb') ``` -In English, convert the address to hex, but if the `i`th digit is a letter (ie. it's one of `abcdef`) print it in uppercase if the `4*i`th bit of the hash of the address is 1 otherwise print it in lowercase. +In English, convert the address to hex, but if the `i`th digit is a letter (ie. it's one of `abcdef`) print it in uppercase if the `4*i`th bit of the hash of the lowercase hexadecimal address is 1 otherwise print it in lowercase. # Implementation From 378af99430be9fb57de201ec485c337f9d4d4dc3 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Fri, 30 Jun 2017 10:33:52 +0100 Subject: [PATCH 0159/1085] Create eip-draft-returndata.md --- EIPS/eip-draft-returndata.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 EIPS/eip-draft-returndata.md diff --git a/EIPS/eip-draft-returndata.md b/EIPS/eip-draft-returndata.md new file mode 100644 index 0000000000000..da1f128b2fb94 --- /dev/null +++ b/EIPS/eip-draft-returndata.md @@ -0,0 +1,35 @@ +## Preamble + + EIP: + Title: Embedding transaction return data in receipts + Author: Nick Johnson + Type: Standard Track + Category Core + Status: Draft + Created: 2017-06-30 + Requires: 140 + Replaces: 98 + + +## Abstract +This EIP replaces the intermediate state root field of the receipt with either the contract return data and status, or a hash of that value. + +## Motivation +With the introduction of the REVERT opcode in EIP140, it is no longer possible for users to assume that a transaction failed iff it consumed all gas. As a result, there is no clear mechanism for callers to determine whether a transaction succeeded and the state changes contained in it were applied. + +Full nodes can provide RPCs to get a transaction return status and value by replaying the transaction, but fast nodes can only do this for nodes after their pivot point, and light nodes cannot do this at all, making a non-consensus solution impractical. + +Instead, we propose to replace the intermediate state root, already obsoleted by EIP98, with either the return status (1 for success, 0 for failure) and any return/revert data, or the hash of the above. This both allows callers to determine success status, and remedies the previous omission of return data from the receipt. + +## Specification +Option 1: For blocks where block.number >= METROPOLIS_FORK_BLKNUM, the intermediate state root is replaced by `status + return_data`, where `status` is the 1 byte status code, with 0 indicating failure (due to any operation that can cause the transaction or top-level call to revert) and 1 indicating success, and `return_data` is the data returned from the `RETURN` or `REVERT` opcode of the top-level call, and where `+` indicates concatenation. + +Option 2: For blocks where block.number >= METROPOLIS_FORK_BLKNUM, the intermediate state root is replaced by `keccak256(status + return_data)`, where `status`, `return_data` and `+` have meanings as described in option 1. Additionally, new wire protocol messages are added for `GetReturnData` and `ReturnData`, permitting nodes to fetch the status and return data for transactions contained in specified blocks. + +## Rationale +Option 1 minimises additional complexity in the wire protocol and client synchronisation implementations by embedding all necessary data in the receipt itself, but may complicate the transition process by changing the relevant field from a fixed length hash to a variable length field. The implications of a transaction sender being able to add arbitrary length data to transaction receipts also need close examination from the perspective of gas costing. + +Option 2 reduces overhead from data type changes, but introduces extra wire protocol complexity, and another record type for fast and light nodes to synchronise or fetch. + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From efd2333c806b278b29f483bd5d41d9d7060e37a6 Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 30 Jun 2017 15:21:00 +0200 Subject: [PATCH 0160/1085] Some clarifications. --- EIPS/eip-140.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-140.md b/EIPS/eip-140.md index af5b9fcb764b1..e6c0f50f04767 100644 --- a/EIPS/eip-140.md +++ b/EIPS/eip-140.md @@ -22,11 +22,19 @@ Currently this is not possible. There are two practical ways to revert a transac ## Specification -The `REVERT` instruction is introduced at `0xfd`. Execution is aborted, considered as failed, and state changes are rolled back. +The `REVERT` instruction is introduced at `0xfd`. It expects two stack items, the top item is the `memory_offset` followed by `memory_length`. It does not return anything because it stops execution. -It expects two stack items, the top item is the `memory_offset` followed by `memory_length`. Both of these can equal to zero. The cost of the `REVERT` instruction equals to that of the `RETURN` instruction. +The semantics of `REVERT` with respect to memory and memory cost are identical to those of `RETURN`. The sequence of bytes given by `memory_offset` and `memory_length` is called "error message" in the following. -In case there is not enough gas left to cover the cost of `REVERT` or there is a stack underflow, the effect of the `REVERT` instruction will equal to that of a regular out of gas exception. +The effect of `REVERT` is that execution is aborted, considered as failed, and state changes are rolled back. The error message will be available to the caller in the returndata buffer and will also be copied to the output area, i.e. it is handled in the same way as the regular return data is handled. + +The cost of the `REVERT` instruction equals to that of the `RETURN` instruction, i.e. the rollback itself does not consume all gas, the contract only has to pay for memory. + +In case there is not enough gas left to cover the cost of `REVERT` or there is a stack underflow, the effect of the `REVERT` instruction will equal to that of a regular out of gas exception, i.e. it will consume all gas. + +In the same way as all other failures, the calling opcode returns `1` on the stack following a `REVERT` opcode in the callee. + +In case `REVERT` is used in the context of a `CREATE` or `CREATE2` call, no code is deployed, `1` is put on the stack and the error message is available in the returndata buffer. The content of the optionally provided memory section is not defined by this EIP, but is a candidate for another Informational EIP. From 2d2d028c3cee5f2fd7a0b36d0b5eaadef66eebb4 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 3 Jul 2017 18:30:31 +0200 Subject: [PATCH 0161/1085] Clarify value argument. --- EIPS/static_call.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/static_call.md b/EIPS/static_call.md index 6de5ed7d6b093..5e0b79af90576 100644 --- a/EIPS/static_call.md +++ b/EIPS/static_call.md @@ -28,7 +28,7 @@ Introduce a new `STATIC` flag to the virtual machine. This flag is set to `false Opcode: `0xfa`. -`STATICCALL` functions equivalently to a `CALL`, except it takes 6 arguments not including value, and calls the child with the `STATIC` flag set to `true` for the execution of the child. Once this call returns, the flag is reset to its value before the call. +`STATICCALL` functions equivalently to a `CALL`, except it takes only 6 arguments (the "value" argument is not included and taken to be zero), and calls the child with the `STATIC` flag set to `true` for the execution of the child. Once this call returns, the flag is reset to its value before the call. Any attempts to make state-changing operations inside an execution instance with `STATIC` set to `true` will instead throw an exception. These operations include `CREATE`, `CREATE2`, `LOG1`, `LOG2`, `LOG3`, `LOG4`, `SSTORE`, and `SELFDESTRUCT`. They also include `CALL` with a non-zero value. As an exception, `CALLCODE` is not considered state-changing, even with a non-zero value. From e5ca9196720c2a52134ce922ba80638e40ad5614 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 3 Jul 2017 21:31:23 +0100 Subject: [PATCH 0162/1085] Use floor and not udiv/sdiv --- EIPS/eip-145.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-145.md b/EIPS/eip-145.md index 91bf3232120e7..cd1bf8c19d3a6 100644 --- a/EIPS/eip-145.md +++ b/EIPS/eip-145.md @@ -42,7 +42,7 @@ Notes: The `SHR` instruction (logical shift right) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the first popped value `arg1` shifted to the right by the number of bits in the second popped value `arg2` with zero fill. The result is equal to ``` -arg1 udiv 2^arg2 +floor(arg1 / 2^arg2) ``` Notes: @@ -54,7 +54,7 @@ Notes: The `SAR` instruction (arithmetic shift right) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the first popped value `arg1` shifted to the right by the number of bits in the second popped value `arg2` with sign extension. The result is equal to ``` -arg1 sdiv 2^arg2 +floor(arg1 / 2^arg2) ``` Notes: From 4218665af978444201d685c8fef23a360500befd Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 3 Jul 2017 21:35:40 +0100 Subject: [PATCH 0163/1085] Explain sign of arg1/arg2 --- EIPS/eip-145.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/EIPS/eip-145.md b/EIPS/eip-145.md index cd1bf8c19d3a6..95c8481671881 100644 --- a/EIPS/eip-145.md +++ b/EIPS/eip-145.md @@ -34,6 +34,7 @@ The `SHL` instruction (shift left) pops 2 values from the stack, `arg1` and `arg ``` Notes: +- The value (`arg1`) is interpreted as an unsigned number. - The shift amount (`arg2`) is interpreted as an unsigned number. - If the shift amount (`arg2`) is greater or equal 256 the result is 0. @@ -46,6 +47,7 @@ floor(arg1 / 2^arg2) ``` Notes: +- The value (`arg1`) is interpreted as an unsigned number. - The shift amount (`arg2`) is interpreted as an unsigned number. - If the shift amount (`arg2`) is greater or equal 256 the result is 0. @@ -58,6 +60,7 @@ floor(arg1 / 2^arg2) ``` Notes: +- The value (`arg1`) is interpreted as a signed number. - The shift amount (`arg2`) is interpreted as an unsigned number. - If the shift amount (`arg2`) is greater or equal 256 the result is 0 if `arg1` is non-negative or -1 if `arg1` is negative. From fabc86434da2cafa274b877b23296435675483c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Katona?= Date: Tue, 4 Jul 2017 23:06:52 +0200 Subject: [PATCH 0164/1085] * add Etherwall 2.0.1 to supported list --- EIPS/eip-55.md | 1 + 1 file changed, 1 insertion(+) diff --git a/EIPS/eip-55.md b/EIPS/eip-55.md index 468fb0c5d77df..d7f0369ca4010 100644 --- a/EIPS/eip-55.md +++ b/EIPS/eip-55.md @@ -83,6 +83,7 @@ Benefits: | Wallet | displays checksummed addresses | rejects invalid mixed-case | rejects too short | rejects too long | |--------------------------|--------------------------------|----------------------------|-------------------|------------------| +| Etherwall 2.0.1 | Yes | Yes | Yes | Yes | | Jaxx 1.2.17 | No | Yes | Yes | Yes | | MetaMask 3.7.8 | Yes | Yes | Yes | Yes | | Mist 0.8.10 | Yes | Yes | Yes | Yes | From 62f3052774a1c1745805194ff3e43cd636f2d9bb Mon Sep 17 00:00:00 2001 From: maurelian Date: Thu, 6 Jul 2017 11:37:58 -0400 Subject: [PATCH 0165/1085] Revert to more closely describe implementation As implemented: https://github.com/ethereum/ens/blob/mainnet/contracts/HashRegistrarSimplified.sol#L379 --- EIPS/eip-162.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-162.md b/EIPS/eip-162.md index a69ee232b17f3..e0d46e9580bfc 100644 --- a/EIPS/eip-162.md +++ b/EIPS/eip-162.md @@ -121,7 +121,7 @@ The following table outlines what portion of the balance held in a deed contract | --- | --- | --- | | A valid non-winning bid is revealed. | Bidder | 99.5% | | A bid submitted after the auction period is revealed. | Bidder | 99.5% | -| A bid is revealed after the reveal period. 1 | Bidder | 0.5% | +| An otherwise valid bid is revealed on an owned name. 1 | Bidder | 0.5% | | An expired sealed bid is cancelled. 2 | Canceler | 0.5% | | A registered hash is reported as invalid. 3 | Reporter | 50% | | A registered hash is reported as invalid. 3 | Owner | 50% | From fc748cce51b8496141c87549cd69b1cba0bc1bc6 Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Tue, 11 Jul 2017 15:58:46 +0200 Subject: [PATCH 0166/1085] Add template for EIP #649 --- EIPS/eip-649.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 EIPS/eip-649.md diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md new file mode 100644 index 0000000000000..3ab783216dd8c --- /dev/null +++ b/EIPS/eip-649.md @@ -0,0 +1,43 @@ +This is the suggested template for new EIPs. + +Note that an EIP number will be assigned by an editor. When opening a pull request to submit your EIP, please use an abbreviated title in the filename, `eip-draft_title_abbrev.md`. + +## Preamble + + EIP: + Title: + Author: + Type: + Category (*only required for Standard Track): + Status: Draft + Created: + Requires (*optional): + Replaces (*optional): + + +## Simple Summary +"If you can't explain it simply, you don't understand it well enough." Provide a simplified and layman-accessible explanation of the EIP. + +## Abstract +A short (~200 word) description of the technical issue being addressed. + +## Motivation +The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright. + +## Specification +The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (cpp-ethereum, go-ethereum, parity, ethereumj, ethereumjs, ...). + +## Rationale +The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion. + +## Backwards Compatibility +All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright. + +## Test Cases +Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable. + +## Implementation +The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details. + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 6aa9951f247cec4c28cbfb13b6d736c6bf0d1f9d Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Tue, 11 Jul 2017 16:24:50 +0200 Subject: [PATCH 0167/1085] Update EIP #649 --- EIPS/eip-649.md | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index 3ab783216dd8c..3499d19da1c99 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -1,43 +1,40 @@ -This is the suggested template for new EIPs. - -Note that an EIP number will be assigned by an editor. When opening a pull request to submit your EIP, please use an abbreviated title in the filename, `eip-draft_title_abbrev.md`. - ## Preamble - EIP: - Title: - Author: - Type: - Category (*only required for Standard Track): + EIP: 649 ? 669 + Title: Metropolis Difficulty Bomb Delay + Authors: Afri Schoedon (Champion), Vitalik Buterin (Specification) + Type: Standard Track + Category: Core Status: Draft - Created: - Requires (*optional): - Replaces (*optional): - + Created: 2017-06-21 ## Simple Summary -"If you can't explain it simply, you don't understand it well enough." Provide a simplified and layman-accessible explanation of the EIP. +The average block times are increasing due to the difficulty bomb (also as known as the "ice age") slowly accelerating. This EIP proposes to delay the difficulty bomb for approximately one and a half year. ## Abstract -A short (~200 word) description of the technical issue being addressed. +After `METROPOLIS_FORK_BLKNUM` the client will simply calculate the difficulty based on a fake block number suggesting the client that the difficulty bomb is adjusting around 3 million blocks later than previously specified with the Homestead fork. ## Motivation -The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright. +The Casper development and switch to Proof-of-Stake is delayed, the Proof-of-Work should be feasible for miners and create new blocks every 15 seconds on average for another 1.4 years. ## Specification -The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (cpp-ethereum, go-ethereum, parity, ethereumj, ethereumjs, ...). +For the purposes of `calc_difficulty`, we simply replace the use of `block.number`, as used in the exponential ice age component, with the formula: + + fake_block_number = block.number - 3000000 if block.number >= METROPOLIS_FORK_BLKNUM else block.number ## Rationale -The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion. +This will delay the ice age by 42 million seconds ~= 1.4 years, so we would be back at 30 second block times at the end of 2018. An alternate proposal was that we add special rules to the difficulty calculation to effectively _pause_ the difficulty between different blocks. That would lead to similar results. + +This was previously discussed at All Core Devs Meeting [#09](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%209.md#metropolis-timing-and-roadmap-discussion), [#12](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2012.md#5-metropolis-update), [#13](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2013.md#3-eip-186-reduce-eth-issuance-before-proof-of-stake-hudson), and [#14](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2014.md#1-eip-186-reduce-eth-issuance-before-proof-of-stake-core-devs). Consensus on the specification was achieved in All Core Devs Meeting [#19](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2019.md) and specification drafted in EIP issue [#649](https://github.com/ethereum/EIPs/issues/649). ## Backwards Compatibility -All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright. +This EIP is not forward compatible and introduces backwards incompatibilities in the difficulty calculation. Therefore, it should be included in a scheduled hardfork at a certain block number. It's suggested to include this EIP in the Metropolis fork. ## Test Cases -Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable. +No test cases exist yet. But will be easy to set up based on the rules specified above. ## Implementation -The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details. +None existing client implementation exists yet. ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 33fc59db74ef6dd8c0e6da51c14021a3bad593f7 Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Tue, 11 Jul 2017 16:26:54 +0200 Subject: [PATCH 0168/1085] EIP Number for #649 --- EIPS/eip-649.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index 3499d19da1c99..70dd2e66201b5 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -1,6 +1,6 @@ ## Preamble - EIP: 649 ? 669 + EIP: 649 Title: Metropolis Difficulty Bomb Delay Authors: Afri Schoedon (Champion), Vitalik Buterin (Specification) Type: Standard Track From 327c81c5816c0210aecaa71f0aa574ecba098425 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Fri, 14 Jul 2017 12:23:58 +0100 Subject: [PATCH 0169/1085] Update eip-draft-returndata.md --- EIPS/eip-draft-returndata.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/EIPS/eip-draft-returndata.md b/EIPS/eip-draft-returndata.md index da1f128b2fb94..5377ba1bd754f 100644 --- a/EIPS/eip-draft-returndata.md +++ b/EIPS/eip-draft-returndata.md @@ -22,14 +22,10 @@ Full nodes can provide RPCs to get a transaction return status and value by repl Instead, we propose to replace the intermediate state root, already obsoleted by EIP98, with either the return status (1 for success, 0 for failure) and any return/revert data, or the hash of the above. This both allows callers to determine success status, and remedies the previous omission of return data from the receipt. ## Specification -Option 1: For blocks where block.number >= METROPOLIS_FORK_BLKNUM, the intermediate state root is replaced by `status + return_data`, where `status` is the 1 byte status code, with 0 indicating failure (due to any operation that can cause the transaction or top-level call to revert) and 1 indicating success, and `return_data` is the data returned from the `RETURN` or `REVERT` opcode of the top-level call, and where `+` indicates concatenation. - -Option 2: For blocks where block.number >= METROPOLIS_FORK_BLKNUM, the intermediate state root is replaced by `keccak256(status + return_data)`, where `status`, `return_data` and `+` have meanings as described in option 1. Additionally, new wire protocol messages are added for `GetReturnData` and `ReturnData`, permitting nodes to fetch the status and return data for transactions contained in specified blocks. +For blocks where block.number >= METROPOLIS_FORK_BLKNUM, the intermediate state root is replaced by a status code, a single byte with 0 indicating failure (due to any operation that can cause the transaction or top-level call to revert) and 1 indicating success. ## Rationale -Option 1 minimises additional complexity in the wire protocol and client synchronisation implementations by embedding all necessary data in the receipt itself, but may complicate the transition process by changing the relevant field from a fixed length hash to a variable length field. The implications of a transaction sender being able to add arbitrary length data to transaction receipts also need close examination from the perspective of gas costing. - -Option 2 reduces overhead from data type changes, but introduces extra wire protocol complexity, and another record type for fast and light nodes to synchronise or fetch. +This constitutes a minimal possible change that permits fetching the success/failure state of transactions, preserving existing capabilities with minimum disruption or additional work for Metropolis. ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 6933badd32efc16e6ab7c7b90ca67bba54496eee Mon Sep 17 00:00:00 2001 From: cdetrio Date: Fri, 14 Jul 2017 11:04:02 -0400 Subject: [PATCH 0170/1085] add links to Homestead EIPs --- EIPS/eip-draft_hfmeta_homestead.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-draft_hfmeta_homestead.md b/EIPS/eip-draft_hfmeta_homestead.md index 968155401b594..1078f5e0e28e6 100644 --- a/EIPS/eip-draft_hfmeta_homestead.md +++ b/EIPS/eip-draft_hfmeta_homestead.md @@ -7,7 +7,7 @@ Category: Core Status: Final Created: 23/04/2017 - Requires: 2, 6, 7, 8 + Requires: 2, 7 ## Abstract @@ -21,8 +21,8 @@ This specifies the changes included in the hard fork named Homestead. - Block >= 494,000 on Morden - Block >= 0 on future testnets - Included EIPs: - - EIP 2 (Homestead Hard-fork Changes) - - EIP 7 (DELEGATECALL) + - [EIP 2](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md) (Homestead Hard-fork Changes) + - [EIP 7](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-8.md) (DELEGATECALL) ## Copyright From 93cf078d7f93128567b56af6de17d9ec87d07dae Mon Sep 17 00:00:00 2001 From: cdetrio Date: Fri, 14 Jul 2017 11:45:29 -0400 Subject: [PATCH 0171/1085] assign no. 606 to Homestead meta-EIP --- EIPS/{eip-draft_hfmeta_homestead.md => eip-606.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename EIPS/{eip-draft_hfmeta_homestead.md => eip-606.md} (96%) diff --git a/EIPS/eip-draft_hfmeta_homestead.md b/EIPS/eip-606.md similarity index 96% rename from EIPS/eip-draft_hfmeta_homestead.md rename to EIPS/eip-606.md index 1078f5e0e28e6..04d9af3a3ce22 100644 --- a/EIPS/eip-draft_hfmeta_homestead.md +++ b/EIPS/eip-606.md @@ -1,6 +1,6 @@ ## Preamble - EIP: + EIP: 606 Title: Hardfork Meta: Homestead Author: Alex Beregszaszi Type: Standard Track From 1328f53fcdcd7eb0acf7fdad39733463922ab5ef Mon Sep 17 00:00:00 2001 From: cdetrio Date: Fri, 14 Jul 2017 11:57:32 -0400 Subject: [PATCH 0172/1085] type and date in preamble --- EIPS/eip-606.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-606.md b/EIPS/eip-606.md index 04d9af3a3ce22..d0ccc71145e44 100644 --- a/EIPS/eip-606.md +++ b/EIPS/eip-606.md @@ -3,10 +3,9 @@ EIP: 606 Title: Hardfork Meta: Homestead Author: Alex Beregszaszi - Type: Standard Track - Category: Core + Type: Meta Status: Final - Created: 23/04/2017 + Created: 2017-04-23 Requires: 2, 7 ## Abstract From ff9e91312dddb72aee8ec9a97853d7e9874c27f2 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 17 Jul 2017 16:25:58 +0200 Subject: [PATCH 0173/1085] Add EIP-658 to the list of accepted EIPs --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f2e38c991b83a..1659c7c4b84d9 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [198](https://github.com/ethereum/EIPs/pull/198) | Precompiled contract for bigint modular exponentiation | Vitalik Buterin | Core | Accepted | | [211](https://github.com/ethereum/EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner| Core | Accepted | | [214](https://github.com/ethereum/EIPs/pull/214) | New opcode STATICCALL | Buterin, Reitwiessner | Core | Accepted | +| [658](https://github.com/ethereum/EIPs/pull/658) | Embedding transaction return data in receipts | Nick Johnson | Core | Accepted | # Finalized EIPs (standards that have been adopted) From cd33bd6ebd784a13dc8da1f08325e300cf858d69 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Mon, 17 Jul 2017 11:21:12 -0400 Subject: [PATCH 0174/1085] move EIP 86 to deferred table --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1659c7c4b84d9..030fe459a7d4b 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,6 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP # Accepted EIPs (planned for adoption) | Number |Title | Author | Layer | Status | | ------------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ------------| ----------| -| [86](https://github.com/ethereum/EIPs/pull/208) | Abstraction of transaction origin and signature | Vitalik Buterin | Core | Accepted | | [96](https://github.com/ethereum/EIPs/pull/210) | Blockhash refactoring | Vitalik Buterin | Core | Accepted | | [98](https://github.com/ethereum/EIPs/pull/98) | Removal of intermediate state roots from receipts | Vitalik Buterin | Core | Accepted | | [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Core | Accepted | @@ -31,6 +30,10 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [214](https://github.com/ethereum/EIPs/pull/214) | New opcode STATICCALL | Buterin, Reitwiessner | Core | Accepted | | [658](https://github.com/ethereum/EIPs/pull/658) | Embedding transaction return data in receipts | Nick Johnson | Core | Accepted | +# Deferred EIPs (adoption postponed) +| Number |Title | Author | Layer | Status | +| ------------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ------------| ----------| +| [86](https://github.com/ethereum/EIPs/pull/208) | Abstraction of transaction origin and signature | Vitalik Buterin | Core | Deferred | # Finalized EIPs (standards that have been adopted) | Number |Title | Author | Layer | Status | From 9dd6355ffaeab46262f242e6b2f7fb2fca31f1a2 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Tue, 27 Jun 2017 13:07:07 +0200 Subject: [PATCH 0175/1085] create file for EIP-160 --- EIPS/eip-160.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 EIPS/eip-160.md diff --git a/EIPS/eip-160.md b/EIPS/eip-160.md new file mode 100644 index 0000000000000..6fd18fab832fb --- /dev/null +++ b/EIPS/eip-160.md @@ -0,0 +1,8 @@ +EDITOR NOTE: below is a copy of the EIP 160 https://github.com/ethereum/EIPs/issues/160#issue-184230277 raw text fetched on 2017-07-17. + +### Specification + +If `block.number >= FORK_BLKNUM`, increase the gas cost of EXP from 10 + 10 per byte in the exponent to 10 + 50 per byte in the exponent. +### Rationale + +Benchmarks suggest that EXP is currently underpriced by a factor of about 4-8. From 80edeaa5c3db34bce4b7fb797e0c7dfd60fbc538 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Mon, 17 Jul 2017 11:02:44 -0400 Subject: [PATCH 0176/1085] add eip-160 preamble and references --- EIPS/eip-160.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-160.md b/EIPS/eip-160.md index 6fd18fab832fb..c80d384155e02 100644 --- a/EIPS/eip-160.md +++ b/EIPS/eip-160.md @@ -1,8 +1,21 @@ -EDITOR NOTE: below is a copy of the EIP 160 https://github.com/ethereum/EIPs/issues/160#issue-184230277 raw text fetched on 2017-07-17. +``` +EIP: 160 +Title: EXP cost increase +Author: Vitalik Buterin +Type: Standard Track +Category: Core +Status: Final +Created: 2016-10-20 +``` ### Specification If `block.number >= FORK_BLKNUM`, increase the gas cost of EXP from 10 + 10 per byte in the exponent to 10 + 50 per byte in the exponent. + ### Rationale Benchmarks suggest that EXP is currently underpriced by a factor of about 4-8. + +### References + +1. EIP-160 issue and discussion: https://github.com/ethereum/EIPs/issues/160 From 4ca8c73b933578d2c816321c6377f6dc557ba15d Mon Sep 17 00:00:00 2001 From: cdetrio Date: Tue, 18 Jul 2017 18:12:11 -0400 Subject: [PATCH 0177/1085] add references to Homestead meta-EIP --- EIPS/eip-606.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/EIPS/eip-606.md b/EIPS/eip-606.md index d0ccc71145e44..0d3cdf5a5f8d6 100644 --- a/EIPS/eip-606.md +++ b/EIPS/eip-606.md @@ -22,6 +22,10 @@ This specifies the changes included in the hard fork named Homestead. - Included EIPs: - [EIP 2](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md) (Homestead Hard-fork Changes) - [EIP 7](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-8.md) (DELEGATECALL) + +## References + +1. https://blog.ethereum.org/2016/02/29/homestead-release/ ## Copyright From 1abc6b7e1716f66ef4f4f4acf459d85d446f3bf8 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Tue, 18 Jul 2017 18:42:33 -0400 Subject: [PATCH 0178/1085] fix link --- EIPS/eip-606.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-606.md b/EIPS/eip-606.md index 0d3cdf5a5f8d6..b2ecb84792aa6 100644 --- a/EIPS/eip-606.md +++ b/EIPS/eip-606.md @@ -21,7 +21,7 @@ This specifies the changes included in the hard fork named Homestead. - Block >= 0 on future testnets - Included EIPs: - [EIP 2](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md) (Homestead Hard-fork Changes) - - [EIP 7](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-8.md) (DELEGATECALL) + - [EIP 7](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7.md) (DELEGATECALL) ## References From 4049242c044c9566c1cff635614aec67f81a2890 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 24 Jul 2017 11:30:22 +0200 Subject: [PATCH 0179/1085] Updated the specification Note that this is an actual change in the specification, especially in the case of empty input. Thanks to @bbuenz for pointing this out! --- EIPS/pairings.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/EIPS/pairings.md b/EIPS/pairings.md index 509a86e9c5ce2..b44eee22be585 100644 --- a/EIPS/pairings.md +++ b/EIPS/pairings.md @@ -32,7 +32,7 @@ Add a precompiled contracts for a bilinear function on groups on the elliptic cu Address: 0x8 -For a cyclic group `G` (written additively) of prime order q let `log_P: G -> F_q` be the discrete logarithm on this group with respect to a generator `P`, i.e. `log_P(x)` is the integer `n` such that `n * P = x`. +For a cyclic group `G` (written additively) of prime order q let `log_P: G -> F_q` be the discrete logarithm on this group with respect to a generator `P`, i.e. `log_P(x)` is the smallest non-negative integer `n` such that `n * P = x`. The precompiled contract is defined as follows, where the two groups `G_1` and `G_2` and their generators `P_1` and `P_2` are defined below (they have the same order `q`): @@ -41,11 +41,13 @@ Input: (a1, b1, a2, b2, ..., ak, bk) from (G_1 x G_2)^k Output: If the length of the input is incorrect or any of the inputs are not elements of the respective group or are not encoded correctly, the call fails. Otherwise, return one if - log_P1(a1) * log_P2(b1) + ... + log_P1(ak) * log_P2(bk) = 0 + log_P1(a1) * log_P2(b1) + ... + log_P1(ak) * log_P2(bk) = 1 (in F_q) and zero else. ``` -Note that `k` is determined from the length of the input. `k == 0` is valid and results in returning one. +Note that `k` is determined from the length of the input. Following the section on the encoding below, +`k` is the length of the input divided by `192`. If the input length is not a multiple of `192`, +the call fails. Empty input is valid and results in returning zero. In order to check that an input is an element of `G_1`, verifying the encoding of the coordinates and checking that they satisfy the curve equation (or is the encoding of infinity) is sufficient. For `G_2`, in addition to that, the order of the element has to be checked to be equal to the group order `q = 21888242871839275222246405745257275088548364400416034343698204186575808495617`. @@ -118,7 +120,7 @@ The precompiled contract can be implemented using elliptic curve pairing functio Now observe that ``` -log_P1(a1) * log_P2(b1) + ... + log_P1(ak) * log_P2(bk) = 0 +log_P1(a1) * log_P2(b1) + ... + log_P1(ak) * log_P2(bk) = 1 ``` if and only if ``` From 470c61bed3b94d67815557aca224641742badb56 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 25 Jul 2017 15:03:17 +0200 Subject: [PATCH 0180/1085] Correct equality check and clarify group order. --- EIPS/pairings.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/EIPS/pairings.md b/EIPS/pairings.md index b44eee22be585..276342300f0d1 100644 --- a/EIPS/pairings.md +++ b/EIPS/pairings.md @@ -32,22 +32,22 @@ Add a precompiled contracts for a bilinear function on groups on the elliptic cu Address: 0x8 -For a cyclic group `G` (written additively) of prime order q let `log_P: G -> F_q` be the discrete logarithm on this group with respect to a generator `P`, i.e. `log_P(x)` is the smallest non-negative integer `n` such that `n * P = x`. +For a cyclic group `G` (written additively) of prime order `q` let `log_P: G -> F_q` be the discrete logarithm on this group with respect to a generator `P`, i.e. `log_P(x)` is the smallest non-negative integer `n` such that `n * P = x`. -The precompiled contract is defined as follows, where the two groups `G_1` and `G_2` and their generators `P_1` and `P_2` are defined below (they have the same order `q`): +The precompiled contract is defined as follows, where the two groups `G_1` and `G_2` and their generators `P_1` and `P_2` are defined below. Both generators have the same prime order `q` and the actual choice of the generators does not matter, as long as they have order `q`. ``` Input: (a1, b1, a2, b2, ..., ak, bk) from (G_1 x G_2)^k Output: If the length of the input is incorrect or any of the inputs are not elements of the respective group or are not encoded correctly, the call fails. Otherwise, return one if - log_P1(a1) * log_P2(b1) + ... + log_P1(ak) * log_P2(bk) = 1 + log_P1(a1) * log_P2(b1) + ... + log_P1(ak) * log_P2(bk) = 0 (in F_q) and zero else. ``` Note that `k` is determined from the length of the input. Following the section on the encoding below, `k` is the length of the input divided by `192`. If the input length is not a multiple of `192`, -the call fails. Empty input is valid and results in returning zero. +the call fails. Empty input is valid and results in returning one. In order to check that an input is an element of `G_1`, verifying the encoding of the coordinates and checking that they satisfy the curve equation (or is the encoding of infinity) is sufficient. For `G_2`, in addition to that, the order of the element has to be checked to be equal to the group order `q = 21888242871839275222246405745257275088548364400416034343698204186575808495617`. @@ -68,6 +68,8 @@ P2 = ( ) ``` +Note that `G_2` is the only group of order `q` of that elliptic curve over the field `F_p^2`. + ### Encoding @@ -120,11 +122,11 @@ The precompiled contract can be implemented using elliptic curve pairing functio Now observe that ``` -log_P1(a1) * log_P2(b1) + ... + log_P1(ak) * log_P2(bk) = 1 +log_P1(a1) * log_P2(b1) + ... + log_P1(ak) * log_P2(bk) = 0 (in F_q) ``` if and only if ``` -e(P1, P2)^(log_P1(a1) * log_P2(b1) + ... + log_P1(ak) * log_P2(bk)) = e(P1, P2) +e(P1, P2)^(log_P1(a1) * log_P2(b1) + ... + log_P1(ak) * log_P2(bk)) = 1 (in G_T) ``` Furthermore, the left hand side of this equation is equal to @@ -134,7 +136,7 @@ e(log_P1(a1) * P1, log_P2(b1) * P2) * ... * e(log_P1(ak) * P1, log_P2(bk) * P2) ``` And thus, the precompiled contract can be implemented by verifying that -`e(a1, b1) * ... * e(ak, bk) = e(P1, P2)` +`e(a1, b1) * ... * e(ak, bk) = 1` Implementations are available here: From 471c8131b2bcd029ac6d6377bc6c1217c03664e3 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Sat, 29 Jul 2017 15:40:45 +0100 Subject: [PATCH 0181/1085] Add meta EIP for Tangerine Whistle (EIP 150 Hard Fork) (#608) * Add meta EIP for EIP 150 Hard Fork * Rename to Tangerine Whistle * link to EIP-150 in meta-hf spec * assign no. 608 to Tangerine Whistle meta-eip * add references and aliases to EIP150 meta-EIP --- EIPS/eip-608.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 EIPS/eip-608.md diff --git a/EIPS/eip-608.md b/EIPS/eip-608.md new file mode 100644 index 0000000000000..22ee846e127a5 --- /dev/null +++ b/EIPS/eip-608.md @@ -0,0 +1,31 @@ +## Preamble + + EIP: 608 + Title: Hardfork Meta: Tangerine Whistle + Author: Alex Beregszaszi + Type: Meta + Status: Final + Created: 2017-04-23 + Requires: 150 + +## Abstract + +This specifies the changes included in the hard fork named Tangerine Whistle (EIP 150). + +## Specification + +- Codename: Tangerine Whistle +- Aliases: EIP 150, Anti-DoS +- Activation: + - Block >= 2,463,000 on Mainnet +- Included EIPs: + - [EIP 150](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-150.md) (Gas cost changes for IO-heavy operations) + +## References + +1. https://blog.ethereum.org/2016/10/13/announcement-imminent-hard-fork-eip150-gas-cost-changes/ +2. https://blog.ethereum.org/2016/10/18/faq-upcoming-ethereum-hard-fork/ + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From ede79e4031a64c320ea2edf907089fd9060f5cf5 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Sat, 29 Jul 2017 16:03:23 +0100 Subject: [PATCH 0182/1085] Add meta EIP for Spurious Dragon (#607) * Add meta EIP for Spurious Dragon * assign no. 607 to Spurious Dragon meta-eip * add links to spurious dragon meta * links in Spurious Dragon meta-EIP * add references and aliases to eip-607 --- EIPS/eip-607.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 EIPS/eip-607.md diff --git a/EIPS/eip-607.md b/EIPS/eip-607.md new file mode 100644 index 0000000000000..15a2a2f256898 --- /dev/null +++ b/EIPS/eip-607.md @@ -0,0 +1,35 @@ + +## Preamble + + EIP: 607 + Title: Hardfork Meta: Spurious Dragon + Author: Alex Beregszaszi + Type: Meta + Status: Final + Created: 2017-04-23 + Requires: 155, 160, 161, 170 + +## Abstract + +This specifies the changes included in the hard fork named Spurious Dragon. + +## Specification + +- Codename: Spurious Dragon +- Aliases: State-clearing +- Activation: + - Block >= 2,675,000 on Mainnet + - Block >= 1,885,000 on Morden +- Included EIPs: + - [EIP 155](eip-155.md) (Simple replay attack protection) + - [EIP 160](eip-160.md) (EXP cost increase) + - [EIP 161](eip-161.md) (State trie clearing) + - [EIP 170](eip-170.md) (Contract code size limit) + +## References + +1. https://blog.ethereum.org/2016/11/18/hard-fork-no-4-spurious-dragon/ + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 8740170c623aa01805aa99ea5a0edc0320094664 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 31 Jul 2017 13:49:08 +0100 Subject: [PATCH 0183/1085] REVERT returns 0 in CALL/CREATE --- EIPS/eip-140.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-140.md b/EIPS/eip-140.md index e6c0f50f04767..048596ca83c2c 100644 --- a/EIPS/eip-140.md +++ b/EIPS/eip-140.md @@ -32,9 +32,9 @@ The cost of the `REVERT` instruction equals to that of the `RETURN` instruction, In case there is not enough gas left to cover the cost of `REVERT` or there is a stack underflow, the effect of the `REVERT` instruction will equal to that of a regular out of gas exception, i.e. it will consume all gas. -In the same way as all other failures, the calling opcode returns `1` on the stack following a `REVERT` opcode in the callee. +In the same way as all other failures, the calling opcode returns `0` on the stack following a `REVERT` opcode in the callee. -In case `REVERT` is used in the context of a `CREATE` or `CREATE2` call, no code is deployed, `1` is put on the stack and the error message is available in the returndata buffer. +In case `REVERT` is used in the context of a `CREATE` or `CREATE2` call, no code is deployed, `0` is put on the stack and the error message is available in the returndata buffer. The content of the optionally provided memory section is not defined by this EIP, but is a candidate for another Informational EIP. From 5051d0f2977a630a17bbd2e5983491f5b648e0f1 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 31 Jul 2017 13:49:46 +0100 Subject: [PATCH 0184/1085] Mark REVERT as accepted --- EIPS/eip-140.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-140.md b/EIPS/eip-140.md index 048596ca83c2c..94e89bd8a1b31 100644 --- a/EIPS/eip-140.md +++ b/EIPS/eip-140.md @@ -5,7 +5,7 @@ Author: Alex Beregszaszi, Nikolai Mushegian (nikolai@nexusdev.us) Type: Standard Track Category: Core - Status: Draft + Status: Accepted Created: 2017-02-06 ## Simple Summary From 0b08d11f488fa14975fbc585af639aa00d7f4c0b Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 31 Jul 2017 13:59:00 +0100 Subject: [PATCH 0185/1085] Add comparison with current opcodes --- EIPS/eip-145.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/EIPS/eip-145.md b/EIPS/eip-145.md index 95c8481671881..04f36bcd2d537 100644 --- a/EIPS/eip-145.md +++ b/EIPS/eip-145.md @@ -37,6 +37,7 @@ Notes: - The value (`arg1`) is interpreted as an unsigned number. - The shift amount (`arg2`) is interpreted as an unsigned number. - If the shift amount (`arg2`) is greater or equal 256 the result is 0. +- This is equivalent to `SWAP1 PUSH1 2 EXP MUL`. ### `0x1c`: `SHR` (logical shift right) @@ -50,6 +51,7 @@ Notes: - The value (`arg1`) is interpreted as an unsigned number. - The shift amount (`arg2`) is interpreted as an unsigned number. - If the shift amount (`arg2`) is greater or equal 256 the result is 0. +- This is equivalent to `SWAP1 PUSH1 2 EXP DIV`. ### `0x1d`: `SAR` (arithmetic shift right) @@ -63,6 +65,7 @@ Notes: - The value (`arg1`) is interpreted as a signed number. - The shift amount (`arg2`) is interpreted as an unsigned number. - If the shift amount (`arg2`) is greater or equal 256 the result is 0 if `arg1` is non-negative or -1 if `arg1` is negative. +- This is **not** equivalent to `SWAP1 PUSH1 2 EXP SDIV`, since it rounds differently. See `SDIV(-1, 2) == 0`, while `SAR(-1, 1) == -1`. The cost of the shift instructions is set at `verylow` tier (3 gas). From 640a8a7616222f7667341abbe483724d4123aa41 Mon Sep 17 00:00:00 2001 From: "Daniel A. Nagy" Date: Tue, 1 Aug 2017 11:53:19 +0200 Subject: [PATCH 0186/1085] EIP: Payment request URL specification for QR codes, hyperlinks and Android Intents. --- EIPS/pay_req_url_fmt.md | 65 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 EIPS/pay_req_url_fmt.md diff --git a/EIPS/pay_req_url_fmt.md b/EIPS/pay_req_url_fmt.md new file mode 100644 index 0000000000000..804baafeaf99e --- /dev/null +++ b/EIPS/pay_req_url_fmt.md @@ -0,0 +1,65 @@ +## Preamble + + EIP: + Title: URL Format for Payment Requests + Author: Daniel A. Nagy + Type: Standard Track + Category: ERC + Status: Draft + Created: 2017-08-01 + Requires: #20 + +## Simple Summary +A standard way of representing payment requests in Ethers and ERC #20 tokens as URLs. + +## Abstract +URLs embedded in QR-codes, hyperlinks in webpages, emails or chat messages provide for robust cross-application signaling between very +loosely coupled applications. A standardized URL format for payment requests allows for instant invocation of the user's preferred +wallet application (even if it is a webapp or a swarm đapp), with the correct parametrization of the payment transaction only to be +confirmed by the (authenticated) user. + +## Motivation +The convenience of representing payment requests by standard URLs has been a major factor in the wide adoption of Bitcoin. Bringing a +similarly convenient mechanism to Ethereum would speed up its acceptance as a payment platform among end-users. In particular, URLs +embedded in broadcast Intents are the preferred way of launching applications on the Android operating system and work across +practiaclly all applications. Desktop web browsers have a standardized way of defining protocol handlers for URLs with specific protocol +specifications. Other desktop applications typically launch the web browser upon encountering a URL. Thus, payment request URLs +could be delivered through a very broad, ever growing selection of channels. + +## Specification + +### Syntax +Payment request URLs contain "ethereum" in their schema (protocol) part and are constructed as follows: + + request = "ethereum" ":" beneficiary_address [ "/" token_contract_address ] [ "?" parameters ] + beneficiary_address = ethereum_address + token_contract_address = ethereum_address + ethereum_address = 40*40HEXDIG + parameters = parameter *( "&" parameter ) + parameter = key "=" value + +At present, the only `key` defined is `amount` and the corresponding `value` is a decimal number. Thus: + + key = "amount" + value = *DIGIT [ "." 1*DIGIT ] + +### Semantics +If `token_contract_address` is missing, then the payment is requested in the native token of the blockchain, which is Ether in our case. +The only mandatory field `beneficiary_address` denotes the address of the account to be credited with the requested token. + +Thus, if `token_contract_address` is missing, the target address of the transaction is `beneficiary_address`, otherwise it is +`token_contract_address`, with the appropriate transaction data, as defined in ERC #20 indicating the transfer of the given amount of tokens. + +The amount is to be interpreted in the decimal definition of the token, NOT the atomic unit. In case of Ether, it needs to +be multiplied by 10^18 to get the integer amount in Wei. For other tokens, the decimal value should be read from the +token contract before conversion. + +Note that the indicated amount is only a suggestion and the user is free to change it. With no indicated amount, the user should be +prompted to enter the amount to be paid. In case of multiple suggestions, the user should have the option of choosing one or +enter their own. + +## Rationale +The proposed format is chosen to resemble `bitcoin:` URLs as closely as possible, as both users and application programmers +are already familiar with that format. In particular, this motivated the omission of the unit, which is often used in +Ethereum ecosystem. Handling different orders of magnitude is delegated to the application, just like in the case of `bitcoin:`. +Additional parameters may be added, if popular use cases requiring them emerge in practice. From b7f8744d9d8026dec909b2baf2e58a0ffc5f5c99 Mon Sep 17 00:00:00 2001 From: "Daniel A. Nagy" Date: Tue, 1 Aug 2017 13:40:10 +0200 Subject: [PATCH 0187/1085] EIP: Add ENS support to payment requests --- EIPS/pay_req_url_fmt.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/EIPS/pay_req_url_fmt.md b/EIPS/pay_req_url_fmt.md index 804baafeaf99e..719d3986015ac 100644 --- a/EIPS/pay_req_url_fmt.md +++ b/EIPS/pay_req_url_fmt.md @@ -7,22 +7,22 @@ Category: ERC Status: Draft Created: 2017-08-01 - Requires: #20 + Requires: #20, #137 ## Simple Summary A standard way of representing payment requests in Ethers and ERC #20 tokens as URLs. ## Abstract -URLs embedded in QR-codes, hyperlinks in webpages, emails or chat messages provide for robust cross-application signaling between very +URLs embedded in QR-codes, hyperlinks in web-pages, emails or chat messages provide for robust cross-application signaling between very loosely coupled applications. A standardized URL format for payment requests allows for instant invocation of the user's preferred -wallet application (even if it is a webapp or a swarm đapp), with the correct parametrization of the payment transaction only to be +wallet application (even if it is a webapp or a swarm đapp), with the correct parameterization of the payment transaction only to be confirmed by the (authenticated) user. ## Motivation The convenience of representing payment requests by standard URLs has been a major factor in the wide adoption of Bitcoin. Bringing a similarly convenient mechanism to Ethereum would speed up its acceptance as a payment platform among end-users. In particular, URLs embedded in broadcast Intents are the preferred way of launching applications on the Android operating system and work across -practiaclly all applications. Desktop web browsers have a standardized way of defining protocol handlers for URLs with specific protocol +practically all applications. Desktop web browsers have a standardized way of defining protocol handlers for URLs with specific protocol specifications. Other desktop applications typically launch the web browser upon encountering a URL. Thus, payment request URLs could be delivered through a very broad, ever growing selection of channels. @@ -34,7 +34,7 @@ Payment request URLs contain "ethereum" in their schema (protocol) part and are request = "ethereum" ":" beneficiary_address [ "/" token_contract_address ] [ "?" parameters ] beneficiary_address = ethereum_address token_contract_address = ethereum_address - ethereum_address = 40*40HEXDIG + ethereum_address = 40*40HEXDIG / ENS_NAME parameters = parameter *( "&" parameter ) parameter = key "=" value @@ -43,6 +43,8 @@ At present, the only `key` defined is `amount` and the corresponding `value` is key = "amount" value = *DIGIT [ "." 1*DIGIT ] +For the syntax of ENS_NAME, please consult ERC #137 defining Ethereum Name Service. + ### Semantics If `token_contract_address` is missing, then the payment is requested in the native token of the blockchain, which is Ether in our case. The only mandatory field `beneficiary_address` denotes the address of the account to be credited with the requested token. @@ -50,6 +52,9 @@ The only mandatory field `beneficiary_address` denotes the address of the accoun Thus, if `token_contract_address` is missing, the target address of the transaction is `beneficiary_address`, otherwise it is `token_contract_address`, with the appropriate transaction data, as defined in ERC #20 indicating the transfer of the given amount of tokens. +If using ENS names instead of hexadecimal addresses, the resolution is up to the payer, at any time between receiving the +URL and sending the transaction. + The amount is to be interpreted in the decimal definition of the token, NOT the atomic unit. In case of Ether, it needs to be multiplied by 10^18 to get the integer amount in Wei. For other tokens, the decimal value should be read from the token contract before conversion. From 56a2454b07e02428bee7165345710edf2e5e4a1f Mon Sep 17 00:00:00 2001 From: "Daniel A. Nagy" Date: Tue, 1 Aug 2017 14:17:23 +0200 Subject: [PATCH 0188/1085] EIP: Explicit disclaimer for hexadecimal addresses taking priority over ENS names. --- EIPS/pay_req_url_fmt.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/EIPS/pay_req_url_fmt.md b/EIPS/pay_req_url_fmt.md index 719d3986015ac..3988c6a99ac24 100644 --- a/EIPS/pay_req_url_fmt.md +++ b/EIPS/pay_req_url_fmt.md @@ -52,8 +52,9 @@ The only mandatory field `beneficiary_address` denotes the address of the accoun Thus, if `token_contract_address` is missing, the target address of the transaction is `beneficiary_address`, otherwise it is `token_contract_address`, with the appropriate transaction data, as defined in ERC #20 indicating the transfer of the given amount of tokens. -If using ENS names instead of hexadecimal addresses, the resolution is up to the payer, at any time between receiving the -URL and sending the transaction. +If using ENS names instead of hexadecimal addresses, the resolution is up to the payer, at any time between receiving the URL and +sending the transaction. Hexadecimal addresses always take precedence over ENS names, i. e. even if there exists a matching ENS name +consisting of 40 hexadecimal digits, it should never be resolved. Instead, the hexadecimal address should be used directly. The amount is to be interpreted in the decimal definition of the token, NOT the atomic unit. In case of Ether, it needs to be multiplied by 10^18 to get the integer amount in Wei. For other tokens, the decimal value should be read from the From 1546a4804b45c29d78a18a8281ce03066467b6db Mon Sep 17 00:00:00 2001 From: "Daniel A. Nagy" Date: Thu, 3 Aug 2017 16:30:32 +0200 Subject: [PATCH 0189/1085] EIP: Explicit reference to ERC #67 added. Protocol part changed to "ethpay" for distinction and compatibility. --- EIPS/pay_req_url_fmt.md | 43 +++++++++++++---------------------------- 1 file changed, 13 insertions(+), 30 deletions(-) diff --git a/EIPS/pay_req_url_fmt.md b/EIPS/pay_req_url_fmt.md index 3988c6a99ac24..c6c45fcee8588 100644 --- a/EIPS/pay_req_url_fmt.md +++ b/EIPS/pay_req_url_fmt.md @@ -7,31 +7,25 @@ Category: ERC Status: Draft Created: 2017-08-01 - Requires: #20, #137 + Requires: #20, #67, #137 ## Simple Summary A standard way of representing payment requests in Ethers and ERC #20 tokens as URLs. ## Abstract -URLs embedded in QR-codes, hyperlinks in web-pages, emails or chat messages provide for robust cross-application signaling between very -loosely coupled applications. A standardized URL format for payment requests allows for instant invocation of the user's preferred -wallet application (even if it is a webapp or a swarm đapp), with the correct parameterization of the payment transaction only to be -confirmed by the (authenticated) user. +URLs embedded in QR-codes, hyperlinks in web-pages, emails or chat messages provide for robust cross-application signaling between very loosely coupled applications. A standardized URL format for payment requests allows for instant invocation of the user's preferred wallet application (even if it is a webapp or a swarm đapp), with the correct parameterization of the payment transaction only to be confirmed by the (authenticated) user. ## Motivation -The convenience of representing payment requests by standard URLs has been a major factor in the wide adoption of Bitcoin. Bringing a -similarly convenient mechanism to Ethereum would speed up its acceptance as a payment platform among end-users. In particular, URLs -embedded in broadcast Intents are the preferred way of launching applications on the Android operating system and work across -practically all applications. Desktop web browsers have a standardized way of defining protocol handlers for URLs with specific protocol -specifications. Other desktop applications typically launch the web browser upon encountering a URL. Thus, payment request URLs -could be delivered through a very broad, ever growing selection of channels. +The convenience of representing payment requests by standard URLs has been a major factor in the wide adoption of Bitcoin. Bringing a similarly convenient mechanism to Ethereum would speed up its acceptance as a payment platform among end-users. In particular, URLs embedded in broadcast Intents are the preferred way of launching applications on the Android operating system and work across practically all applications. Desktop web browsers have a standardized way of defining protocol handlers for URLs with specific protocol specifications. Other desktop applications typically launch the web browser upon encountering a URL. Thus, payment request URLs could be delivered through a very broad, ever growing selection of channels. + +Note that this is different from ERC #67, which is a URL format for representing arbitrary transactions and as such is more general and low-level. This ERC deals specifically with the important special case of payment requests. ## Specification ### Syntax -Payment request URLs contain "ethereum" in their schema (protocol) part and are constructed as follows: +Payment request URLs contain "ethpay" in their schema (protocol) part and are constructed as follows: - request = "ethereum" ":" beneficiary_address [ "/" token_contract_address ] [ "?" parameters ] + request = "ethpay" ":" beneficiary_address [ "/" token_contract_address ] [ "?" parameters ] beneficiary_address = ethereum_address token_contract_address = ethereum_address ethereum_address = 40*40HEXDIG / ENS_NAME @@ -46,26 +40,15 @@ At present, the only `key` defined is `amount` and the corresponding `value` is For the syntax of ENS_NAME, please consult ERC #137 defining Ethereum Name Service. ### Semantics -If `token_contract_address` is missing, then the payment is requested in the native token of the blockchain, which is Ether in our case. -The only mandatory field `beneficiary_address` denotes the address of the account to be credited with the requested token. +If `token_contract_address` is missing, then the payment is requested in the native token of the blockchain, which is Ether in our case. The only mandatory field `beneficiary_address` denotes the address of the account to be credited with the requested token. -Thus, if `token_contract_address` is missing, the target address of the transaction is `beneficiary_address`, otherwise it is -`token_contract_address`, with the appropriate transaction data, as defined in ERC #20 indicating the transfer of the given amount of tokens. +Thus, if `token_contract_address` is missing, the target address of the transaction is `beneficiary_address`, otherwise it is `token_contract_address`, with the appropriate transaction data, as defined in ERC #20 indicating the transfer of the given amount of tokens. -If using ENS names instead of hexadecimal addresses, the resolution is up to the payer, at any time between receiving the URL and -sending the transaction. Hexadecimal addresses always take precedence over ENS names, i. e. even if there exists a matching ENS name -consisting of 40 hexadecimal digits, it should never be resolved. Instead, the hexadecimal address should be used directly. +If using ENS names instead of hexadecimal addresses, the resolution is up to the payer, at any time between receiving the URL and sending the transaction. Hexadecimal addresses always take precedence over ENS names, i. e. even if there exists a matching ENS name consisting of 40 hexadecimal digits, it should never be resolved. Instead, the hexadecimal address should be used directly. -The amount is to be interpreted in the decimal definition of the token, NOT the atomic unit. In case of Ether, it needs to -be multiplied by 10^18 to get the integer amount in Wei. For other tokens, the decimal value should be read from the -token contract before conversion. +The amount is to be interpreted in the decimal definition of the token, NOT the atomic unit. In case of Ether, it needs to be multiplied by 10^18 to get the integer amount in Wei. For other tokens, the decimal value should be read from the token contract before conversion. -Note that the indicated amount is only a suggestion and the user is free to change it. With no indicated amount, the user should be -prompted to enter the amount to be paid. In case of multiple suggestions, the user should have the option of choosing one or -enter their own. +Note that the indicated amount is only a suggestion and the user is free to change it. With no indicated amount, the user should be prompted to enter the amount to be paid. In case of multiple suggestions, the user should have the option of choosing one or enter their own. ## Rationale -The proposed format is chosen to resemble `bitcoin:` URLs as closely as possible, as both users and application programmers -are already familiar with that format. In particular, this motivated the omission of the unit, which is often used in -Ethereum ecosystem. Handling different orders of magnitude is delegated to the application, just like in the case of `bitcoin:`. -Additional parameters may be added, if popular use cases requiring them emerge in practice. +The proposed format is chosen to resemble `bitcoin:` URLs as closely as possible, as both users and application programmers are already familiar with that format. In particular, this motivated the omission of the unit, which is often used in Ethereum ecosystem. Handling different orders of magnitude is delegated to the application, just like in the case of `bitcoin:`. Additional parameters may be added, if popular use cases requiring them emerge in practice. From 2b8a1608999c931f4d92afdea60eb1d76dea5804 Mon Sep 17 00:00:00 2001 From: "Daniel A. Nagy" Date: Thu, 3 Aug 2017 16:47:06 +0200 Subject: [PATCH 0190/1085] EIP: Removed #67 from requirements. It is not required, merely referenced. --- EIPS/pay_req_url_fmt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/pay_req_url_fmt.md b/EIPS/pay_req_url_fmt.md index c6c45fcee8588..293ca132f1a07 100644 --- a/EIPS/pay_req_url_fmt.md +++ b/EIPS/pay_req_url_fmt.md @@ -7,7 +7,7 @@ Category: ERC Status: Draft Created: 2017-08-01 - Requires: #20, #67, #137 + Requires: #20, #137 ## Simple Summary A standard way of representing payment requests in Ethers and ERC #20 tokens as URLs. From 0b1284370277e77674736efb4e26c2d3b953edf6 Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Tue, 8 Aug 2017 10:21:58 +0200 Subject: [PATCH 0191/1085] Replace #186 with eip-649 --- EIPS/eip-649.md | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index 70dd2e66201b5..aa231aaa9ff7b 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -1,34 +1,45 @@ ## Preamble EIP: 649 - Title: Metropolis Difficulty Bomb Delay + Title: Metropolis Difficulty Bomb Delay and Issuance Reduction Authors: Afri Schoedon (Champion), Vitalik Buterin (Specification) Type: Standard Track Category: Core Status: Draft Created: 2017-06-21 + Replaces: 186 ## Simple Summary -The average block times are increasing due to the difficulty bomb (also as known as the "ice age") slowly accelerating. This EIP proposes to delay the difficulty bomb for approximately one and a half year. +The average block times are increasing due to the difficulty bomb (also as known as the "ice age") slowly accelerating. This EIP proposes to delay the difficulty bomb for approximately one and a half year and to reduce the block rewards with the Metropolis fork. ## Abstract -After `METROPOLIS_FORK_BLKNUM` the client will simply calculate the difficulty based on a fake block number suggesting the client that the difficulty bomb is adjusting around 3 million blocks later than previously specified with the Homestead fork. +After `METROPOLIS_FORK_BLKNUM` the client will calculate the difficulty based on a fake block number suggesting the client that the difficulty bomb is adjusting around 3 million blocks later than previously specified with the Homestead fork. Furthermore, to add an issuance reduction, block rewards will be adjusted to a base of 3 ETH, and uncle rewards will be adjusted accordingly. ## Motivation -The Casper development and switch to Proof-of-Stake is delayed, the Proof-of-Work should be feasible for miners and create new blocks every 15 seconds on average for another 1.4 years. +The Casper development and switch to Proof-of-Stake is delayed, the Proof-of-Work should be feasible for miners and create new blocks every 15 seconds on average for another 1.4 years. The incentive to continue mining the Proof-of-Work chain after a potential move to Proof-of-Stake is reduced by adjusting block rewards. ## Specification +#### Relax Difficulty with Fake Block Number For the purposes of `calc_difficulty`, we simply replace the use of `block.number`, as used in the exponential ice age component, with the formula: - fake_block_number = block.number - 3000000 if block.number >= METROPOLIS_FORK_BLKNUM else block.number + fake_block_number = block.number - 3_000_000 if block.number >= METROPOLIS_FORK_BLKNUM else block.number + +#### Adjust Block, Uncle, and Nephew rewards +To add an issuance reduction, we adjust the block reward for `block.number >= METROPOLIS_FORK_BLKNUM` to `new_block_reward`, where `new_block_reward = 3_000_000_000_000_000_000`. This is 3E18 wei, or 3,000,000,000,000,000,000 wei, or 3 ETH for the `new_block_reward`. + +If an uncle is included in a block for `block.number >= METROPOLIS_FORK_BLKNUM` such that `block.number - uncle.number = k`, the uncle reward is `(8 - k) * new_block_reward / 8`. This is the existing pre-Metropolis formula for uncle rewards, simply adjusted with `new_block_reward`. + +The nephew reward for `block.number >= METROPOLIS_FORK_BLKNUM` is `new_block_reward / 32`. This is the existing pre-Metropolis formula for nephew rewards, simply adjusted with `new_block_reward`. ## Rationale This will delay the ice age by 42 million seconds ~= 1.4 years, so we would be back at 30 second block times at the end of 2018. An alternate proposal was that we add special rules to the difficulty calculation to effectively _pause_ the difficulty between different blocks. That would lead to similar results. This was previously discussed at All Core Devs Meeting [#09](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%209.md#metropolis-timing-and-roadmap-discussion), [#12](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2012.md#5-metropolis-update), [#13](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2013.md#3-eip-186-reduce-eth-issuance-before-proof-of-stake-hudson), and [#14](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2014.md#1-eip-186-reduce-eth-issuance-before-proof-of-stake-core-devs). Consensus on the specification was achieved in All Core Devs Meeting [#19](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2019.md) and specification drafted in EIP issue [#649](https://github.com/ethereum/EIPs/issues/649). +It was decided to replace EIP [#186](https://github.com/ethereum/EIPs/issues/186) and include the issuance reduction along with the difficulty bomb delay in All Core Devs Meeting [#20](#) and [#21](#). + ## Backwards Compatibility -This EIP is not forward compatible and introduces backwards incompatibilities in the difficulty calculation. Therefore, it should be included in a scheduled hardfork at a certain block number. It's suggested to include this EIP in the Metropolis fork. +This EIP is not forward compatible and introduces backwards incompatibilities in the difficulty calculation, as well as the block, uncle and nephew reward structure. Therefore, it should be included in a scheduled hardfork at a certain block number. It's suggested to include this EIP in the Metropolis fork. ## Test Cases No test cases exist yet. But will be easy to set up based on the rules specified above. From 5fd71ef0dedb602b59f529a6df128f53db372641 Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Tue, 8 Aug 2017 10:31:41 +0200 Subject: [PATCH 0192/1085] Wording and formatting. --- EIPS/eip-649.md | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index aa231aaa9ff7b..ddcb07f5683c4 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -20,19 +20,31 @@ The Casper development and switch to Proof-of-Stake is delayed, the Proof-of-Wor ## Specification #### Relax Difficulty with Fake Block Number -For the purposes of `calc_difficulty`, we simply replace the use of `block.number`, as used in the exponential ice age component, with the formula: +For the purposes of `calc_difficulty`, simply replace the use of `block.number`, as used in the exponential ice age component, with the formula: fake_block_number = block.number - 3_000_000 if block.number >= METROPOLIS_FORK_BLKNUM else block.number #### Adjust Block, Uncle, and Nephew rewards -To add an issuance reduction, we adjust the block reward for `block.number >= METROPOLIS_FORK_BLKNUM` to `new_block_reward`, where `new_block_reward = 3_000_000_000_000_000_000`. This is 3E18 wei, or 3,000,000,000,000,000,000 wei, or 3 ETH for the `new_block_reward`. +To add an issuance reduction, adjust the block reward to `new_block_reward`, where -If an uncle is included in a block for `block.number >= METROPOLIS_FORK_BLKNUM` such that `block.number - uncle.number = k`, the uncle reward is `(8 - k) * new_block_reward / 8`. This is the existing pre-Metropolis formula for uncle rewards, simply adjusted with `new_block_reward`. + new_block_reward = 3_000_000_000_000_000_000 if block.number >= METROPOLIS_FORK_BLKNUM else block.reward -The nephew reward for `block.number >= METROPOLIS_FORK_BLKNUM` is `new_block_reward / 32`. This is the existing pre-Metropolis formula for nephew rewards, simply adjusted with `new_block_reward`. +(3E18 wei, or 3,000,000,000,000,000,000 wei, or 3 ETH). + +Analogue, if an uncle is included in a block for `block.number >= METROPOLIS_FORK_BLKNUM` such that `block.number - uncle.number = k`, the uncle reward is + + new_uncle_reward = (8 - k) * new_block_reward / 8 + +This is the existing pre-Metropolis formula for uncle rewards, simply adjusted with `new_block_reward`. + +The nephew reward for `block.number >= METROPOLIS_FORK_BLKNUM` is + + new_nephew_reward = new_block_reward / 32 + +This is the existing pre-Metropolis formula for nephew rewards, simply adjusted with `new_block_reward`. ## Rationale -This will delay the ice age by 42 million seconds ~= 1.4 years, so we would be back at 30 second block times at the end of 2018. An alternate proposal was that we add special rules to the difficulty calculation to effectively _pause_ the difficulty between different blocks. That would lead to similar results. +This will delay the ice age by 42 million seconds ~= 1.4 years, so the chain would be back at 30 second block times at the end of 2018. An alternate proposal was to add special rules to the difficulty calculation to effectively _pause_ the difficulty between different blocks. That would lead to similar results. This was previously discussed at All Core Devs Meeting [#09](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%209.md#metropolis-timing-and-roadmap-discussion), [#12](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2012.md#5-metropolis-update), [#13](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2013.md#3-eip-186-reduce-eth-issuance-before-proof-of-stake-hudson), and [#14](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2014.md#1-eip-186-reduce-eth-issuance-before-proof-of-stake-core-devs). Consensus on the specification was achieved in All Core Devs Meeting [#19](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2019.md) and specification drafted in EIP issue [#649](https://github.com/ethereum/EIPs/issues/649). From ee262a30eb033ad1241bc8a56bc4b84fbb752ffa Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Tue, 8 Aug 2017 10:38:01 +0200 Subject: [PATCH 0193/1085] Consider 649 instead of #186. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f2e38c991b83a..ff2f8ec2e9625 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP # EIPs under consideration | Number |Title | Author | Layer | Status | | ------------------------------------------------------ | ----------------------------------------------------------------------------------- | -------------------- | ------------| ----------| -| [186](https://github.com/ethereum/EIPs/issues/186) | Reduce ETH issuance before proof-of-stake | Matthew Light | Core | Draft | +| [649](https://github.com/ethereum/EIPs/issues/669) | Metropolis Difficulty Bomb Delay and Issuance Reduction | Afri Schoedon | Core | Draft | # Accepted EIPs (planned for adoption) From 9c29817d9135afc91f55d710f48d4a679da63adb Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Tue, 8 Aug 2017 10:45:51 +0200 Subject: [PATCH 0194/1085] Fix EIP link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ff2f8ec2e9625..afc5f8e28ae05 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP # EIPs under consideration | Number |Title | Author | Layer | Status | | ------------------------------------------------------ | ----------------------------------------------------------------------------------- | -------------------- | ------------| ----------| -| [649](https://github.com/ethereum/EIPs/issues/669) | Metropolis Difficulty Bomb Delay and Issuance Reduction | Afri Schoedon | Core | Draft | +| [649](https://github.com/ethereum/EIPs/pull/669) | Metropolis Difficulty Bomb Delay and Issuance Reduction | Schoedon, Buterin | Core | Draft | # Accepted EIPs (planned for adoption) From 60b9fe0aa36300eb1f524d377ff7ab64e95eec07 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 14 Aug 2017 15:19:12 +0200 Subject: [PATCH 0195/1085] Defer EIP96 from Byzantium to Constantinople (#685) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 030fe459a7d4b..a96ecad57cd5e 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,6 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP # Accepted EIPs (planned for adoption) | Number |Title | Author | Layer | Status | | ------------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ------------| ----------| -| [96](https://github.com/ethereum/EIPs/pull/210) | Blockhash refactoring | Vitalik Buterin | Core | Accepted | | [98](https://github.com/ethereum/EIPs/pull/98) | Removal of intermediate state roots from receipts | Vitalik Buterin | Core | Accepted | | [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Core | Accepted | | [140](https://github.com/ethereum/EIPs/pull/206) | REVERT instruction in the Ethereum Virtual Machine | Beregszaszi, Mushegian| Core | Accepted | @@ -34,6 +33,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | Number |Title | Author | Layer | Status | | ------------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ------------| ----------| | [86](https://github.com/ethereum/EIPs/pull/208) | Abstraction of transaction origin and signature | Vitalik Buterin | Core | Deferred | +| [96](https://github.com/ethereum/EIPs/pull/210) | Blockhash refactoring | Vitalik Buterin | Core | Deferred | # Finalized EIPs (standards that have been adopted) | Number |Title | Author | Layer | Status | From c25130885e7433639e861ddc6561d1632749aa7d Mon Sep 17 00:00:00 2001 From: cdetrio Date: Mon, 14 Aug 2017 11:35:15 -0400 Subject: [PATCH 0196/1085] remove intermediate state roots (#98) from accepted table --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index a96ecad57cd5e..d16f0a1d29313 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,6 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP # Accepted EIPs (planned for adoption) | Number |Title | Author | Layer | Status | | ------------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ------------| ----------| -| [98](https://github.com/ethereum/EIPs/pull/98) | Removal of intermediate state roots from receipts | Vitalik Buterin | Core | Accepted | | [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Core | Accepted | | [140](https://github.com/ethereum/EIPs/pull/206) | REVERT instruction in the Ethereum Virtual Machine | Beregszaszi, Mushegian| Core | Accepted | | [196](https://github.com/ethereum/EIPs/pull/213) | Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 | Reitwiessner | Core | Accepted | From c601c391ea53dbad37d6fec7f57ec82e2672ef55 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Sun, 23 Apr 2017 17:04:44 +0100 Subject: [PATCH 0197/1085] Add meta EIP for Metropolis --- EIPS/eip-draft_hfmeta_metropolis.md | 35 +++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 EIPS/eip-draft_hfmeta_metropolis.md diff --git a/EIPS/eip-draft_hfmeta_metropolis.md b/EIPS/eip-draft_hfmeta_metropolis.md new file mode 100644 index 0000000000000..3cd4f99dd793e --- /dev/null +++ b/EIPS/eip-draft_hfmeta_metropolis.md @@ -0,0 +1,35 @@ +## Preamble + + EIP: + Title: Hardfork Meta: Metropolis + Author: Alex Beregszaszi + Type: Standard Track + Category: Core + Status: Draft + Created: 23/04/2017 + Requires: 86, 96, 98, 100, 140, 196, 197, 198, 211, 214 + +## Abstract + +This specifies the changes included in the hard fork named Metropolis. + +## Specification + +- Codename: Metropolis +- Activation: + - Block not specified yet +- Included EIPs: + - EIP 86 (Abstraction of transaction origin and signature) + - EIP 96 (Blockhash refactoring) + - EIP 98 (Removal of intermediate state roots from receipts) + - EIP 100 (Change difficulty adjustment to target mean block time including uncles) + - EIP 140 (REVERT instruction in the Ethereum Virtual Machine) + - EIP 196 (Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128) + - EIP 197 (Precompiled contracts for optimal ate pairing check on the elliptic curve alt_bn128) + - EIP 198 (Precompiled contract for bigint modular exponentiation) + - EIP 211 (New opcodes: RETURNDATASIZE and RETURNDATACOPY) + - EIP 214 (New opcode STATICCALL) + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 5b93f6cdf3e6ae9320d33cad5fd44d2661c90297 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Sun, 13 Aug 2017 10:28:36 -0400 Subject: [PATCH 0198/1085] update HF-meta for Metropolis to Byzantium --- EIPS/eip-draft_hfmeta_metropolis.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/EIPS/eip-draft_hfmeta_metropolis.md b/EIPS/eip-draft_hfmeta_metropolis.md index 3cd4f99dd793e..66e6cb3418587 100644 --- a/EIPS/eip-draft_hfmeta_metropolis.md +++ b/EIPS/eip-draft_hfmeta_metropolis.md @@ -1,27 +1,25 @@ ## Preamble - EIP: - Title: Hardfork Meta: Metropolis + EIP: 609 + Title: Hardfork Meta: Byzantium Author: Alex Beregszaszi Type: Standard Track Category: Core Status: Draft - Created: 23/04/2017 - Requires: 86, 96, 98, 100, 140, 196, 197, 198, 211, 214 + Created: 2017-04-23 + Requires: 100, 140, 196, 197, 198, 211, 214 ## Abstract -This specifies the changes included in the hard fork named Metropolis. +This specifies the changes included in the hard fork named Byzantium. ## Specification -- Codename: Metropolis +- Codename: Byzantium +- Aliases: Metropolis/Byzantium, Metropolis part 1 - Activation: - Block not specified yet - Included EIPs: - - EIP 86 (Abstraction of transaction origin and signature) - - EIP 96 (Blockhash refactoring) - - EIP 98 (Removal of intermediate state roots from receipts) - EIP 100 (Change difficulty adjustment to target mean block time including uncles) - EIP 140 (REVERT instruction in the Ethereum Virtual Machine) - EIP 196 (Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128) @@ -29,6 +27,7 @@ This specifies the changes included in the hard fork named Metropolis. - EIP 198 (Precompiled contract for bigint modular exponentiation) - EIP 211 (New opcodes: RETURNDATASIZE and RETURNDATACOPY) - EIP 214 (New opcode STATICCALL) + - EIP 658 (Embedding transaction return data in receipts) ## Copyright From c52a3f13b5cb394a6c940ff5a785ded42bdca8b2 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Mon, 14 Aug 2017 11:46:23 -0400 Subject: [PATCH 0199/1085] Rename hfmeta-byzantium to eip-609.md --- EIPS/{eip-draft_hfmeta_metropolis.md => eip-609.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename EIPS/{eip-draft_hfmeta_metropolis.md => eip-609.md} (100%) diff --git a/EIPS/eip-draft_hfmeta_metropolis.md b/EIPS/eip-609.md similarity index 100% rename from EIPS/eip-draft_hfmeta_metropolis.md rename to EIPS/eip-609.md From b48d836412c442703bd3ecd31f449bf80b99a40f Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Tue, 15 Aug 2017 11:43:01 +0200 Subject: [PATCH 0200/1085] Use the byzantium fork block number. --- EIPS/eip-649.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index ddcb07f5683c4..ff28747d7ebbf 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -10,10 +10,10 @@ Replaces: 186 ## Simple Summary -The average block times are increasing due to the difficulty bomb (also as known as the "ice age") slowly accelerating. This EIP proposes to delay the difficulty bomb for approximately one and a half year and to reduce the block rewards with the Metropolis fork. +The average block times are increasing due to the difficulty bomb (also as known as the "ice age") slowly accelerating. This EIP proposes to delay the difficulty bomb for approximately one and a half year and to reduce the block rewards with the Byzantium fork (the first part of the Metropolis fork). ## Abstract -After `METROPOLIS_FORK_BLKNUM` the client will calculate the difficulty based on a fake block number suggesting the client that the difficulty bomb is adjusting around 3 million blocks later than previously specified with the Homestead fork. Furthermore, to add an issuance reduction, block rewards will be adjusted to a base of 3 ETH, and uncle rewards will be adjusted accordingly. +After `BYZANTIUM_FORK_BLKNUM` the client will calculate the difficulty based on a fake block number suggesting the client that the difficulty bomb is adjusting around 3 million blocks later than previously specified with the Homestead fork. Furthermore, to add an issuance reduction, block rewards will be adjusted to a base of 3 ETH, and uncle rewards will be adjusted accordingly. ## Motivation The Casper development and switch to Proof-of-Stake is delayed, the Proof-of-Work should be feasible for miners and create new blocks every 15 seconds on average for another 1.4 years. The incentive to continue mining the Proof-of-Work chain after a potential move to Proof-of-Stake is reduced by adjusting block rewards. @@ -22,22 +22,22 @@ The Casper development and switch to Proof-of-Stake is delayed, the Proof-of-Wor #### Relax Difficulty with Fake Block Number For the purposes of `calc_difficulty`, simply replace the use of `block.number`, as used in the exponential ice age component, with the formula: - fake_block_number = block.number - 3_000_000 if block.number >= METROPOLIS_FORK_BLKNUM else block.number + fake_block_number = block.number - 3_000_000 if block.number >= BYZANTIUM_FORK_BLKNUM else block.number #### Adjust Block, Uncle, and Nephew rewards To add an issuance reduction, adjust the block reward to `new_block_reward`, where - new_block_reward = 3_000_000_000_000_000_000 if block.number >= METROPOLIS_FORK_BLKNUM else block.reward + new_block_reward = 3_000_000_000_000_000_000 if block.number >= BYZANTIUM_FORK_BLKNUM else block.reward (3E18 wei, or 3,000,000,000,000,000,000 wei, or 3 ETH). -Analogue, if an uncle is included in a block for `block.number >= METROPOLIS_FORK_BLKNUM` such that `block.number - uncle.number = k`, the uncle reward is +Analogue, if an uncle is included in a block for `block.number >= BYZANTIUM_FORK_BLKNUM` such that `block.number - uncle.number = k`, the uncle reward is new_uncle_reward = (8 - k) * new_block_reward / 8 This is the existing pre-Metropolis formula for uncle rewards, simply adjusted with `new_block_reward`. -The nephew reward for `block.number >= METROPOLIS_FORK_BLKNUM` is +The nephew reward for `block.number >= BYZANTIUM_FORK_BLKNUM` is new_nephew_reward = new_block_reward / 32 @@ -48,10 +48,10 @@ This will delay the ice age by 42 million seconds ~= 1.4 years, so the chain wou This was previously discussed at All Core Devs Meeting [#09](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%209.md#metropolis-timing-and-roadmap-discussion), [#12](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2012.md#5-metropolis-update), [#13](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2013.md#3-eip-186-reduce-eth-issuance-before-proof-of-stake-hudson), and [#14](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2014.md#1-eip-186-reduce-eth-issuance-before-proof-of-stake-core-devs). Consensus on the specification was achieved in All Core Devs Meeting [#19](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2019.md) and specification drafted in EIP issue [#649](https://github.com/ethereum/EIPs/issues/649). -It was decided to replace EIP [#186](https://github.com/ethereum/EIPs/issues/186) and include the issuance reduction along with the difficulty bomb delay in All Core Devs Meeting [#20](#) and [#21](#). +It was decided to replace EIP [#186](https://github.com/ethereum/EIPs/issues/186) and include the issuance reduction along with the difficulty bomb delay in All Core Devs Meeting [#20](#) and [#21](#); accepted in [#22](#). ## Backwards Compatibility -This EIP is not forward compatible and introduces backwards incompatibilities in the difficulty calculation, as well as the block, uncle and nephew reward structure. Therefore, it should be included in a scheduled hardfork at a certain block number. It's suggested to include this EIP in the Metropolis fork. +This EIP is not forward compatible and introduces backwards incompatibilities in the difficulty calculation, as well as the block, uncle and nephew reward structure. Therefore, it should be included in a scheduled hardfork at a certain block number. It's suggested to include this EIP in the first of the two Metropolis hard-forks, the _Byzantium_ fork. ## Test Cases No test cases exist yet. But will be easy to set up based on the rules specified above. From a37720f35f0b88f930a61008cb51a24db06c140b Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Tue, 15 Aug 2017 11:44:08 +0200 Subject: [PATCH 0201/1085] Move eip-649 to accepted as per CDM-22 --- README.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/README.md b/README.md index afc5f8e28ae05..010fbb66f037e 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,6 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP * **Final** - an EIP that has been adopted in a previous hard fork (for Core/Consensus layer EIPs). * **Deferred** - an EIP that is not being considered for immediate adoption. May be reconsidered in the future for a subsequent hard fork. -# EIPs under consideration -| Number |Title | Author | Layer | Status | -| ------------------------------------------------------ | ----------------------------------------------------------------------------------- | -------------------- | ------------| ----------| -| [649](https://github.com/ethereum/EIPs/pull/669) | Metropolis Difficulty Bomb Delay and Issuance Reduction | Schoedon, Buterin | Core | Draft | - - # Accepted EIPs (planned for adoption) | Number |Title | Author | Layer | Status | | ------------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ------------| ----------| @@ -29,6 +23,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [198](https://github.com/ethereum/EIPs/pull/198) | Precompiled contract for bigint modular exponentiation | Vitalik Buterin | Core | Accepted | | [211](https://github.com/ethereum/EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner| Core | Accepted | | [214](https://github.com/ethereum/EIPs/pull/214) | New opcode STATICCALL | Buterin, Reitwiessner | Core | Accepted | +| [649](https://github.com/ethereum/EIPs/pull/669) | Metropolis Difficulty Bomb Delay and Issuance Reduction | Schoedon, Buterin | Core | Draft | # Finalized EIPs (standards that have been adopted) From 935a4ddfaa995e63af8ddf88028baaa141b53403 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Mon, 14 Aug 2017 17:15:43 -0400 Subject: [PATCH 0202/1085] add EIP 649 (difficulty bomb and issuance reduction) to accepted table --- README.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/README.md b/README.md index d16f0a1d29313..f8ced9dc6f8e4 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,6 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP * **Final** - an EIP that has been adopted in a previous hard fork (for Core/Consensus layer EIPs). * **Deferred** - an EIP that is not being considered for immediate adoption. May be reconsidered in the future for a subsequent hard fork. -# EIPs under consideration -| Number |Title | Author | Layer | Status | -| ------------------------------------------------------ | ----------------------------------------------------------------------------------- | -------------------- | ------------| ----------| -| [186](https://github.com/ethereum/EIPs/issues/186) | Reduce ETH issuance before proof-of-stake | Matthew Light | Core | Draft | - - # Accepted EIPs (planned for adoption) | Number |Title | Author | Layer | Status | | ------------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ------------| ----------| @@ -26,6 +20,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [198](https://github.com/ethereum/EIPs/pull/198) | Precompiled contract for bigint modular exponentiation | Vitalik Buterin | Core | Accepted | | [211](https://github.com/ethereum/EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner| Core | Accepted | | [214](https://github.com/ethereum/EIPs/pull/214) | New opcode STATICCALL | Buterin, Reitwiessner | Core | Accepted | +| [649](https://github.com/ethereum/EIPs/pull/669) | Metropolis Difficulty Bomb Delay and Issuance Reduction | Schoedon, Buterin | Core | Accepted | | [658](https://github.com/ethereum/EIPs/pull/658) | Embedding transaction return data in receipts | Nick Johnson | Core | Accepted | # Deferred EIPs (adoption postponed) From b469503c5963bfb980cc75d0b84402d0a32b5494 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Tue, 15 Aug 2017 09:36:45 -0400 Subject: [PATCH 0203/1085] update links to ref files, not issues --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f8ced9dc6f8e4..e14a400c35e70 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,11 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP # Accepted EIPs (planned for adoption) | Number |Title | Author | Layer | Status | | ------------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ------------| ----------| -| [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Core | Accepted | +| [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Core | Accepted | | [140](https://github.com/ethereum/EIPs/pull/206) | REVERT instruction in the Ethereum Virtual Machine | Beregszaszi, Mushegian| Core | Accepted | | [196](https://github.com/ethereum/EIPs/pull/213) | Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 | Reitwiessner | Core | Accepted | | [197](https://github.com/ethereum/EIPs/pull/212) | Precompiled contracts for optimal Ate pairing check on the elliptic curve alt_bn128 | Buterin, Reitwiessner | Core | Accepted | -| [198](https://github.com/ethereum/EIPs/pull/198) | Precompiled contract for bigint modular exponentiation | Vitalik Buterin | Core | Accepted | +| [198](https://github.com/ethereum/EIPs/pull/198) | Precompiled contract for bigint modular exponentiation | Vitalik Buterin | Core | Accepted | | [211](https://github.com/ethereum/EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner| Core | Accepted | | [214](https://github.com/ethereum/EIPs/pull/214) | New opcode STATICCALL | Buterin, Reitwiessner | Core | Accepted | | [649](https://github.com/ethereum/EIPs/pull/669) | Metropolis Difficulty Bomb Delay and Issuance Reduction | Schoedon, Buterin | Core | Accepted | @@ -32,13 +32,13 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP # Finalized EIPs (standards that have been adopted) | Number |Title | Author | Layer | Status | | ------------------------------------------------------- | ----------------------------------------------------------- | ----------------| ------------| --------| -| [2](EIPS/eip-2.md) | Homestead Hard-fork Changes | Vitalik Buterin | Core | Final | +| [2](EIPS/eip-2.md) | Homestead Hard-fork Changes | Vitalik Buterin | Core | Final | | [6](EIPS/eip-6.md) | Renaming Suicide Opcode | Hudson Jameson | Interface | Final | | [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Core | Final | | [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Networking | Final | | [141](EIPS/eip-141.md) | Designated invalid EVM instruction | Alex Beregsazszi| Core | Final | -| [150](https://github.com/ethereum/EIPs/issues/150) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Core | Final | -| [155](https://github.com/ethereum/EIPs/issues/155) | Simple replay attack protection | Vitalik Buterin | Core | Final | -| [160](https://github.com/ethereum/EIPs/issues/160) | EXP cost increase | Vitalik Buterin | Core | Final | -| [161](https://github.com/ethereum/EIPs/issues/161) | State trie clearing (invariant-preserving alternative) | Gavin Wood | Core | Final | -| [170](https://github.com/ethereum/EIPs/issues/170) | Contract code size limit | Vitalik Buterin | Core | Final | +| [150](EIPS/eip-150.md) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Core | Final | +| [155](EIPS/eip-155.md) | Simple replay attack protection | Vitalik Buterin | Core | Final | +| [160](EIPS/eip-160.md) | EXP cost increase | Vitalik Buterin | Core | Final | +| [161](EIPS/eip-161.md) | State trie clearing (invariant-preserving alternative) | Gavin Wood | Core | Final | +| [170](EIPS/eip-170.md) | Contract code size limit | Vitalik Buterin | Core | Final | From 465c4d655045a404eca23014a0850e5f245dbcc0 Mon Sep 17 00:00:00 2001 From: Hudson Jameson Date: Tue, 15 Aug 2017 08:50:56 -0500 Subject: [PATCH 0204/1085] Corrected typo in "Beregszaszi" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e14a400c35e70..0949e49cadf2f 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [6](EIPS/eip-6.md) | Renaming Suicide Opcode | Hudson Jameson | Interface | Final | | [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Core | Final | | [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Networking | Final | -| [141](EIPS/eip-141.md) | Designated invalid EVM instruction | Alex Beregsazszi| Core | Final | +| [141](EIPS/eip-141.md) | Designated invalid EVM instruction | Alex Beregszaszi| Core | Final | | [150](EIPS/eip-150.md) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Core | Final | | [155](EIPS/eip-155.md) | Simple replay attack protection | Vitalik Buterin | Core | Final | | [160](EIPS/eip-160.md) | EXP cost increase | Vitalik Buterin | Core | Final | From 6feeb362e4b4af27eb5b4c1cd53130868ed84371 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Tue, 15 Aug 2017 10:15:24 -0400 Subject: [PATCH 0205/1085] amend 161 (state trie clearing) to clarify revert behavior --- EIPS/eip-161.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/EIPS/eip-161.md b/EIPS/eip-161.md index e9364563ef2c9..bd73c60a05106 100644 --- a/EIPS/eip-161.md +++ b/EIPS/eip-161.md @@ -50,7 +50,13 @@ Same as #158 except that several edge cases are avoided since we do not break in `CREATE` avoids zero in the nonce to avoid any suggestion of the oddity of `CREATE`d accounts being reaped half-way through their creation. +# Addendum (2017-08-15) + +On 2016-11-24, a consensus bug occurred due to two implementations having different behavior in the case of state reverts.[3] The specification was amended to clarify that empty account deletions are reverted when the state is reverted. + # References 1. EIP-158 issue and discussion: https://github.com/ethereum/EIPs/issues/158 2. EIP-161 issue and discussion: https://github.com/ethereum/EIPs/issues/161 +3. https://blog.ethereum.org/2016/11/25/security-alert-11242016-consensus-bug-geth-v1-4-19-v1-5-2/ +> Details: Geth was failing to revert empty account deletions when the transaction causing the deletions of empty accounts ended with an an out-of-gas exception. An additional issue was found in Parity, where the Parity client incorrectly failed to revert empty account deletions in a more limited set of contexts involving out-of-gas calls to precompiled contracts; the new Geth behavior matches Parity’s, and empty accounts will cease to be a source of concern in general in about one week once the state clearing process finishes. From 0aa35f0e058557a340541f7f867ba7beb05fbe39 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Tue, 15 Aug 2017 11:34:17 -0400 Subject: [PATCH 0206/1085] create file for EIP 100 --- EIPS/eip-100.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 EIPS/eip-100.md diff --git a/EIPS/eip-100.md b/EIPS/eip-100.md new file mode 100644 index 0000000000000..8f8f88a9a116e --- /dev/null +++ b/EIPS/eip-100.md @@ -0,0 +1,33 @@ +EDITOR NOTE: below is a copy of the EIP 100 https://github.com/ethereum/EIPs/issues/100#issue-151777532 raw text fetched on 2017-08-15. + +### Specification + +Currently, the formula to compute the difficulty of a block includes the following logic: + +``` python +adj_factor = max(1 - ((timestamp - parent.timestamp) // 10), -99) +child_diff = int(max(parent.difficulty + (parent.difficulty // BLOCK_DIFF_FACTOR) * adj_factor, min(parent.difficulty, MIN_DIFF))) +... +``` + +If `block.number >= METROPOLIS_FORK_BLKNUM`, we change the first line to the following: + +``` python +adj_factor = max(1 + len(parent.uncles) - ((timestamp - parent.timestamp) // 9), -99) +``` +### Specification (1b) + +``` python +adj_factor = max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99) +``` +### Rationale + +This new formula ensures that the difficulty adjustment algorithm targets a constant average rate of blocks produced including uncles, and so ensures a highly predictable issuance rate that cannot be manipulated upward by manipulating the uncle rate. The formula can be fairly easily seen to be (to within a tolerance of ~3/4194304) mathematically equivalent to assuming that a block with `k` uncles is equivalent to a sequence of `k+1` blocks that all appear with the exact same timestamp, and this is likely the simplest possible way to accomplish the desired effect. + +Changing the denominator from 10 to 9 ensures that the block time remains roughly the same (in fact, it should decrease by ~3% given the current uncle rate of 7%). + +(1b) accomplishes almost the same effect but has the benefit that it depends only on the block header (as you can check the uncle hash against the blank hash) and not the entire block. + +### Update 2017.06.29 + +Version (1b) was chosen. From e136656ccabab0c04b3874e72abe085cdb7e75d2 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Tue, 15 Aug 2017 11:36:05 -0400 Subject: [PATCH 0207/1085] add preamble to EIP 100 --- EIPS/eip-100.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-100.md b/EIPS/eip-100.md index 8f8f88a9a116e..7732e45214e53 100644 --- a/EIPS/eip-100.md +++ b/EIPS/eip-100.md @@ -1,4 +1,12 @@ -EDITOR NOTE: below is a copy of the EIP 100 https://github.com/ethereum/EIPs/issues/100#issue-151777532 raw text fetched on 2017-08-15. +``` +EIP: 100 +Title: Change difficulty adjustment to target mean block time including uncles +Author: Vitalik Buterin +Type: Standard Track +Category: Core +Status: Accepted +Created: 2016-04-28 +``` ### Specification From 04886529d494e88628d0d302426356e70399c6c8 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Tue, 15 Aug 2017 15:36:53 -0400 Subject: [PATCH 0208/1085] EIP 100: specify only the chosen version --- EIPS/eip-100.md | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/EIPS/eip-100.md b/EIPS/eip-100.md index 7732e45214e53..44433968baf3c 100644 --- a/EIPS/eip-100.md +++ b/EIPS/eip-100.md @@ -20,22 +20,15 @@ child_diff = int(max(parent.difficulty + (parent.difficulty // BLOCK_DIFF_FACTOR If `block.number >= METROPOLIS_FORK_BLKNUM`, we change the first line to the following: -``` python -adj_factor = max(1 + len(parent.uncles) - ((timestamp - parent.timestamp) // 9), -99) -``` -### Specification (1b) - ``` python adj_factor = max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99) ``` ### Rationale -This new formula ensures that the difficulty adjustment algorithm targets a constant average rate of blocks produced including uncles, and so ensures a highly predictable issuance rate that cannot be manipulated upward by manipulating the uncle rate. The formula can be fairly easily seen to be (to within a tolerance of ~3/4194304) mathematically equivalent to assuming that a block with `k` uncles is equivalent to a sequence of `k+1` blocks that all appear with the exact same timestamp, and this is likely the simplest possible way to accomplish the desired effect. +This new formula ensures that the difficulty adjustment algorithm targets a constant average rate of blocks produced including uncles, and so ensures a highly predictable issuance rate that cannot be manipulated upward by manipulating the uncle rate. A formula that accounts for the exact number of included uncles: +``` python +adj_factor = max(1 + len(parent.uncles) - ((timestamp - parent.timestamp) // 9), -99) +``` +can be fairly easily seen to be (to within a tolerance of ~3/4194304) mathematically equivalent to assuming that a block with `k` uncles is equivalent to a sequence of `k+1` blocks that all appear with the exact same timestamp, and this is likely the simplest possible way to accomplish the desired effect. But since the exact formula depends on the full block and not just the header, we are instead using an approximate formula that accomplishes almost the same effect but has the benefit that it depends only on the block header (as you can check the uncle hash against the blank hash). Changing the denominator from 10 to 9 ensures that the block time remains roughly the same (in fact, it should decrease by ~3% given the current uncle rate of 7%). - -(1b) accomplishes almost the same effect but has the benefit that it depends only on the block header (as you can check the uncle hash against the blank hash) and not the entire block. - -### Update 2017.06.29 - -Version (1b) was chosen. From a6fe8b4755963e1ad80ce5246591d3a7b02463a0 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Tue, 15 Aug 2017 15:42:38 -0400 Subject: [PATCH 0209/1085] EIP 100: add references --- EIPS/eip-100.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/EIPS/eip-100.md b/EIPS/eip-100.md index 44433968baf3c..2d631de37100e 100644 --- a/EIPS/eip-100.md +++ b/EIPS/eip-100.md @@ -32,3 +32,8 @@ adj_factor = max(1 + len(parent.uncles) - ((timestamp - parent.timestamp) // 9), can be fairly easily seen to be (to within a tolerance of ~3/4194304) mathematically equivalent to assuming that a block with `k` uncles is equivalent to a sequence of `k+1` blocks that all appear with the exact same timestamp, and this is likely the simplest possible way to accomplish the desired effect. But since the exact formula depends on the full block and not just the header, we are instead using an approximate formula that accomplishes almost the same effect but has the benefit that it depends only on the block header (as you can check the uncle hash against the blank hash). Changing the denominator from 10 to 9 ensures that the block time remains roughly the same (in fact, it should decrease by ~3% given the current uncle rate of 7%). + +### References + +1. EIP 100 issue and discussion: https://github.com/ethereum/EIPs/issues/100 +2. https://bitslog.wordpress.com/2016/04/28/uncle-mining-an-ethereum-consensus-protocol-flaw/ From e9f741ab1f2ab643f1c3323c456f119585a58ff8 Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Thu, 17 Aug 2017 09:54:18 +0200 Subject: [PATCH 0210/1085] Clarify motivation behind block reward structure, ref #186 --- EIPS/eip-649.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index ff28747d7ebbf..89beaa0d08426 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -2,7 +2,7 @@ EIP: 649 Title: Metropolis Difficulty Bomb Delay and Issuance Reduction - Authors: Afri Schoedon (Champion), Vitalik Buterin (Specification) + Authors: Afri Schoedon, Vitalik Buterin Type: Standard Track Category: Core Status: Draft @@ -10,13 +10,13 @@ Replaces: 186 ## Simple Summary -The average block times are increasing due to the difficulty bomb (also as known as the "ice age") slowly accelerating. This EIP proposes to delay the difficulty bomb for approximately one and a half year and to reduce the block rewards with the Byzantium fork (the first part of the Metropolis fork). +The average block times are increasing due to the difficulty bomb (also known as the "_ice age_") slowly accelerating. This EIP proposes to delay the difficulty bomb for approximately one and a half year and to reduce the block rewards with the Byzantium fork, the first part of the Metropolis fork. ## Abstract -After `BYZANTIUM_FORK_BLKNUM` the client will calculate the difficulty based on a fake block number suggesting the client that the difficulty bomb is adjusting around 3 million blocks later than previously specified with the Homestead fork. Furthermore, to add an issuance reduction, block rewards will be adjusted to a base of 3 ETH, and uncle rewards will be adjusted accordingly. +After `BYZANTIUM_FORK_BLKNUM` the client will calculate the difficulty based on a fake block number suggesting the client that the difficulty bomb is adjusting around 3 million blocks later than previously specified with the Homestead fork. Furthermore, block rewards will be adjusted to a base of 3 ETH, uncle and nephew rewards will be adjusted accordingly. ## Motivation -The Casper development and switch to Proof-of-Stake is delayed, the Proof-of-Work should be feasible for miners and create new blocks every 15 seconds on average for another 1.4 years. The incentive to continue mining the Proof-of-Work chain after a potential move to Proof-of-Stake is reduced by adjusting block rewards. +The Casper development and switch to proof-of-stake is delayed, the Ethash proof-of-work should be feasible for miners and allow sealing new blocks every 15 seconds on average for another one and a half years. With the delay of the ice age, there is a desire to not suddenly also increase miner rewards. The difficulty bomb has been known about for a long time and now it's going to stop from happening. In order to maintain stability of the system, a block reward reduction that offsets the ice age delay would leave the system in the same general state as before. Reducing the reward also decreases the likelihood of a miner driven chain split as Ethereum approaches proof-of-stake. ## Specification #### Relax Difficulty with Fake Block Number @@ -44,11 +44,9 @@ The nephew reward for `block.number >= BYZANTIUM_FORK_BLKNUM` is This is the existing pre-Metropolis formula for nephew rewards, simply adjusted with `new_block_reward`. ## Rationale -This will delay the ice age by 42 million seconds ~= 1.4 years, so the chain would be back at 30 second block times at the end of 2018. An alternate proposal was to add special rules to the difficulty calculation to effectively _pause_ the difficulty between different blocks. That would lead to similar results. +This will delay the ice age by 42 million seconds (approximately 1.4 years), so the chain would be back at 30 second block times at the end of 2018. An alternate proposal was to add special rules to the difficulty calculation to effectively _pause_ the difficulty between different blocks. This would lead to similar results. -This was previously discussed at All Core Devs Meeting [#09](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%209.md#metropolis-timing-and-roadmap-discussion), [#12](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2012.md#5-metropolis-update), [#13](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2013.md#3-eip-186-reduce-eth-issuance-before-proof-of-stake-hudson), and [#14](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2014.md#1-eip-186-reduce-eth-issuance-before-proof-of-stake-core-devs). Consensus on the specification was achieved in All Core Devs Meeting [#19](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2019.md) and specification drafted in EIP issue [#649](https://github.com/ethereum/EIPs/issues/649). - -It was decided to replace EIP [#186](https://github.com/ethereum/EIPs/issues/186) and include the issuance reduction along with the difficulty bomb delay in All Core Devs Meeting [#20](#) and [#21](#); accepted in [#22](#). +This was previously discussed at All Core Devs Meeting [#09](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%209.md#metropolis-timing-and-roadmap-discussion), [#12](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2012.md#5-metropolis-update), [#13](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2013.md#3-eip-186-reduce-eth-issuance-before-proof-of-stake-hudson), and [#14](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2014.md#1-eip-186-reduce-eth-issuance-before-proof-of-stake-core-devs). Consensus on the specification was achieved in All Core Devs Meeting [#19](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2019.md) and specification drafted in EIP issue [#649](https://github.com/ethereum/EIPs/issues/649). It was decided to replace EIP [#186](https://github.com/ethereum/EIPs/issues/186) and include the issuance reduction along with the difficulty bomb delay in All Core Devs Meeting [#20](#) and [#21](#); accepted in [#22](#). ## Backwards Compatibility This EIP is not forward compatible and introduces backwards incompatibilities in the difficulty calculation, as well as the block, uncle and nephew reward structure. Therefore, it should be included in a scheduled hardfork at a certain block number. It's suggested to include this EIP in the first of the two Metropolis hard-forks, the _Byzantium_ fork. From cab7b1f09587098cd715f42f60379bbe8314224a Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Fri, 18 Aug 2017 11:23:42 +0200 Subject: [PATCH 0211/1085] Ensure fake block number is not negative --- EIPS/eip-649.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index 89beaa0d08426..d4022e4b403d8 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -22,7 +22,7 @@ The Casper development and switch to proof-of-stake is delayed, the Ethash proof #### Relax Difficulty with Fake Block Number For the purposes of `calc_difficulty`, simply replace the use of `block.number`, as used in the exponential ice age component, with the formula: - fake_block_number = block.number - 3_000_000 if block.number >= BYZANTIUM_FORK_BLKNUM else block.number + fake_block_number = min(0, block.number - 3_000_000) if block.number >= BYZANTIUM_FORK_BLKNUM else block.number #### Adjust Block, Uncle, and Nephew rewards To add an issuance reduction, adjust the block reward to `new_block_reward`, where From 6744a288785bfd7169fb4e022e37cca9d686de4a Mon Sep 17 00:00:00 2001 From: ia Date: Mon, 21 Aug 2017 11:17:47 -0500 Subject: [PATCH 0212/1085] EIP: Implement method in JSON-RPC. Rel https://github.com/ethereum/go-ethereum/pull/15002 --- EIPS/eip-rpc_eth_chain_id.md | 74 ++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 EIPS/eip-rpc_eth_chain_id.md diff --git a/EIPS/eip-rpc_eth_chain_id.md b/EIPS/eip-rpc_eth_chain_id.md new file mode 100644 index 0000000000000..75ec26de2263b --- /dev/null +++ b/EIPS/eip-rpc_eth_chain_id.md @@ -0,0 +1,74 @@ +## Preamble + + EIP: + Title: Create `eth_chainId` method for JSON-RPC + Author: Isaac Ardis: isaac.ardis@gmail.com, Wei Tang: hi@that.world + Type: Standard Track + Category: Interface + Status: Draft + Created: 2017-08-21 + + +## Simple Summary +Include `eth_chainId` method in `eth_`-namespaced JSON-RPC methods. + +## Abstract +The `eth_chainId` method should return a single STRING result +for an integer value in hexadecimal format, describing the +currently configured "Chain Id" value used for signing replay-protected transactions, +introduced via EIP-155. + +## Motivation +Currently although we can use net_version RPC call to get the +current network ID, there's no RPC for querying the chain ID. This +makes it impossible to determine the current actual blockchain using +the RPC. + +## Specification + +---- + +### eth_chainId + +Returns the currently configured chain id, a value used in replay-protected transaction +signing as introduced by EIP-155. + +##### Parameters +none + +##### Returns + +`QUANTITY` - big integer of the current chain id. Defaults are mainnet=61, morden=62. + +##### Example +```js +curl -X POST --data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' + +// Result +{ + "id":83, + "jsonrpc": "2.0", + "result": "0x3d" // 61 +} +``` + +---- + +## Rationale +An ETH/ETC client can accidentally connect to an ETC/ETH RPC +endpoint without knowing it unless it tries to sign a transaction or +it fetch a transaction that is known to have signed with a chain +ID. This has since caused trouble for application developers, such as +MetaMask, to add multi-chain support. + +## Backwards Compatibility +Not relevant. + +## Test Cases +Not currently implemented. + +## Implementation +Would be good to have a test to confirm that expected==got. + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From b54a4e3d84ff1ea79c7475f3e65245b2601a4c0b Mon Sep 17 00:00:00 2001 From: ia Date: Mon, 21 Aug 2017 11:18:59 -0500 Subject: [PATCH 0213/1085] Include related PR link. --- EIPS/eip-rpc_eth_chain_id.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/EIPS/eip-rpc_eth_chain_id.md b/EIPS/eip-rpc_eth_chain_id.md index 75ec26de2263b..c711064561c3d 100644 --- a/EIPS/eip-rpc_eth_chain_id.md +++ b/EIPS/eip-rpc_eth_chain_id.md @@ -26,6 +26,11 @@ the RPC. ## Specification +__Related PR__: +https://github.com/ethereum/go-ethereum/pull/15002 + +__Example documentation__: + ---- ### eth_chainId From 3a6b4663b963d225ddc93ca3ef415f7c3c540cf7 Mon Sep 17 00:00:00 2001 From: ia Date: Mon, 21 Aug 2017 16:07:02 -0500 Subject: [PATCH 0214/1085] Include @tcz001 as author and add related links --- EIPS/eip-rpc_eth_chain_id.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/EIPS/eip-rpc_eth_chain_id.md b/EIPS/eip-rpc_eth_chain_id.md index c711064561c3d..ab11affe8c207 100644 --- a/EIPS/eip-rpc_eth_chain_id.md +++ b/EIPS/eip-rpc_eth_chain_id.md @@ -2,7 +2,7 @@ EIP: Title: Create `eth_chainId` method for JSON-RPC - Author: Isaac Ardis: isaac.ardis@gmail.com, Wei Tang: hi@that.world + Author: Isaac Ardis: isaac.ardis@gmail.com, Wei Tang: hi@that.world, [@tcz001](https://github.com/tcz001) Type: Standard Track Category: Interface Status: Draft @@ -26,11 +26,6 @@ the RPC. ## Specification -__Related PR__: -https://github.com/ethereum/go-ethereum/pull/15002 - -__Example documentation__: - ---- ### eth_chainId @@ -66,6 +61,12 @@ it fetch a transaction that is known to have signed with a chain ID. This has since caused trouble for application developers, such as MetaMask, to add multi-chain support. +Please note related links: + +- [Parity PR](https://github.com/paritytech/parity/pull/6329) +- [Geth Classic PR (merged)](https://github.com/ethereumproject/go-ethereum/pull/336) + + ## Backwards Compatibility Not relevant. From 2da707c93e53f8522b85910757a6e204a4658d3b Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 24 Aug 2017 11:40:35 +0200 Subject: [PATCH 0215/1085] Add log0 --- EIPS/static_call.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/static_call.md b/EIPS/static_call.md index 5e0b79af90576..41163a22aba7e 100644 --- a/EIPS/static_call.md +++ b/EIPS/static_call.md @@ -30,7 +30,7 @@ Opcode: `0xfa`. `STATICCALL` functions equivalently to a `CALL`, except it takes only 6 arguments (the "value" argument is not included and taken to be zero), and calls the child with the `STATIC` flag set to `true` for the execution of the child. Once this call returns, the flag is reset to its value before the call. -Any attempts to make state-changing operations inside an execution instance with `STATIC` set to `true` will instead throw an exception. These operations include `CREATE`, `CREATE2`, `LOG1`, `LOG2`, `LOG3`, `LOG4`, `SSTORE`, and `SELFDESTRUCT`. They also include `CALL` with a non-zero value. As an exception, `CALLCODE` is not considered state-changing, even with a non-zero value. +Any attempts to make state-changing operations inside an execution instance with `STATIC` set to `true` will instead throw an exception. These operations include `CREATE`, `CREATE2`, `LOG0`, `LOG1`, `LOG2`, `LOG3`, `LOG4`, `SSTORE`, and `SELFDESTRUCT`. They also include `CALL` with a non-zero value. As an exception, `CALLCODE` is not considered state-changing, even with a non-zero value. ## Rationale From e3dff831121549e850fa662a0e6944878dc1ce22 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 24 Aug 2017 12:16:06 +0200 Subject: [PATCH 0216/1085] Clarify return data buffer for failed calls. --- EIPS/returndatacopy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/returndatacopy.md b/EIPS/returndatacopy.md index 1201df21e4954..f8b940854b458 100644 --- a/EIPS/returndatacopy.md +++ b/EIPS/returndatacopy.md @@ -29,7 +29,7 @@ Note that this proposal also makes the EIP that proposes to allow to return data ## Specification -Add two new opcodes and amend the semantics of any opcode that creates a new call frame (like `CALL`, `CREATE`, `DELEGATECALL`, ...) called call-like opcodes in the following. It is assumed that the EVM (to be more specific: an EVM call frame) has a new internal buffer of variable size, called the return data buffer. This buffer is created empty for each new call frame. Upon executing any call-like opcode, the buffer is cleared (its size is set to zero). After executing a call-like opcode, the complete return data (or failure data, see EIP [206](https://github.com/ethereum/EIPs/pull/206)) of the call is stored in the return data buffer (of the caller), and its size changed accordingly. As an exception, `CREATE` and `CREATE2` are considered to return the empty buffer in the success case and the failure data in the failure case. +Add two new opcodes and amend the semantics of any opcode that creates a new call frame (like `CALL`, `CREATE`, `DELEGATECALL`, ...) called call-like opcodes in the following. It is assumed that the EVM (to be more specific: an EVM call frame) has a new internal buffer of variable size, called the return data buffer. This buffer is created empty for each new call frame. Upon executing any call-like opcode, the buffer is cleared (its size is set to zero). After executing a call-like opcode, the complete return data (or failure data, see EIP [206](https://github.com/ethereum/EIPs/pull/206)) of the call is stored in the return data buffer (of the caller), and its size changed accordingly. As an exception, `CREATE` and `CREATE2` are considered to return the empty buffer in the success case and the failure data in the failure case. If the call-like opcode is executed but does not really instanciate a call frame (for example due to insufficient funds for a value transfer or if the called contract does not exist), the return data buffer is empty. As an optimization, it is possible to share the return data buffer across call frames because only one will be non-empty at any time. From 7a946e08b68f54d54ff1311ac742c73985db3b82 Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Fri, 25 Aug 2017 09:25:59 +0200 Subject: [PATCH 0217/1085] Avoid negative block numbers, ref #649. --- EIPS/eip-649.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index d4022e4b403d8..8635e79a7017d 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -22,7 +22,7 @@ The Casper development and switch to proof-of-stake is delayed, the Ethash proof #### Relax Difficulty with Fake Block Number For the purposes of `calc_difficulty`, simply replace the use of `block.number`, as used in the exponential ice age component, with the formula: - fake_block_number = min(0, block.number - 3_000_000) if block.number >= BYZANTIUM_FORK_BLKNUM else block.number + fake_block_number = max(0, block.number - 3_000_000) if block.number >= BYZANTIUM_FORK_BLKNUM else block.number #### Adjust Block, Uncle, and Nephew rewards To add an issuance reduction, adjust the block reward to `new_block_reward`, where From 3eaf90c5379d309f643e20a11ffc441b96c0b185 Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Sat, 26 Aug 2017 11:23:57 +0200 Subject: [PATCH 0218/1085] Add EIP #649 to Byzantium Meta EIP #609 --- EIPS/eip-609.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-609.md b/EIPS/eip-609.md index 66e6cb3418587..e402763a8e415 100644 --- a/EIPS/eip-609.md +++ b/EIPS/eip-609.md @@ -7,7 +7,7 @@ Category: Core Status: Draft Created: 2017-04-23 - Requires: 100, 140, 196, 197, 198, 211, 214 + Requires: 100, 140, 196, 197, 198, 211, 214, 649, 658 ## Abstract @@ -27,6 +27,7 @@ This specifies the changes included in the hard fork named Byzantium. - EIP 198 (Precompiled contract for bigint modular exponentiation) - EIP 211 (New opcodes: RETURNDATASIZE and RETURNDATACOPY) - EIP 214 (New opcode STATICCALL) + - EIP 649 (Difficulty Bomb Delay and Issuance Reduction) - EIP 658 (Embedding transaction return data in receipts) ## Copyright From ce61f00926e2d19f38930d8b3b657964a34956e6 Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Sat, 26 Aug 2017 11:28:01 +0200 Subject: [PATCH 0219/1085] Change EIP #649 status to accepted, ref #688 --- EIPS/eip-649.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index 8635e79a7017d..e36bbfe6c1c95 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -5,7 +5,7 @@ Authors: Afri Schoedon, Vitalik Buterin Type: Standard Track Category: Core - Status: Draft + Status: Accepted Created: 2017-06-21 Replaces: 186 From df687f520816df2ce7604093ea87ff79ae2fde15 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Mon, 4 Sep 2017 17:32:22 +0100 Subject: [PATCH 0220/1085] Update eip-draft-returndata.md --- EIPS/eip-draft-returndata.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-draft-returndata.md b/EIPS/eip-draft-returndata.md index 5377ba1bd754f..92041fb1c3373 100644 --- a/EIPS/eip-draft-returndata.md +++ b/EIPS/eip-draft-returndata.md @@ -12,14 +12,14 @@ ## Abstract -This EIP replaces the intermediate state root field of the receipt with either the contract return data and status, or a hash of that value. +This EIP replaces the intermediate state root field of the receipt with a status code indicating if the top-level call succeeded or failed. ## Motivation With the introduction of the REVERT opcode in EIP140, it is no longer possible for users to assume that a transaction failed iff it consumed all gas. As a result, there is no clear mechanism for callers to determine whether a transaction succeeded and the state changes contained in it were applied. Full nodes can provide RPCs to get a transaction return status and value by replaying the transaction, but fast nodes can only do this for nodes after their pivot point, and light nodes cannot do this at all, making a non-consensus solution impractical. -Instead, we propose to replace the intermediate state root, already obsoleted by EIP98, with either the return status (1 for success, 0 for failure) and any return/revert data, or the hash of the above. This both allows callers to determine success status, and remedies the previous omission of return data from the receipt. +Instead, we propose to replace the intermediate state root, already obsoleted by EIP98, with the return status (1 for success, 0 for failure). This both allows callers to determine success status, and remedies the previous omission of return data from the receipt. ## Specification For blocks where block.number >= METROPOLIS_FORK_BLKNUM, the intermediate state root is replaced by a status code, a single byte with 0 indicating failure (due to any operation that can cause the transaction or top-level call to revert) and 1 indicating success. From 6845cebac04fcce4c5cd2d61561a383f5f461da7 Mon Sep 17 00:00:00 2001 From: "Daniel A. Nagy" Date: Thu, 7 Sep 2017 20:41:21 +0200 Subject: [PATCH 0221/1085] EIP: Major overhaul, taking into account the feedback received. In particular, generalized to supersede ERC 67. --- EIPS/pay_req_url_fmt.md | 43 ++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/EIPS/pay_req_url_fmt.md b/EIPS/pay_req_url_fmt.md index 293ca132f1a07..5573cc3dcff90 100644 --- a/EIPS/pay_req_url_fmt.md +++ b/EIPS/pay_req_url_fmt.md @@ -1,16 +1,17 @@ ## Preamble EIP: - Title: URL Format for Payment Requests + Title: URL Format for Transaction Requests Author: Daniel A. Nagy Type: Standard Track Category: ERC Status: Draft + Replaces: 67 Created: 2017-08-01 - Requires: #20, #137 + Requires: 20 ## Simple Summary -A standard way of representing payment requests in Ethers and ERC #20 tokens as URLs. +A standard way of representing various transactions, especially payment requests in Ethers and ERC #20 tokens as URLs. ## Abstract URLs embedded in QR-codes, hyperlinks in web-pages, emails or chat messages provide for robust cross-application signaling between very loosely coupled applications. A standardized URL format for payment requests allows for instant invocation of the user's preferred wallet application (even if it is a webapp or a swarm đapp), with the correct parameterization of the payment transaction only to be confirmed by the (authenticated) user. @@ -18,37 +19,47 @@ URLs embedded in QR-codes, hyperlinks in web-pages, emails or chat messages prov ## Motivation The convenience of representing payment requests by standard URLs has been a major factor in the wide adoption of Bitcoin. Bringing a similarly convenient mechanism to Ethereum would speed up its acceptance as a payment platform among end-users. In particular, URLs embedded in broadcast Intents are the preferred way of launching applications on the Android operating system and work across practically all applications. Desktop web browsers have a standardized way of defining protocol handlers for URLs with specific protocol specifications. Other desktop applications typically launch the web browser upon encountering a URL. Thus, payment request URLs could be delivered through a very broad, ever growing selection of channels. -Note that this is different from ERC #67, which is a URL format for representing arbitrary transactions and as such is more general and low-level. This ERC deals specifically with the important special case of payment requests. +This specification supersedes ERC #67, which is a URL format for representing arbitrary transactions in a low-level fashion. This ERC focuses specifically on the important special case of payment requests, while allowing for other, ABI-specified transactions. ## Specification ### Syntax Payment request URLs contain "ethpay" in their schema (protocol) part and are constructed as follows: - request = "ethpay" ":" beneficiary_address [ "/" token_contract_address ] [ "?" parameters ] - beneficiary_address = ethereum_address - token_contract_address = ethereum_address - ethereum_address = 40*40HEXDIG / ENS_NAME + request = "ethereum" ":" target_address [ "/" function_name ] [ "?" parameters ] + target_address = ethereum_address + function_name = STRING + ethereum_address = ( "0x" 40*40HEXDIG ) / ENS_NAME parameters = parameter *( "&" parameter ) parameter = key "=" value + key = "value" / "gas" / TYPE + value = number / ethereum_address / STRING + number = [ "-" / "+" ] *DIGIT [ "." 1*DIGIT ] [ ( "e" / "E" ) [ 1*DIGIT ] -At present, the only `key` defined is `amount` and the corresponding `value` is a decimal number. Thus: +Where `TYPE` is a standard ABI type name, as defined in [Ethereum Contract ABI specification](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI). `STRING` is a URL-encoded unicode string of arbitrary length, where delimiters and the percentage symbol (`%`) are mandatorily hex-encoded with a `%` prefix. - key = "amount" - value = *DIGIT [ "." 1*DIGIT ] +Note that a `number` can be expressed in *scientific notation*, with a multiplier of a power of 10. The use of this notation is strongly encouraged when expressing monetary value in Ethers or ERC #20 tokens in atomic units (e. g. Wei, in case of Ether). + +If *key* in the parameter list is `value` or `gas` then *value* MUST be a `number`. Otherwise, it must correspond to the `TYPE` string used as *key*. For the syntax of ENS_NAME, please consult ERC #137 defining Ethereum Name Service. ### Semantics -If `token_contract_address` is missing, then the payment is requested in the native token of the blockchain, which is Ether in our case. The only mandatory field `beneficiary_address` denotes the address of the account to be credited with the requested token. -Thus, if `token_contract_address` is missing, the target address of the transaction is `beneficiary_address`, otherwise it is `token_contract_address`, with the appropriate transaction data, as defined in ERC #20 indicating the transfer of the given amount of tokens. +`target_address` is mandatory and denotes either the beneficiary of native token payment (see below) or the contract address with which the user is asked to interact. + +If `function_name` is missing, then the URL is requesting payment in the native token of the blockchain, which is Ether in our case. The amount is specified in `value` parameter, in the atomic unit (i.e. Wei). The use of scientific notation is strongly encouraged. For example, requesting 2.014 ETH to address `0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359` would look as follows: +[ethereum:0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359?value=2.014e18](ethereum:0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359?value=2.014e18) + +Requesting payments in ERC #20 tokens involves a request to call the `transfer` function of the token contract with an `address` and a `uint256` typed parameter, containing the *beneficiary address* and the *amount in atomic units*, respectively. For example, +requesting a Unicorn to address `0x8e23ee67d1332ad560396262c48ffbb01f93d052` looks as follows: +[ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7/transfer?address=0x8e23ee67d1332ad560396262c48ffbb01f93d052&uint256=1](ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7/transfer?address=0x8e23ee67d1332ad560396262c48ffbb01f93d052&uint256=1) If using ENS names instead of hexadecimal addresses, the resolution is up to the payer, at any time between receiving the URL and sending the transaction. Hexadecimal addresses always take precedence over ENS names, i. e. even if there exists a matching ENS name consisting of 40 hexadecimal digits, it should never be resolved. Instead, the hexadecimal address should be used directly. -The amount is to be interpreted in the decimal definition of the token, NOT the atomic unit. In case of Ether, it needs to be multiplied by 10^18 to get the integer amount in Wei. For other tokens, the decimal value should be read from the token contract before conversion. +If the payer client has access to the blockchain, the interface should display the amount in the units as specified in the token contract. Otherwise, it should be displayed as expressed in the URL. -Note that the indicated amount is only a suggestion and the user is free to change it. With no indicated amount, the user should be prompted to enter the amount to be paid. In case of multiple suggestions, the user should have the option of choosing one or enter their own. +Note that the indicated amount is only a suggestion (as are all the supplied arguments) which the user is free to change. With no indicated amount, the user should be prompted to enter the amount to be paid. ## Rationale -The proposed format is chosen to resemble `bitcoin:` URLs as closely as possible, as both users and application programmers are already familiar with that format. In particular, this motivated the omission of the unit, which is often used in Ethereum ecosystem. Handling different orders of magnitude is delegated to the application, just like in the case of `bitcoin:`. Additional parameters may be added, if popular use cases requiring them emerge in practice. +The proposed format is chosen to resemble `bitcoin:` URLs as closely as possible, as both users and application programmers are already familiar with that format. In particular, this motivated the omission of the unit, which is often used in Ethereum ecosystem. Handling different orders of magnitude is delegated to the application, just like in the case of `bitcoin:`, but lacking access to the block chain, the application can take a hint from the exponent in the URL. Additional parameters may be added, if popular use cases requiring them emerge in practice. From fcc7b9ee4df74b2fab1745a1151d279d2d896c7a Mon Sep 17 00:00:00 2001 From: "Daniel A. Nagy" Date: Thu, 7 Sep 2017 21:38:47 +0200 Subject: [PATCH 0222/1085] EIP: fixes missing s/ethpay/ethereum --- EIPS/pay_req_url_fmt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/pay_req_url_fmt.md b/EIPS/pay_req_url_fmt.md index 5573cc3dcff90..6f7f1095c093b 100644 --- a/EIPS/pay_req_url_fmt.md +++ b/EIPS/pay_req_url_fmt.md @@ -24,7 +24,7 @@ This specification supersedes ERC #67, which is a URL format for representing ar ## Specification ### Syntax -Payment request URLs contain "ethpay" in their schema (protocol) part and are constructed as follows: +Payment request URLs contain "ethereum" in their schema (protocol) part and are constructed as follows: request = "ethereum" ":" target_address [ "/" function_name ] [ "?" parameters ] target_address = ethereum_address From c82890ed92b35d83df0610841b19b15e865da545 Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Fri, 8 Sep 2017 09:18:04 +0200 Subject: [PATCH 0223/1085] Improve wording for exact block number targeted, ref #649. --- EIPS/eip-649.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index 8635e79a7017d..6838c10f96105 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -13,7 +13,7 @@ The average block times are increasing due to the difficulty bomb (also known as the "_ice age_") slowly accelerating. This EIP proposes to delay the difficulty bomb for approximately one and a half year and to reduce the block rewards with the Byzantium fork, the first part of the Metropolis fork. ## Abstract -After `BYZANTIUM_FORK_BLKNUM` the client will calculate the difficulty based on a fake block number suggesting the client that the difficulty bomb is adjusting around 3 million blocks later than previously specified with the Homestead fork. Furthermore, block rewards will be adjusted to a base of 3 ETH, uncle and nephew rewards will be adjusted accordingly. +Starting with `BYZANTIUM_FORK_BLKNUM` the client will calculate the difficulty based on a fake block number suggesting the client that the difficulty bomb is adjusting around 3 million blocks later than previously specified with the Homestead fork. Furthermore, block rewards will be adjusted to a base of 3 ETH, uncle and nephew rewards will be adjusted accordingly. ## Motivation The Casper development and switch to proof-of-stake is delayed, the Ethash proof-of-work should be feasible for miners and allow sealing new blocks every 15 seconds on average for another one and a half years. With the delay of the ice age, there is a desire to not suddenly also increase miner rewards. The difficulty bomb has been known about for a long time and now it's going to stop from happening. In order to maintain stability of the system, a block reward reduction that offsets the ice age delay would leave the system in the same general state as before. Reducing the reward also decreases the likelihood of a miner driven chain split as Ethereum approaches proof-of-stake. From 03deb55b0f19d7cea0c6668436796966dadae978 Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Fri, 8 Sep 2017 10:55:37 +0200 Subject: [PATCH 0224/1085] Update existing implementations --- EIPS/eip-649.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index b55c6f84dd8c5..801baa261c78b 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -55,7 +55,10 @@ This EIP is not forward compatible and introduces backwards incompatibilities in No test cases exist yet. But will be easy to set up based on the rules specified above. ## Implementation -None existing client implementation exists yet. +The following clients implemented EIP-649: + +- Geth [#15028](https://github.com/ethereum/go-ethereum/pull/15028) +- EthereumJ [#927](https://github.com/ethereum/ethereumj/pull/927) ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 5cd738143b4347595e03f414166e6b9a22fc0126 Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Fri, 8 Sep 2017 14:53:41 +0200 Subject: [PATCH 0225/1085] Improve title to make sure the issuance is not reduced, ref #186 --- EIPS/eip-609.md | 2 +- EIPS/eip-649.md | 6 +++--- README.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/EIPS/eip-609.md b/EIPS/eip-609.md index e402763a8e415..714a5bdeacbf4 100644 --- a/EIPS/eip-609.md +++ b/EIPS/eip-609.md @@ -27,7 +27,7 @@ This specifies the changes included in the hard fork named Byzantium. - EIP 198 (Precompiled contract for bigint modular exponentiation) - EIP 211 (New opcodes: RETURNDATASIZE and RETURNDATACOPY) - EIP 214 (New opcode STATICCALL) - - EIP 649 (Difficulty Bomb Delay and Issuance Reduction) + - EIP 649 (Difficulty Bomb Delay and Block Reward Reduction) - EIP 658 (Embedding transaction return data in receipts) ## Copyright diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index 801baa261c78b..b40e8502dc696 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -1,7 +1,7 @@ ## Preamble EIP: 649 - Title: Metropolis Difficulty Bomb Delay and Issuance Reduction + Title: Metropolis Difficulty Bomb Delay and Block Reward Reduction Authors: Afri Schoedon, Vitalik Buterin Type: Standard Track Category: Core @@ -25,7 +25,7 @@ For the purposes of `calc_difficulty`, simply replace the use of `block.number`, fake_block_number = max(0, block.number - 3_000_000) if block.number >= BYZANTIUM_FORK_BLKNUM else block.number #### Adjust Block, Uncle, and Nephew rewards -To add an issuance reduction, adjust the block reward to `new_block_reward`, where +To ensure a constant Ether issuance, adjust the block reward to `new_block_reward`, where new_block_reward = 3_000_000_000_000_000_000 if block.number >= BYZANTIUM_FORK_BLKNUM else block.reward @@ -46,7 +46,7 @@ This is the existing pre-Metropolis formula for nephew rewards, simply adjusted ## Rationale This will delay the ice age by 42 million seconds (approximately 1.4 years), so the chain would be back at 30 second block times at the end of 2018. An alternate proposal was to add special rules to the difficulty calculation to effectively _pause_ the difficulty between different blocks. This would lead to similar results. -This was previously discussed at All Core Devs Meeting [#09](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%209.md#metropolis-timing-and-roadmap-discussion), [#12](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2012.md#5-metropolis-update), [#13](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2013.md#3-eip-186-reduce-eth-issuance-before-proof-of-stake-hudson), and [#14](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2014.md#1-eip-186-reduce-eth-issuance-before-proof-of-stake-core-devs). Consensus on the specification was achieved in All Core Devs Meeting [#19](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2019.md) and specification drafted in EIP issue [#649](https://github.com/ethereum/EIPs/issues/649). It was decided to replace EIP [#186](https://github.com/ethereum/EIPs/issues/186) and include the issuance reduction along with the difficulty bomb delay in All Core Devs Meeting [#20](#) and [#21](#); accepted in [#22](#). +This was previously discussed at All Core Devs Meeting [#09](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%209.md#metropolis-timing-and-roadmap-discussion), [#12](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2012.md#5-metropolis-update), [#13](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2013.md#3-eip-186-reduce-eth-issuance-before-proof-of-stake-hudson), and [#14](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2014.md#1-eip-186-reduce-eth-issuance-before-proof-of-stake-core-devs). Consensus on the specification was achieved in All Core Devs Meeting [#19](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2019.md) and specification drafted in EIP issue [#649](https://github.com/ethereum/EIPs/issues/649). It was decided to replace EIP [#186](https://github.com/ethereum/EIPs/issues/186) and include the block reward reduction along with the difficulty bomb delay in All Core Devs Meeting [#20](#) and [#21](#); accepted in [#22](#). ## Backwards Compatibility This EIP is not forward compatible and introduces backwards incompatibilities in the difficulty calculation, as well as the block, uncle and nephew reward structure. Therefore, it should be included in a scheduled hardfork at a certain block number. It's suggested to include this EIP in the first of the two Metropolis hard-forks, the _Byzantium_ fork. diff --git a/README.md b/README.md index 0949e49cadf2f..46f4abd12e7f7 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [198](https://github.com/ethereum/EIPs/pull/198) | Precompiled contract for bigint modular exponentiation | Vitalik Buterin | Core | Accepted | | [211](https://github.com/ethereum/EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner| Core | Accepted | | [214](https://github.com/ethereum/EIPs/pull/214) | New opcode STATICCALL | Buterin, Reitwiessner | Core | Accepted | -| [649](https://github.com/ethereum/EIPs/pull/669) | Metropolis Difficulty Bomb Delay and Issuance Reduction | Schoedon, Buterin | Core | Accepted | +| [649](https://github.com/ethereum/EIPs/pull/669) | Metropolis Difficulty Bomb Delay and Block Reward Reduction | Schoedon, Buterin | Core | Accepted | | [658](https://github.com/ethereum/EIPs/pull/658) | Embedding transaction return data in receipts | Nick Johnson | Core | Accepted | # Deferred EIPs (adoption postponed) From 619b19cb85e42d6e18c2e0030c69d47765906e5b Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Mon, 11 Sep 2017 09:55:57 +0200 Subject: [PATCH 0226/1085] Add yellow paper and parity implementations. --- EIPS/eip-649.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index b40e8502dc696..8143e16a63320 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -58,7 +58,10 @@ No test cases exist yet. But will be easy to set up based on the rules specified The following clients implemented EIP-649: - Geth [#15028](https://github.com/ethereum/go-ethereum/pull/15028) +- Parity [#5855](https://github.com/paritytech/parity/pull/5855) - EthereumJ [#927](https://github.com/ethereum/ethereumj/pull/927) +The Yellow Paper implements EIP-649 in [#333](https://github.com/ethereum/yellowpaper/pull/333). + ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 0063de10b489b4eba9ec505dcd573a9c19966326 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 11 Sep 2017 11:41:19 +0200 Subject: [PATCH 0227/1085] Added gas costs. --- EIPS/ecopts.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/EIPS/ecopts.md b/EIPS/ecopts.md index d9cebd8f8c3d9..614f4ac1361b8 100644 --- a/EIPS/ecopts.md +++ b/EIPS/ecopts.md @@ -64,7 +64,8 @@ Fails on invalid input and consumes all gas. ### Gas costs -To be determined. + - Gas cost for ``ECADD``: 500 + - Gas cost for ``ECMUL``: 40000 ## Rationale From 9961da4c77659c6217eae41130c3a40d3f526ac4 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 11 Sep 2017 14:35:38 +0200 Subject: [PATCH 0228/1085] Gas costs. --- EIPS/pairings.md | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/EIPS/pairings.md b/EIPS/pairings.md index 276342300f0d1..793cd3e1bc7cc 100644 --- a/EIPS/pairings.md +++ b/EIPS/pairings.md @@ -85,15 +85,8 @@ The length of the returned data is always exactly 32 bytes and encoded as a 32 b ### Gas costs -[Benchmarks run on cpp-ethereum](https://gist.github.com/chriseth/4168b56bfe638cae8da1945dd988600b) - -suggest the following gas formula: - -`60000 * k + 40000` - -if we target 20000 gas per millisecond. - -Awaiting benchmarks from other implementations. +The gas costs of the precompiled contract are `80 000 * k + 100 000`, where `k` is the number of +points or, equivalently, the length of the input divided by 192. ## Rationale From 7f9a46bfe56c6373be4d9f648835682cdb6f7db9 Mon Sep 17 00:00:00 2001 From: Fabian Vogelsteller Date: Mon, 24 Apr 2017 15:37:03 +0200 Subject: [PATCH 0229/1085] added erc20 --- EIPS/eip-token-standard.md | 113 +++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 EIPS/eip-token-standard.md diff --git a/EIPS/eip-token-standard.md b/EIPS/eip-token-standard.md new file mode 100644 index 0000000000000..a7ffa494422c0 --- /dev/null +++ b/EIPS/eip-token-standard.md @@ -0,0 +1,113 @@ +This is the suggested template for new EIPs. + +Note that an EIP number will be assigned by an editor. When opening a pull request to submit your EIP, please use an abbreviated title in the filename, `eip-draft_title_abbrev.md`. + +## Preamble + + EIP: (I Suggest 20) + Title: + Author: Fabian Vogelsteller , Vitalik Buterin + Type: Informational + Category ERC + Status: Draft + Created: 2015-11-19 + + +## Simple Summary + +Token standard interface. + + +## Abstract + +The following standard allows for people to implement a token standard API withing their smart contracts. + +This standard provides basic functionality for sending and approving tokens to be spend by a third party. + + +## Motivation + +Following the same standard interface allows those tokens to be used in many wallets and exchanges. + + +## Specification + +## Token +### Methods + +**NOTE**: An important point is that callers should handle `false` from `returns (bool success)`. Callers should not assume that `false` is never returned! + +#### totalSupply + +``` js +function totalSupply() constant returns (uint256 totalSupply) +``` + +Get the total token supply +#### balanceOf + +``` js +function balanceOf(address _owner) constant returns (uint256 balance) +``` + +Get the account balance of another account with address `_owner` +#### transfer + +``` js +function transfer(address _to, uint256 _value) returns (bool success) +``` + +Send `_value` amount of tokens to address `_to` +#### transferFrom + +``` js +function transferFrom(address _from, address _to, uint256 _value) returns (bool success) +``` + +Send `_value` amount of tokens from address `_from` to address `_to` + +The `transferFrom` method is used for a withdraw workflow, allowing contracts to send tokens on your behalf, for example to "deposit" to a contract address and/or to charge fees in sub-currencies; the command should fail unless the `_from` account has deliberately authorized the sender of the message via some mechanism; we propose these standardized APIs for approval: +#### approve + +``` js +function approve(address _spender, uint256 _value) returns (bool success) +``` + +Allow _spender to withdraw from your account, multiple times, up to the _value amount. If this function is called again it overwrites the current allowance with _value. +To prevent attack vectors like described here: https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/ +make sure to set the allowance to 0 before setting it to another value for the same spender. +#### allowance + +``` js +function allowance(address _owner, address _spender) constant returns (uint256 remaining) +``` + +Returns the amount which `_spender` is still allowed to withdraw from `_owner` +### Events +#### Transfer + +``` js +event Transfer(address indexed _from, address indexed _to, uint256 _value) +``` + +Triggered when tokens are transferred. +#### Approval + +``` js +event Approval(address indexed _owner, address indexed _spender, uint256 _value) +``` + +Triggered whenever `approve(address _spender, uint256 _value)` is called. + + +## Implementation + +Different implementations are available at +- https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/StandardToken.sol +- https://github.com/ConsenSys/Tokens/blob/master/Token_Contracts/contracts/StandardToken.sol + +Implentation adding the force 0 before calling approve again: +- https://github.com/Giveth/minime/blob/master/MiniMeToken.sol + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 5dc879024aeb906b59e8ac4207c63a8e940d8ee5 Mon Sep 17 00:00:00 2001 From: Fabian Vogelsteller Date: Mon, 24 Apr 2017 15:42:04 +0200 Subject: [PATCH 0230/1085] reformatted --- EIPS/eip-token-standard.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/EIPS/eip-token-standard.md b/EIPS/eip-token-standard.md index a7ffa494422c0..59806a7677bae 100644 --- a/EIPS/eip-token-standard.md +++ b/EIPS/eip-token-standard.md @@ -44,6 +44,8 @@ function totalSupply() constant returns (uint256 totalSupply) ``` Get the total token supply + + #### balanceOf ``` js @@ -51,6 +53,8 @@ function balanceOf(address _owner) constant returns (uint256 balance) ``` Get the account balance of another account with address `_owner` + + #### transfer ``` js @@ -58,6 +62,8 @@ function transfer(address _to, uint256 _value) returns (bool success) ``` Send `_value` amount of tokens to address `_to` + + #### transferFrom ``` js @@ -67,6 +73,8 @@ function transferFrom(address _from, address _to, uint256 _value) returns (bool Send `_value` amount of tokens from address `_from` to address `_to` The `transferFrom` method is used for a withdraw workflow, allowing contracts to send tokens on your behalf, for example to "deposit" to a contract address and/or to charge fees in sub-currencies; the command should fail unless the `_from` account has deliberately authorized the sender of the message via some mechanism; we propose these standardized APIs for approval: + + #### approve ``` js @@ -76,6 +84,8 @@ function approve(address _spender, uint256 _value) returns (bool success) Allow _spender to withdraw from your account, multiple times, up to the _value amount. If this function is called again it overwrites the current allowance with _value. To prevent attack vectors like described here: https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/ make sure to set the allowance to 0 before setting it to another value for the same spender. + + #### allowance ``` js @@ -83,7 +93,11 @@ function allowance(address _owner, address _spender) constant returns (uint256 r ``` Returns the amount which `_spender` is still allowed to withdraw from `_owner` + + ### Events + + #### Transfer ``` js @@ -91,6 +105,8 @@ event Transfer(address indexed _from, address indexed _to, uint256 _value) ``` Triggered when tokens are transferred. + + #### Approval ``` js From d34981d4e9536ee44d84464db9de3c36b5370997 Mon Sep 17 00:00:00 2001 From: Fabian Vogelsteller Date: Wed, 3 May 2017 15:38:54 +0200 Subject: [PATCH 0231/1085] fixed spelling suggestions --- EIPS/eip-token-standard.md | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/EIPS/eip-token-standard.md b/EIPS/eip-token-standard.md index 59806a7677bae..e5fabc9711b2b 100644 --- a/EIPS/eip-token-standard.md +++ b/EIPS/eip-token-standard.md @@ -1,33 +1,27 @@ -This is the suggested template for new EIPs. - -Note that an EIP number will be assigned by an editor. When opening a pull request to submit your EIP, please use an abbreviated title in the filename, `eip-draft_title_abbrev.md`. - ## Preamble EIP: (I Suggest 20) Title: Author: Fabian Vogelsteller , Vitalik Buterin Type: Informational - Category ERC Status: Draft Created: 2015-11-19 ## Simple Summary -Token standard interface. +A standard interface for tokens. ## Abstract -The following standard allows for people to implement a token standard API withing their smart contracts. - -This standard provides basic functionality for sending and approving tokens to be spend by a third party. +The following standard allows for the implementation of a standard API for tokens within their smart contracts: +it primarily provides basic functionality to transfer tokens and allow them to be approved to be spend by another on-chain third party. ## Motivation -Following the same standard interface allows those tokens to be used in many wallets and exchanges. +A standard interface allows any tokens on Ethereum to be re-used by other applications: from wallets to decentralized exchanges. ## Specification @@ -61,7 +55,7 @@ Get the account balance of another account with address `_owner` function transfer(address _to, uint256 _value) returns (bool success) ``` -Send `_value` amount of tokens to address `_to` +Transfer `_value` amount of tokens to address `_to` #### transferFrom @@ -82,7 +76,7 @@ function approve(address _spender, uint256 _value) returns (bool success) ``` Allow _spender to withdraw from your account, multiple times, up to the _value amount. If this function is called again it overwrites the current allowance with _value. -To prevent attack vectors like described here: https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/ +To prevent attack vectors like the one described here: https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/ make sure to set the allowance to 0 before setting it to another value for the same spender. @@ -118,11 +112,14 @@ Triggered whenever `approve(address _spender, uint256 _value)` is called. ## Implementation -Different implementations are available at +There are already plenty of ERC20-compliant tokens deployed on the Ethereum network and is the most widely used standard. +Different implementations have been written by various teams that have different trade-offs: from gas saving to improved security. + +#### Example implementations are available at - https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/StandardToken.sol - https://github.com/ConsenSys/Tokens/blob/master/Token_Contracts/contracts/StandardToken.sol -Implentation adding the force 0 before calling approve again: +#### Implementation adding the force 0 before calling approve again: - https://github.com/Giveth/minime/blob/master/MiniMeToken.sol ## Copyright From 0a051c820cb622ad35a106de0e0e1a48f25e4d20 Mon Sep 17 00:00:00 2001 From: Fabian Vogelsteller Date: Wed, 3 May 2017 15:45:15 +0200 Subject: [PATCH 0232/1085] added name, symbol, decimals --- EIPS/eip-token-standard.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/EIPS/eip-token-standard.md b/EIPS/eip-token-standard.md index e5fabc9711b2b..c3152b9991054 100644 --- a/EIPS/eip-token-standard.md +++ b/EIPS/eip-token-standard.md @@ -31,6 +31,33 @@ A standard interface allows any tokens on Ethereum to be re-used by other applic **NOTE**: An important point is that callers should handle `false` from `returns (bool success)`. Callers should not assume that `false` is never returned! +#### name + +``` js +function name() constant returns (string name) +``` + +Returns the name of the token. E.g. "MyToken" + + +#### symbol + +``` js +function symbol() constant returns (string symbol) +``` + +Returns the symbol of the token. E.g. "MYT" + + +#### decimals + +``` js +function decimals() constant returns (uint8 decimals) +``` + +Returns the number of decimals the token uses. E.g. 8, which would mean to divide the token amount by 100000000 to get its user representation. + + #### totalSupply ``` js From 20706fb8e21c398fafef5c4b5c075ef7974bdcaf Mon Sep 17 00:00:00 2001 From: Fabian Vogelsteller Date: Wed, 17 May 2017 10:51:09 +0200 Subject: [PATCH 0233/1085] added changes and moved method description above the func declaration --- EIPS/eip-token-standard.md | 68 +++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/EIPS/eip-token-standard.md b/EIPS/eip-token-standard.md index c3152b9991054..40f65ed1022ac 100644 --- a/EIPS/eip-token-standard.md +++ b/EIPS/eip-token-standard.md @@ -1,10 +1,11 @@ ## Preamble - EIP: (I Suggest 20) - Title: + EIP: 20 + Title: ERC-20 Token Standard Author: Fabian Vogelsteller , Vitalik Buterin - Type: Informational - Status: Draft + Type: Standard + Category: ERC + Status: Accepted Created: 2015-11-19 @@ -15,8 +16,8 @@ A standard interface for tokens. ## Abstract -The following standard allows for the implementation of a standard API for tokens within their smart contracts: -it primarily provides basic functionality to transfer tokens and allow them to be approved to be spend by another on-chain third party. +The following standard allows for the implementation of a standard API for tokens within smart contracts. +This standard provides basic functionality to transfer tokens, as well as allow tokens to be approved so they can be spent by another on-chain third party. ## Motivation @@ -29,91 +30,102 @@ A standard interface allows any tokens on Ethereum to be re-used by other applic ## Token ### Methods -**NOTE**: An important point is that callers should handle `false` from `returns (bool success)`. Callers should not assume that `false` is never returned! +**NOTE**: Callers should handle `false` from `returns (bool success)`. Callers should not assume that `false` is never returned! #### name +Returns the name of the token - e.g. `"MyToken"` + ``` js function name() constant returns (string name) ``` -Returns the name of the token. E.g. "MyToken" - #### symbol +Returns the symbol of the token. E.g. "MYT" + ``` js function symbol() constant returns (string symbol) ``` -Returns the symbol of the token. E.g. "MYT" #### decimals +Returns the number of decimals the token uses - e.g. `8`, means to divide the token amount by `100000000` to get its user representation. + ``` js function decimals() constant returns (uint8 decimals) ``` -Returns the number of decimals the token uses. E.g. 8, which would mean to divide the token amount by 100000000 to get its user representation. - #### totalSupply +Returns the total token supply. + ``` js function totalSupply() constant returns (uint256 totalSupply) ``` -Get the total token supply #### balanceOf +Returns the account balance of another account with address `_owner`. + ``` js function balanceOf(address _owner) constant returns (uint256 balance) ``` -Get the account balance of another account with address `_owner` #### transfer +Transfers `_value` amount of tokens to address `_to`. +The command should `throw` if the `_from` account balance has not enough tokens to spend. + + ``` js function transfer(address _to, uint256 _value) returns (bool success) ``` -Transfer `_value` amount of tokens to address `_to` #### transferFrom +Transfers `_value` amount of tokens from address `_from` to address `_to`. + +The `transferFrom` method is used for a withdraw workflow, allowing contracts to transfer tokens on your behalf. +This can be used for example to allow a contract to transfer tokens on your behalf and/or to charge fees in sub-currencies. +The command should `throw` unless the `_from` account has deliberately authorized the sender of the message via some mechanism. + ``` js function transferFrom(address _from, address _to, uint256 _value) returns (bool success) ``` -Send `_value` amount of tokens from address `_from` to address `_to` - -The `transferFrom` method is used for a withdraw workflow, allowing contracts to send tokens on your behalf, for example to "deposit" to a contract address and/or to charge fees in sub-currencies; the command should fail unless the `_from` account has deliberately authorized the sender of the message via some mechanism; we propose these standardized APIs for approval: #### approve +Allows `_spender` to withdraw from your account multiple times, up to the `_value` amount. If this function is called again it overwrites the current allowance with `_value`. + +**NOTE**: To prevent attack vectors like the one [described here](https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/) and discussed [here](https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729), +make sure to force users set the allowance to `0` before setting it to another value for the same spender. + ``` js function approve(address _spender, uint256 _value) returns (bool success) ``` -Allow _spender to withdraw from your account, multiple times, up to the _value amount. If this function is called again it overwrites the current allowance with _value. -To prevent attack vectors like the one described here: https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/ -make sure to set the allowance to 0 before setting it to another value for the same spender. - #### allowance +Returns the amount which `_spender` is still allowed to withdraw from `_owner`. + ``` js function allowance(address _owner, address _spender) constant returns (uint256 remaining) ``` -Returns the amount which `_spender` is still allowed to withdraw from `_owner` ### Events @@ -121,32 +133,34 @@ Returns the amount which `_spender` is still allowed to withdraw from `_owner` #### Transfer +Triggered when tokens are transferred. + ``` js event Transfer(address indexed _from, address indexed _to, uint256 _value) ``` -Triggered when tokens are transferred. #### Approval +Triggered when `approve(address _spender, uint256 _value)` is called. + ``` js event Approval(address indexed _owner, address indexed _spender, uint256 _value) ``` -Triggered whenever `approve(address _spender, uint256 _value)` is called. ## Implementation -There are already plenty of ERC20-compliant tokens deployed on the Ethereum network and is the most widely used standard. +There are already plenty of ERC20-compliant tokens deployed on the Ethereum network. Different implementations have been written by various teams that have different trade-offs: from gas saving to improved security. #### Example implementations are available at - https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/StandardToken.sol - https://github.com/ConsenSys/Tokens/blob/master/Token_Contracts/contracts/StandardToken.sol -#### Implementation adding the force 0 before calling approve again: +#### Implementation of adding the force to 0 before calling "approve" again: - https://github.com/Giveth/minime/blob/master/MiniMeToken.sol ## Copyright From 36074618cf9fed43bd0cd35fd93a23e8679fd3e7 Mon Sep 17 00:00:00 2001 From: Fabian Vogelsteller Date: Mon, 12 Jun 2017 12:34:00 +0200 Subject: [PATCH 0234/1085] changed example address --- EIPS/eip-token-standard.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-token-standard.md b/EIPS/eip-token-standard.md index 40f65ed1022ac..d2d4622a27672 100644 --- a/EIPS/eip-token-standard.md +++ b/EIPS/eip-token-standard.md @@ -161,7 +161,7 @@ Different implementations have been written by various teams that have different - https://github.com/ConsenSys/Tokens/blob/master/Token_Contracts/contracts/StandardToken.sol #### Implementation of adding the force to 0 before calling "approve" again: -- https://github.com/Giveth/minime/blob/master/MiniMeToken.sol +- https://github.com/Giveth/minime/blob/master/contracts/MiniMeToken.sol ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 232013660b153692b23b29202177c2fcbee7bd5a Mon Sep 17 00:00:00 2001 From: Fabian Vogelsteller Date: Wed, 21 Jun 2017 08:39:20 +0200 Subject: [PATCH 0235/1085] added transfer 0 clearification --- EIPS/eip-token-standard.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/EIPS/eip-token-standard.md b/EIPS/eip-token-standard.md index d2d4622a27672..f3341c07c2744 100644 --- a/EIPS/eip-token-standard.md +++ b/EIPS/eip-token-standard.md @@ -82,9 +82,10 @@ function balanceOf(address _owner) constant returns (uint256 balance) #### transfer -Transfers `_value` amount of tokens to address `_to`. -The command should `throw` if the `_from` account balance has not enough tokens to spend. +Transfers `_value` amount of tokens to address `_to`, and should fire the `Transfer` event. +The function should `throw` if the `_from` account balance has not enough tokens to spend. +*Note* Transfers of 0 values should be treated as normal transfers and fire the `Transfer` event. ``` js function transfer(address _to, uint256 _value) returns (bool success) @@ -94,11 +95,13 @@ function transfer(address _to, uint256 _value) returns (bool success) #### transferFrom -Transfers `_value` amount of tokens from address `_from` to address `_to`. +Transfers `_value` amount of tokens from address `_from` to address `_to`, and should fire the `Transfer` event. The `transferFrom` method is used for a withdraw workflow, allowing contracts to transfer tokens on your behalf. This can be used for example to allow a contract to transfer tokens on your behalf and/or to charge fees in sub-currencies. -The command should `throw` unless the `_from` account has deliberately authorized the sender of the message via some mechanism. +The function should `throw` unless the `_from` account has deliberately authorized the sender of the message via some mechanism. + +*Note* Transfers of 0 values should be treated as normal transfers and fire the `Transfer` event. ``` js function transferFrom(address _from, address _to, uint256 _value) returns (bool success) From 0de522e2175ea8ebcfe5f5459b5f67e4479ff554 Mon Sep 17 00:00:00 2001 From: Fabian Vogelsteller Date: Wed, 21 Jun 2017 11:04:15 +0200 Subject: [PATCH 0236/1085] addressed RFC2119 --- EIPS/eip-token-standard.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/EIPS/eip-token-standard.md b/EIPS/eip-token-standard.md index f3341c07c2744..7f838cd32c683 100644 --- a/EIPS/eip-token-standard.md +++ b/EIPS/eip-token-standard.md @@ -30,7 +30,8 @@ A standard interface allows any tokens on Ethereum to be re-used by other applic ## Token ### Methods -**NOTE**: Callers should handle `false` from `returns (bool success)`. Callers should not assume that `false` is never returned! +**NOTE**: Callers MUST handle `false` from `returns (bool success)`. Callers MUST NOT assume that `false` is never returned! + #### name @@ -82,10 +83,10 @@ function balanceOf(address _owner) constant returns (uint256 balance) #### transfer -Transfers `_value` amount of tokens to address `_to`, and should fire the `Transfer` event. -The function should `throw` if the `_from` account balance has not enough tokens to spend. +Transfers `_value` amount of tokens to address `_to`, and MUST fire the `Transfer` event. +The function SHOULD `throw` if the `_from` account balance has not enough tokens to spend. -*Note* Transfers of 0 values should be treated as normal transfers and fire the `Transfer` event. +*Note* Transfers of 0 values MUST be treated as normal transfers and fire the `Transfer` event. ``` js function transfer(address _to, uint256 _value) returns (bool success) @@ -95,13 +96,13 @@ function transfer(address _to, uint256 _value) returns (bool success) #### transferFrom -Transfers `_value` amount of tokens from address `_from` to address `_to`, and should fire the `Transfer` event. +Transfers `_value` amount of tokens from address `_from` to address `_to`, and MUST fire the `Transfer` event. The `transferFrom` method is used for a withdraw workflow, allowing contracts to transfer tokens on your behalf. This can be used for example to allow a contract to transfer tokens on your behalf and/or to charge fees in sub-currencies. -The function should `throw` unless the `_from` account has deliberately authorized the sender of the message via some mechanism. +The function SHOULD `throw` unless the `_from` account has deliberately authorized the sender of the message via some mechanism. -*Note* Transfers of 0 values should be treated as normal transfers and fire the `Transfer` event. +*Note* Transfers of 0 values MUST be treated as normal transfers and fire the `Transfer` event. ``` js function transferFrom(address _from, address _to, uint256 _value) returns (bool success) @@ -114,7 +115,7 @@ function transferFrom(address _from, address _to, uint256 _value) returns (bool Allows `_spender` to withdraw from your account multiple times, up to the `_value` amount. If this function is called again it overwrites the current allowance with `_value`. **NOTE**: To prevent attack vectors like the one [described here](https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/) and discussed [here](https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729), -make sure to force users set the allowance to `0` before setting it to another value for the same spender. +make sure to force users to set the allowance to `0` before setting it to another value for the same spender. ``` js function approve(address _spender, uint256 _value) returns (bool success) @@ -136,7 +137,7 @@ function allowance(address _owner, address _spender) constant returns (uint256 r #### Transfer -Triggered when tokens are transferred. +MUST trigger when tokens are transferred. ``` js event Transfer(address indexed _from, address indexed _to, uint256 _value) @@ -146,7 +147,7 @@ event Transfer(address indexed _from, address indexed _to, uint256 _value) #### Approval -Triggered when `approve(address _spender, uint256 _value)` is called. +MUST trigger when `approve(address _spender, uint256 _value)` is called. ``` js event Approval(address indexed _owner, address indexed _spender, uint256 _value) From e2c2abeb34d5199ba377f6a1d10785767c35673d Mon Sep 17 00:00:00 2001 From: Fabian Vogelsteller Date: Thu, 13 Jul 2017 13:58:18 +0200 Subject: [PATCH 0237/1085] renamed file and add small spelling changes --- EIPS/eip-token-standard.md | 171 ------------------------------------- 1 file changed, 171 deletions(-) delete mode 100644 EIPS/eip-token-standard.md diff --git a/EIPS/eip-token-standard.md b/EIPS/eip-token-standard.md deleted file mode 100644 index 7f838cd32c683..0000000000000 --- a/EIPS/eip-token-standard.md +++ /dev/null @@ -1,171 +0,0 @@ -## Preamble - - EIP: 20 - Title: ERC-20 Token Standard - Author: Fabian Vogelsteller , Vitalik Buterin - Type: Standard - Category: ERC - Status: Accepted - Created: 2015-11-19 - - -## Simple Summary - -A standard interface for tokens. - - -## Abstract - -The following standard allows for the implementation of a standard API for tokens within smart contracts. -This standard provides basic functionality to transfer tokens, as well as allow tokens to be approved so they can be spent by another on-chain third party. - - -## Motivation - -A standard interface allows any tokens on Ethereum to be re-used by other applications: from wallets to decentralized exchanges. - - -## Specification - -## Token -### Methods - -**NOTE**: Callers MUST handle `false` from `returns (bool success)`. Callers MUST NOT assume that `false` is never returned! - - -#### name - -Returns the name of the token - e.g. `"MyToken"` - -``` js -function name() constant returns (string name) -``` - - -#### symbol - -Returns the symbol of the token. E.g. "MYT" - -``` js -function symbol() constant returns (string symbol) -``` - - - -#### decimals - -Returns the number of decimals the token uses - e.g. `8`, means to divide the token amount by `100000000` to get its user representation. - -``` js -function decimals() constant returns (uint8 decimals) -``` - - -#### totalSupply - -Returns the total token supply. - -``` js -function totalSupply() constant returns (uint256 totalSupply) -``` - - - -#### balanceOf - -Returns the account balance of another account with address `_owner`. - -``` js -function balanceOf(address _owner) constant returns (uint256 balance) -``` - - - -#### transfer - -Transfers `_value` amount of tokens to address `_to`, and MUST fire the `Transfer` event. -The function SHOULD `throw` if the `_from` account balance has not enough tokens to spend. - -*Note* Transfers of 0 values MUST be treated as normal transfers and fire the `Transfer` event. - -``` js -function transfer(address _to, uint256 _value) returns (bool success) -``` - - - -#### transferFrom - -Transfers `_value` amount of tokens from address `_from` to address `_to`, and MUST fire the `Transfer` event. - -The `transferFrom` method is used for a withdraw workflow, allowing contracts to transfer tokens on your behalf. -This can be used for example to allow a contract to transfer tokens on your behalf and/or to charge fees in sub-currencies. -The function SHOULD `throw` unless the `_from` account has deliberately authorized the sender of the message via some mechanism. - -*Note* Transfers of 0 values MUST be treated as normal transfers and fire the `Transfer` event. - -``` js -function transferFrom(address _from, address _to, uint256 _value) returns (bool success) -``` - - - -#### approve - -Allows `_spender` to withdraw from your account multiple times, up to the `_value` amount. If this function is called again it overwrites the current allowance with `_value`. - -**NOTE**: To prevent attack vectors like the one [described here](https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/) and discussed [here](https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729), -make sure to force users to set the allowance to `0` before setting it to another value for the same spender. - -``` js -function approve(address _spender, uint256 _value) returns (bool success) -``` - - -#### allowance - -Returns the amount which `_spender` is still allowed to withdraw from `_owner`. - -``` js -function allowance(address _owner, address _spender) constant returns (uint256 remaining) -``` - - - -### Events - - -#### Transfer - -MUST trigger when tokens are transferred. - -``` js -event Transfer(address indexed _from, address indexed _to, uint256 _value) -``` - - - -#### Approval - -MUST trigger when `approve(address _spender, uint256 _value)` is called. - -``` js -event Approval(address indexed _owner, address indexed _spender, uint256 _value) -``` - - - -## Implementation - -There are already plenty of ERC20-compliant tokens deployed on the Ethereum network. -Different implementations have been written by various teams that have different trade-offs: from gas saving to improved security. - -#### Example implementations are available at -- https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/StandardToken.sol -- https://github.com/ConsenSys/Tokens/blob/master/Token_Contracts/contracts/StandardToken.sol - -#### Implementation of adding the force to 0 before calling "approve" again: -- https://github.com/Giveth/minime/blob/master/contracts/MiniMeToken.sol - -## Copyright -Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 7e6905c221cf59067f9e1727026155fcf0f0efb1 Mon Sep 17 00:00:00 2001 From: Fabian Vogelsteller Date: Thu, 13 Jul 2017 14:17:43 +0200 Subject: [PATCH 0238/1085] changed name --- EIPS/eip-20-token-standard.md | 183 ++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 EIPS/eip-20-token-standard.md diff --git a/EIPS/eip-20-token-standard.md b/EIPS/eip-20-token-standard.md new file mode 100644 index 0000000000000..ddda6e75cce94 --- /dev/null +++ b/EIPS/eip-20-token-standard.md @@ -0,0 +1,183 @@ +## Preamble + + EIP: 20 + Title: ERC-20 Token Standard + Author: Fabian Vogelsteller , Vitalik Buterin + Type: Standard + Category: ERC + Status: Accepted + Created: 2015-11-19 + + +## Simple Summary + +A standard interface for tokens. + + +## Abstract + +The following standard allows for the implementation of a standard API for tokens within smart contracts. +This standard provides basic functionality to transfer tokens, as well as allow tokens to be approved so they can be spent by another on-chain third party. + + +## Motivation + +A standard interface allows any tokens on Ethereum to be re-used by other applications: from wallets to decentralized exchanges. + + +## Specification + +## Token +### Methods + +**NOTE**: Callers MUST handle `false` from `returns (bool success)`. Callers MUST NOT assume that `false` is never returned! + + +#### name + +Returns the name of the token - e.g. `"MyToken"`. + +OPTIONAL - This method can be used to improve useability, +but interfaces and other contracts MUST NOT expect these values to be present. + + +``` js +function name() constant returns (string name) +``` + + +#### symbol + +Returns the symbol of the token. E.g. "HIX". + +OPTIONAL - This method can be used to improve useability, +but interfaces and other contracts MUST NOT expect these values to be present. + +``` js +function symbol() constant returns (string symbol) +``` + + + +#### decimals + +Returns the number of decimals the token uses - e.g. `8`, means to divide the token amount by `100000000` to get its user representation. + +OPTIONAL - This method can be used to improve useability, +but interfaces and other contracts MUST NOT expect these values to be present. + +``` js +function decimals() constant returns (uint8 decimals) +``` + + +#### totalSupply + +Returns the total token supply. + +``` js +function totalSupply() constant returns (uint256 totalSupply) +``` + + + +#### balanceOf + +Returns the account balance of another account with address `_owner`. + +``` js +function balanceOf(address _owner) constant returns (uint256 balance) +``` + + + +#### transfer + +Transfers `_value` amount of tokens to address `_to`, and MUST fire the `Transfer` event. +The function SHOULD `throw` if the `_from` account balance has not enough tokens to spend. + +An token contract which creates new tokens SHOULD trigger a Transfer event with the `_from` address set to `0x0` when tokens are created. + +*Note* Transfers of 0 values MUST be treated as normal transfers and fire the `Transfer` event. + +``` js +function transfer(address _to, uint256 _value) returns (bool success) +``` + + + +#### transferFrom + +Transfers `_value` amount of tokens from address `_from` to address `_to`, and MUST fire the `Transfer` event. + +The `transferFrom` method is used for a withdraw workflow, allowing contracts to transfer tokens on your behalf. +This can be used for example to allow a contract to transfer tokens on your behalf and/or to charge fees in sub-currencies. +The function SHOULD `throw` unless the `_from` account has deliberately authorized the sender of the message via some mechanism. + +*Note* Transfers of 0 values MUST be treated as normal transfers and fire the `Transfer` event. + +``` js +function transferFrom(address _from, address _to, uint256 _value) returns (bool success) +``` + + + +#### approve + +Allows `_spender` to withdraw from your account multiple times, up to the `_value` amount. If this function is called again it overwrites the current allowance with `_value`. + +**NOTE**: To prevent attack vectors like the one [described here](https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/) and discussed [here](https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729), +make sure to force users to set the allowance to `0` before setting it to another value for the same spender. + +``` js +function approve(address _spender, uint256 _value) returns (bool success) +``` + + +#### allowance + +Returns the amount which `_spender` is still allowed to withdraw from `_owner`. + +``` js +function allowance(address _owner, address _spender) constant returns (uint256 remaining) +``` + + + +### Events + + +#### Transfer + +MUST trigger when tokens are transferred, including zero value transfers. + +``` js +event Transfer(address indexed _from, address indexed _to, uint256 _value) +``` + + + +#### Approval + +MUST trigger on any successful call to `approve(address _spender, uint256 _value)`. + +``` js +event Approval(address indexed _owner, address indexed _spender, uint256 _value) +``` + + + +## Implementation + +There are already plenty of ERC20-compliant tokens deployed on the Ethereum network. +Different implementations have been written by various teams that have different trade-offs: from gas saving to improved security. + +#### Example implementations are available at +- https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/StandardToken.sol +- https://github.com/ConsenSys/Tokens/blob/master/Token_Contracts/contracts/StandardToken.sol + +#### Implementation of adding the force to 0 before calling "approve" again: +- https://github.com/Giveth/minime/blob/master/contracts/MiniMeToken.sol + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 09dc05705e858ac3805f6368b6feddfafaec3c66 Mon Sep 17 00:00:00 2001 From: Fabian Vogelsteller Date: Mon, 24 Jul 2017 19:59:21 +0200 Subject: [PATCH 0239/1085] small corrections --- EIPS/eip-20-token-standard.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-20-token-standard.md b/EIPS/eip-20-token-standard.md index ddda6e75cce94..a81787851fe27 100644 --- a/EIPS/eip-20-token-standard.md +++ b/EIPS/eip-20-token-standard.md @@ -96,7 +96,7 @@ function balanceOf(address _owner) constant returns (uint256 balance) Transfers `_value` amount of tokens to address `_to`, and MUST fire the `Transfer` event. The function SHOULD `throw` if the `_from` account balance has not enough tokens to spend. -An token contract which creates new tokens SHOULD trigger a Transfer event with the `_from` address set to `0x0` when tokens are created. +A token contract which creates new tokens SHOULD trigger a Transfer event with the `_from` address set to `0x0` when tokens are created. *Note* Transfers of 0 values MUST be treated as normal transfers and fire the `Transfer` event. @@ -127,7 +127,8 @@ function transferFrom(address _from, address _to, uint256 _value) returns (bool Allows `_spender` to withdraw from your account multiple times, up to the `_value` amount. If this function is called again it overwrites the current allowance with `_value`. **NOTE**: To prevent attack vectors like the one [described here](https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/) and discussed [here](https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729), -make sure to force users to set the allowance to `0` before setting it to another value for the same spender. +clients SHOULD make sure to create user interfaces in such a way that they set the allowance first to `0` before setting it to another value for the same spender. +THOUGH The contract itself shouldn't enforce it, to allow backwards compatilibilty with contracts deployed before ``` js function approve(address _spender, uint256 _value) returns (bool success) From 31ec8acbd1ea309cc1c17459355bdfddcbe7131f Mon Sep 17 00:00:00 2001 From: Fabian Vogelsteller Date: Wed, 9 Aug 2017 11:28:38 +0200 Subject: [PATCH 0240/1085] small spelling --- EIPS/eip-20-token-standard.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-20-token-standard.md b/EIPS/eip-20-token-standard.md index a81787851fe27..2952404f446c1 100644 --- a/EIPS/eip-20-token-standard.md +++ b/EIPS/eip-20-token-standard.md @@ -94,7 +94,7 @@ function balanceOf(address _owner) constant returns (uint256 balance) #### transfer Transfers `_value` amount of tokens to address `_to`, and MUST fire the `Transfer` event. -The function SHOULD `throw` if the `_from` account balance has not enough tokens to spend. +The function SHOULD `throw` if the `_from` account balance does not have enough tokens to spend. A token contract which creates new tokens SHOULD trigger a Transfer event with the `_from` address set to `0x0` when tokens are created. From f90864a3d2b2b45c4decf95efd26b3f0c276051a Mon Sep 17 00:00:00 2001 From: Fabian Vogelsteller Date: Fri, 8 Sep 2017 13:38:14 +0200 Subject: [PATCH 0241/1085] fix spelling --- EIPS/eip-20-token-standard.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-20-token-standard.md b/EIPS/eip-20-token-standard.md index 2952404f446c1..c5facc53a4a76 100644 --- a/EIPS/eip-20-token-standard.md +++ b/EIPS/eip-20-token-standard.md @@ -37,7 +37,7 @@ A standard interface allows any tokens on Ethereum to be re-used by other applic Returns the name of the token - e.g. `"MyToken"`. -OPTIONAL - This method can be used to improve useability, +OPTIONAL - This method can be used to improve usability, but interfaces and other contracts MUST NOT expect these values to be present. @@ -50,7 +50,7 @@ function name() constant returns (string name) Returns the symbol of the token. E.g. "HIX". -OPTIONAL - This method can be used to improve useability, +OPTIONAL - This method can be used to improve usability, but interfaces and other contracts MUST NOT expect these values to be present. ``` js @@ -63,7 +63,7 @@ function symbol() constant returns (string symbol) Returns the number of decimals the token uses - e.g. `8`, means to divide the token amount by `100000000` to get its user representation. -OPTIONAL - This method can be used to improve useability, +OPTIONAL - This method can be used to improve usability, but interfaces and other contracts MUST NOT expect these values to be present. ``` js From be8a55f2f6518c49b6eed8947dd9f2a63195c48b Mon Sep 17 00:00:00 2001 From: Hudson Jameson Date: Mon, 11 Sep 2017 08:39:33 -0500 Subject: [PATCH 0242/1085] Add ERC-20 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0949e49cadf2f..f5c0be9d167d5 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [6](EIPS/eip-6.md) | Renaming Suicide Opcode | Hudson Jameson | Interface | Final | | [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Core | Final | | [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Networking | Final | +| [20](EIPS/eip-20-token-standard.md) | ERC-20 Token Standard | Fabian Vogelsteller, Vitalik Buterin | ERC | Final | | [141](EIPS/eip-141.md) | Designated invalid EVM instruction | Alex Beregszaszi| Core | Final | | [150](EIPS/eip-150.md) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Core | Final | | [155](EIPS/eip-155.md) | Simple replay attack protection | Vitalik Buterin | Core | Final | From 405c369510479a602e86f4b884a66dd73feb7f65 Mon Sep 17 00:00:00 2001 From: MaxXor Date: Mon, 11 Sep 2017 17:47:25 +0200 Subject: [PATCH 0243/1085] Fix broken url in examples --- EIPS/eip-20-token-standard.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-20-token-standard.md b/EIPS/eip-20-token-standard.md index c5facc53a4a76..e1086c399ded8 100644 --- a/EIPS/eip-20-token-standard.md +++ b/EIPS/eip-20-token-standard.md @@ -175,7 +175,7 @@ Different implementations have been written by various teams that have different #### Example implementations are available at - https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/StandardToken.sol -- https://github.com/ConsenSys/Tokens/blob/master/Token_Contracts/contracts/StandardToken.sol +- https://github.com/ConsenSys/Tokens/blob/master/contracts/StandardToken.sol #### Implementation of adding the force to 0 before calling "approve" again: - https://github.com/Giveth/minime/blob/master/contracts/MiniMeToken.sol From ab76063e6593605488eff1806dd479067a92dee3 Mon Sep 17 00:00:00 2001 From: "Daniel A. Nagy" Date: Sat, 16 Sep 2017 19:58:25 +0200 Subject: [PATCH 0244/1085] EIP: Added the possibility of using a unit. Making the standard sufficiently flexible for use with both online and offline clients, enhancing human readability, if desired. --- EIPS/pay_req_url_fmt.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/EIPS/pay_req_url_fmt.md b/EIPS/pay_req_url_fmt.md index 6f7f1095c093b..51fb5a84179a6 100644 --- a/EIPS/pay_req_url_fmt.md +++ b/EIPS/pay_req_url_fmt.md @@ -34,9 +34,16 @@ Payment request URLs contain "ethereum" in their schema (protocol) part and are parameter = key "=" value key = "value" / "gas" / TYPE value = number / ethereum_address / STRING - number = [ "-" / "+" ] *DIGIT [ "." 1*DIGIT ] [ ( "e" / "E" ) [ 1*DIGIT ] + number = [ "-" / "+" ] *DIGIT [ "." 1*DIGIT ] [ ( "e" / "E" ) [ 1*DIGIT ] [ "+" UNIT ] -Where `TYPE` is a standard ABI type name, as defined in [Ethereum Contract ABI specification](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI). `STRING` is a URL-encoded unicode string of arbitrary length, where delimiters and the percentage symbol (`%`) are mandatorily hex-encoded with a `%` prefix. + +Where `TYPE` is a standard ABI type name, as defined in [Ethereum Contract ABI specification](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI). `STRING` is a URL-encoded unicode string of arbitrary length, where delimiters and the +percentage symbol (`%`) are mandatorily hex-encoded with a `%` prefix. + +`UNIT` is a URL-encoded unicode string. If `UNIT` is ETH, it always means a multiplier of 1018. If it is something +else AND the addressed contract has a `symbol` field exactly matching this string AND the contract has a `decimals` field, then +10 to that power is used as a multiplier. Otherwise, the payment request is deemed invalid. Applications that have no access to +the blockchain should refuse accepting requests with a non-empty `UNIT`, if it is not ETH. Note that a `number` can be expressed in *scientific notation*, with a multiplier of a power of 10. The use of this notation is strongly encouraged when expressing monetary value in Ethers or ERC #20 tokens in atomic units (e. g. Wei, in case of Ether). From 6e105775b886a753333d6f6996dc869f28030ea0 Mon Sep 17 00:00:00 2001 From: Micah Zoltu Date: Thu, 21 Sep 2017 21:21:11 -0700 Subject: [PATCH 0245/1085] Update EIP-draft-getLogs-by-block-hash.md --- EIPS/EIP-draft-getLogs-by-block-hash.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/EIP-draft-getLogs-by-block-hash.md b/EIPS/EIP-draft-getLogs-by-block-hash.md index 4981e5a47c831..38bfeef414aa8 100644 --- a/EIPS/EIP-draft-getLogs-by-block-hash.md +++ b/EIPS/EIP-draft-getLogs-by-block-hash.md @@ -3,7 +3,7 @@ EIP: Title: Add `blockHash` to JSON-RPC filter options. Author: Micah Zoltu -Type: +Type: Standard Track Category: Interface Status: Draft Created: 2017-03-24 From 9464fa7fa5d82c211a0c433c3d39cac569185fcd Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 22 Sep 2017 14:04:45 +0100 Subject: [PATCH 0246/1085] Clarify text (user -> use) --- EIPS/eip-145.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-145.md b/EIPS/eip-145.md index 04f36bcd2d537..01844a9ea1cca 100644 --- a/EIPS/eip-145.md +++ b/EIPS/eip-145.md @@ -15,7 +15,7 @@ To provide native bitwise shifting with cost on par with other arithmetic operat ## Abstract -Native bitwise shifting instructions are introduced, which are more efficient processing wise on the host and are cheaper to user by a contract. +Native bitwise shifting instructions are introduced, which are more efficient processing wise on the host and are cheaper to use by a contract. ## Motivation @@ -87,7 +87,7 @@ Client support: - cpp-ethereum: https://github.com/ethereum/cpp-ethereum/pull/4054 Compiler support: -- Solidity: https://github.com/ethereum/solidity/tree/asm-bitshift +- Solidity/LLL: https://github.com/ethereum/solidity/pull/2541 ## Copyright From d01c9af47fbc75ee482c132a3b37f847bd5dc4de Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 22 Sep 2017 14:15:50 +0100 Subject: [PATCH 0247/1085] Swapp operand order for bitwise shifting --- EIPS/eip-145.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/EIPS/eip-145.md b/EIPS/eip-145.md index 01844a9ea1cca..67370ee91b70e 100644 --- a/EIPS/eip-145.md +++ b/EIPS/eip-145.md @@ -27,51 +27,51 @@ The following instructions are introduced: ### `0x1b`: `SHL` (shift left) -The `SHL` instruction (shift left) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the first popped value `arg1` shifted to the left by the number of bits in the second popped value `arg2`. The result is equal to +The `SHL` instruction (shift left) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the second popped value `arg2` shifted to the left by the number of bits in the first popped value `arg1`. The result is equal to ``` -(arg1 * 2^arg2) mod 2^256 +(arg2 * 2^arg1) mod 2^256 ``` Notes: -- The value (`arg1`) is interpreted as an unsigned number. -- The shift amount (`arg2`) is interpreted as an unsigned number. -- If the shift amount (`arg2`) is greater or equal 256 the result is 0. -- This is equivalent to `SWAP1 PUSH1 2 EXP MUL`. +- The value (`arg2`) is interpreted as an unsigned number. +- The shift amount (`arg1`) is interpreted as an unsigned number. +- If the shift amount (`arg1`) is greater or equal 256 the result is 0. +- This is equivalent to `PUSH1 2 EXP MUL`. ### `0x1c`: `SHR` (logical shift right) -The `SHR` instruction (logical shift right) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the first popped value `arg1` shifted to the right by the number of bits in the second popped value `arg2` with zero fill. The result is equal to +The `SHR` instruction (logical shift right) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the second popped value `arg2` shifted to the right by the number of bits in the first popped value `arg1` with zero fill. The result is equal to ``` -floor(arg1 / 2^arg2) +floor(arg2 / 2^arg1) ``` Notes: -- The value (`arg1`) is interpreted as an unsigned number. -- The shift amount (`arg2`) is interpreted as an unsigned number. -- If the shift amount (`arg2`) is greater or equal 256 the result is 0. -- This is equivalent to `SWAP1 PUSH1 2 EXP DIV`. +- The value (`arg2`) is interpreted as an unsigned number. +- The shift amount (`arg1`) is interpreted as an unsigned number. +- If the shift amount (`arg1`) is greater or equal 256 the result is 0. +- This is equivalent to `PUSH1 2 EXP DIV`. ### `0x1d`: `SAR` (arithmetic shift right) -The `SAR` instruction (arithmetic shift right) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the first popped value `arg1` shifted to the right by the number of bits in the second popped value `arg2` with sign extension. The result is equal to +The `SAR` instruction (arithmetic shift right) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the second popped value `arg2` shifted to the right by the number of bits in the first popped value `arg1` with sign extension. The result is equal to ``` -floor(arg1 / 2^arg2) +floor(arg2 / 2^arg1) ``` Notes: -- The value (`arg1`) is interpreted as a signed number. -- The shift amount (`arg2`) is interpreted as an unsigned number. -- If the shift amount (`arg2`) is greater or equal 256 the result is 0 if `arg1` is non-negative or -1 if `arg1` is negative. -- This is **not** equivalent to `SWAP1 PUSH1 2 EXP SDIV`, since it rounds differently. See `SDIV(-1, 2) == 0`, while `SAR(-1, 1) == -1`. +- The value (`arg2`) is interpreted as a signed number. +- The shift amount (`arg1`) is interpreted as an unsigned number. +- If the shift amount (`arg1`) is greater or equal 256 the result is 0 if `arg2` is non-negative or -1 if `arg2` is negative. +- This is **not** equivalent to `PUSH1 2 EXP SDIV`, since it rounds differently. See `SDIV(-1, 2) == 0`, while `SAR(-1, 1) == -1`. The cost of the shift instructions is set at `verylow` tier (3 gas). ## Rationale -Instruction operands were chosen to match the other logical and arithmetic instructions. +Instruction operands were chosen to fit the more natural use case of shifting a value already on the stack. This means the operand order is swapped compared to most arithmetic insturctions. ## Backwards Compatibility From 74d9a171ffa97c3ccc10433532e8324b1410f1bf Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 22 Sep 2017 16:07:34 +0100 Subject: [PATCH 0248/1085] Clarify wording about arg1/arg2 --- EIPS/eip-145.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-145.md b/EIPS/eip-145.md index 67370ee91b70e..d529c0f3e26df 100644 --- a/EIPS/eip-145.md +++ b/EIPS/eip-145.md @@ -27,7 +27,7 @@ The following instructions are introduced: ### `0x1b`: `SHL` (shift left) -The `SHL` instruction (shift left) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the second popped value `arg2` shifted to the left by the number of bits in the first popped value `arg1`. The result is equal to +The `SHL` instruction (shift left) pops 2 values from the stack, first `arg1` and then `arg2`, and pushes on the stack `arg2` shifted to the left by `arg1` number of bits. The result is equal to ``` (arg2 * 2^arg1) mod 2^256 @@ -41,7 +41,7 @@ Notes: ### `0x1c`: `SHR` (logical shift right) -The `SHR` instruction (logical shift right) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the second popped value `arg2` shifted to the right by the number of bits in the first popped value `arg1` with zero fill. The result is equal to +The `SHR` instruction (logical shift right) pops 2 values from the stack, first `arg1` and then `arg2`, and pushes on the stack `arg2` shifted to the right by `arg1` number of bits with zero fill. The result is equal to ``` floor(arg2 / 2^arg1) @@ -55,7 +55,7 @@ Notes: ### `0x1d`: `SAR` (arithmetic shift right) -The `SAR` instruction (arithmetic shift right) pops 2 values from the stack, `arg1` and `arg2`, and pushes on the stack the second popped value `arg2` shifted to the right by the number of bits in the first popped value `arg1` with sign extension. The result is equal to +The `SAR` instruction (arithmetic shift right) pops 2 values from the stack, first `arg1` and then `arg2`, and pushes on the stack `arg2` shifted to the right by `arg1` number of bits with sign extension. The result is equal to ``` floor(arg2 / 2^arg1) From 19bfeb5f60e5e5d9ced3196124267f0a0c766bc0 Mon Sep 17 00:00:00 2001 From: Hudson Jameson Date: Tue, 26 Sep 2017 15:23:53 -0500 Subject: [PATCH 0249/1085] Corrected 145 to change to final --- EIPS/eip-145.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-145.md b/EIPS/eip-145.md index d529c0f3e26df..6cd270c33eda1 100644 --- a/EIPS/eip-145.md +++ b/EIPS/eip-145.md @@ -5,7 +5,7 @@ Author: Alex Beregszaszi, Paweł Bylica Type: Standard Track Category: Core - Status: Draft + Status: Final Created: 2017-02-13 From 328f6bb4386bb4999f86a33e725d21bc50df4af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 7 Sep 2017 19:02:18 +0300 Subject: [PATCH 0250/1085] Snappy compression for devp2p --- EIPS/eip-devp2p-snappy.md | 68 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 EIPS/eip-devp2p-snappy.md diff --git a/EIPS/eip-devp2p-snappy.md b/EIPS/eip-devp2p-snappy.md new file mode 100644 index 0000000000000..7c0dc93da1f5c --- /dev/null +++ b/EIPS/eip-devp2p-snappy.md @@ -0,0 +1,68 @@ +## Preamble + + EIP: + Title: devp2p snappy compression + Author: Péter Szilágyi + Type: Standard Track + Category: Networking + Status: Draft + Created: 2017-09-07 + +## Abstract +The base networking protocol (devp2p) used by Ethereum currently does not employ any form of compression. This results in a massive amount of bandwidth wasted in the entire network, making both initial sync as well as normal operation slower and laggyer. + +This EIP proposes a tiny extension to the devp2p protocol to enable [Snappy compression](https://en.wikipedia.org/wiki/Snappy_(compression)) on all message payloads after the initial handshake. After extensive benchmarks, results show that data traffic is decreased by 60-80% for initial sync. You can find exact numbers below. + +## Motivation +Synchronizing the Ethereum main network (block 4,248,000) in Geth using fast sync currently consumes 1.01GB upload and 33.59GB download bandwidth. On the Rinkeby test network (block 852,000) it's 55.89MB upload and 2.51GB download. + +However, most of this data (blocks, transactions) are heavily compressable. By enabling compression at the message payload level, we can reduce the previous numbers to 1.01GB upload / 13.46GB download on the main network, and 46.21MB upload / 463.65MB download on the test network. + +The motivation behind doing this at the devp2p level (opposed to eth for example) is that it would enable compression for all sub-protocols (eth, les, bzz) seamlessly, reducing any complexity those protocols might incur in trying to individually optimize for data traffic. + +## Specification +Bump the advertised devp2p version number from `4` to `5`. If during handshake, the remote side advertises support only for version `4`, run the exact same protocol as until now. + +If the remote side advertises a devp2p version `>= 5`, inject a Snappy compression step right before encrypting the devp2p message during sending: + + * A message consists of `{Code, Size, Payload}` + * Compress the original payload with Snappy and store it in the same field. + * Update the message size to the length of the compressed payload. + * Encrypt and send the message as before, oblivious to compression. + +Similarly to message sending, when receiving a devp2p v5 message from a remote node, insert a Snappy decompression step right after the decrypting the devp2p message: + +* A message consists of `{Code, Size, Payload}` + * Decrypt the message payload as before, oblivious to compression. + * Decompress the payload with Snappy and store it in the same field. + * Update the message size to the length of the decompressed payload. + +Note, the handshake message is never compressed, since it is needed to negotiate the common version. + +### Avoiding DOS attacks + +Currently a devp2p message length is limited to 24 bits, amoutning to a maximum size of 16MB. With the introduction of Snappy compression, care must be taken not to blidly decompress messages, since they may get significantly larger than 16MB. + +However, Snappy is capable of calculating the decompressed size of an input message without inflating it in memory. This can be used to set the message size to its final decompressed length and only execute the decompression lazily if upper layers still accept the message. This allows the `eth` protocol to enforce the current 10MB message limit without needing to decompress malicious payload. + +## Rationale +Alternative solutions to data compression that have been brought up and discarded are: + + * Extend protocol `xyz` to support compressed messages + * **Pro**: Can be better optimized when to compress and when not to. + * **Con**: Mixes in transport layer encoding into application layer logic. + * **Con**: Makes the individual message specs more convoluted with compression details. + * **Con**: Requires cross client coordination on every single protocol, making the effor much harder and repeated (eth, les, shh, bzz). + * Introduce seamless variations of protocol such as `xyz` expanded with `xyz-compressed`: + * **Pro**: Can be done (hacked in) without cross client coordination. + * **Con**: Litters the network with client specific protocol announces. + * **Con**: Needs to be specced in an EIP for cross interoperability anyway. + +## Backwards Compatibility +This proposal is fully backward compatible. Clients upgrading to the proposed devp2p protocol version `5` should still support skipping the compression step for connections that only advertise version `4` of the devp2p protocol. + +## Implementation +You can find a reference implementation of this EIP in https://github.com/ethereum/go-ethereum/pull/15106. + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 6a25aa3f7ac51a0268a87c3cca58becd91d096f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Fri, 8 Sep 2017 15:49:46 +0300 Subject: [PATCH 0251/1085] Enforce 16MB limit on decompressed payloads. --- EIPS/eip-devp2p-snappy.md | 40 +++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/EIPS/eip-devp2p-snappy.md b/EIPS/eip-devp2p-snappy.md index 7c0dc93da1f5c..6beed2672e4a5 100644 --- a/EIPS/eip-devp2p-snappy.md +++ b/EIPS/eip-devp2p-snappy.md @@ -43,20 +43,32 @@ Note, the handshake message is never compressed, since it is needed to negotiate Currently a devp2p message length is limited to 24 bits, amoutning to a maximum size of 16MB. With the introduction of Snappy compression, care must be taken not to blidly decompress messages, since they may get significantly larger than 16MB. -However, Snappy is capable of calculating the decompressed size of an input message without inflating it in memory. This can be used to set the message size to its final decompressed length and only execute the decompression lazily if upper layers still accept the message. This allows the `eth` protocol to enforce the current 10MB message limit without needing to decompress malicious payload. - -## Rationale -Alternative solutions to data compression that have been brought up and discarded are: - - * Extend protocol `xyz` to support compressed messages - * **Pro**: Can be better optimized when to compress and when not to. - * **Con**: Mixes in transport layer encoding into application layer logic. - * **Con**: Makes the individual message specs more convoluted with compression details. - * **Con**: Requires cross client coordination on every single protocol, making the effor much harder and repeated (eth, les, shh, bzz). - * Introduce seamless variations of protocol such as `xyz` expanded with `xyz-compressed`: - * **Pro**: Can be done (hacked in) without cross client coordination. - * **Con**: Litters the network with client specific protocol announces. - * **Con**: Needs to be specced in an EIP for cross interoperability anyway. +However, Snappy is capable of calculating the decompressed size of an input message without inflating it in memory. This can be used to discard any messages which decompress above some threshold. **The proposal is to use the same limit (16MB) as the threshold for decompressed messages.** This retains the same guarantees that the current devp2p protocol does, so there won't be surprises in application level protocols. + +## Alternatives (discarded) + +**Alternative solutions to data compression that have been brought up and discarded are:** + +Extend protocol `xyz` to support compressed messages versus doing it at devp2p level: + + * **Pro**: Can be better optimized when to compress and when not to. + * **Con**: Mixes in transport layer encoding into application layer logic. + * **Con**: Makes the individual message specs more convoluted with compression details. + * **Con**: Requires cross client coordination on every single protocol, making the effor much harder and repeated (eth, les, shh, bzz). + +Introduce seamless variations of protocol such as `xyz` expanded with `xyz-compressed`: + + * **Pro**: Can be done (hacked in) without cross client coordination. + * **Con**: Litters the network with client specific protocol announces. + * **Con**: Needs to be specced in an EIP for cross interoperability anyway. + +**Other ideas that have been discussed and discarded:** + +Don't explicitly limit the decompressed message size, only the compressed one: + + * **Pro**: Allows larger messages to traverse through devp2p. + * **Con**: Upper layer protocols need to check and discard large messages. + * **Con**: Needs lazy decompression to allow size limitations without DOS. ## Backwards Compatibility This proposal is fully backward compatible. Clients upgrading to the proposed devp2p protocol version `5` should still support skipping the compression step for connections that only advertise version `4` of the devp2p protocol. From b6c27a3a0db1205e7194f6414a179d657bd64d58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 25 Sep 2017 15:37:20 +0300 Subject: [PATCH 0252/1085] Add test vectors to disambiguate the no-framing aspect. --- EIPS/eip-devp2p-snappy.md | 114 +++++++++++++++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-devp2p-snappy.md b/EIPS/eip-devp2p-snappy.md index 6beed2672e4a5..01577490d0ae7 100644 --- a/EIPS/eip-devp2p-snappy.md +++ b/EIPS/eip-devp2p-snappy.md @@ -37,7 +37,10 @@ Similarly to message sending, when receiving a devp2p v5 message from a remote n * Decompress the payload with Snappy and store it in the same field. * Update the message size to the length of the decompressed payload. -Note, the handshake message is never compressed, since it is needed to negotiate the common version. +Important caveats: + + * The handshake message is **never** compressed, since it is needed to negotiate the common version. + * Snappy framing is **not** used, since the devp2p protocol already message oriented. ### Avoiding DOS attacks @@ -76,5 +79,114 @@ This proposal is fully backward compatible. Clients upgrading to the proposed de ## Implementation You can find a reference implementation of this EIP in https://github.com/ethereum/go-ethereum/pull/15106. +## Test vectors + +There is more than one valid encoding of any given input, and there is more than one good internal compression algorithm within Snappy when trading off throughput for output size. As such, different implementations might produce slight variations in the compressed form, but all should be cross compatible between each other. + +As an example, take hex encoded RLP of block #272621 from the Rinkeby test network: [block.rlp (~3MB)](https://gist.githubusercontent.com/karalabe/72a1a6c4c1dbe6d4996879e415697f06/raw/195bf0c0050ee9805fcd5db4b5b650c58879a55f/block.rlp). + + * Encoding the raw RLP via [Go's Snappy library](https://github.com/golang/snappy) yields: [block.go.snappy (~70KB)](https://gist.githubusercontent.com/karalabe/72a1a6c4c1dbe6d4996879e415697f06/raw/195bf0c0050ee9805fcd5db4b5b650c58879a55f/block.go.snappy). + * Encoding the raw RLP via [Python's Snappy library](https://github.com/andrix/python-snappy) yields: [block.py.snappy (~70KB)](https://gist.githubusercontent.com/karalabe/72a1a6c4c1dbe6d4996879e415697f06/raw/195bf0c0050ee9805fcd5db4b5b650c58879a55f/block.py.snappy). + +You can verify that an encoded binary can be decoded into the proper plaintext using the following snippets: + +### Go + +``` +$ go get https://github.com/golang/snappy +``` + +```go +package main + +import ( + "bytes" + "encoding/hex" + "fmt" + "io/ioutil" + "log" + "os" + + "github.com/golang/snappy" +) + +func main() { + // Read and decode the decompressed file + plainhex, err := ioutil.ReadFile(os.Args[1]) + if err != nil { + log.Fatalf("Failed to read decompressed file %s: %v", os.Args[1], err) + } + plain, err := hex.DecodeString(string(plainhex)) + if err != nil { + log.Fatalf("Failed to decode decompressed file: %v", err) + } + // Read and decode the compressed file + comphex, err := ioutil.ReadFile(os.Args[2]) + if err != nil { + log.Fatalf("Failed to read compressed file %s: %v", os.Args[2], err) + } + comp, err := hex.DecodeString(string(comphex)) + if err != nil { + log.Fatalf("Failed to decode compressed file: %v", err) + } + // Make sure they match + decomp, err := snappy.Decode(nil, comp) + if err != nil { + log.Fatalf("Failed to decompress compressed file: %v", err) + } + if !bytes.Equal(plain, decomp) { + fmt.Println("Booo, decompressed file does not match provided plain text!") + return + } + fmt.Println("Yay, decompressed data matched provided plain text!") +} +``` + +``` +$ go run main.go block.rlp block.go.snappy +Yay, decompressed data matched provided plain text! + +$ go run main.go block.rlp block.py.snappy +Yay, decompressed data matched provided plain text! +``` + +### Python + +```bash +$ pip install python-snappy +``` + +```py +import snappy +import sys + +# Read and decode the decompressed file +with open(sys.argv[1], 'rb') as file: + plainhex = file.read() + +plain = plainhex.decode("hex") + +# Read and decode the compressed file +with open(sys.argv[2], 'rb') as file: + comphex = file.read() + +comp = comphex.decode("hex") + +# Make sure they match +decomp = snappy.uncompress(comp) +if plain != decomp: + print "Booo, decompressed file does not match provided plain text!" +else: + print "Yay, decompressed data matched provided plain text!" +``` + +``` +$ python main.py block.rlp block.go.snappy +Yay, decompressed data matched provided plain text! + +$ python main.py block.rlp block.py.snappy +Yay, decompressed data matched provided plain text! +``` + ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 3e29ac9126dd3f4630d12e9e07590e4c7474bf3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Wed, 27 Sep 2017 11:55:10 +0300 Subject: [PATCH 0253/1085] Spalling fixes and finalizing the Snappy EIP --- EIPS/eip-devp2p-snappy.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/EIPS/eip-devp2p-snappy.md b/EIPS/eip-devp2p-snappy.md index 01577490d0ae7..57f714e5a7549 100644 --- a/EIPS/eip-devp2p-snappy.md +++ b/EIPS/eip-devp2p-snappy.md @@ -1,36 +1,36 @@ ## Preamble - EIP: - Title: devp2p snappy compression + EIP: 706 + Title: DEVp2p snappy compression Author: Péter Szilágyi Type: Standard Track Category: Networking - Status: Draft + Status: Final Created: 2017-09-07 ## Abstract -The base networking protocol (devp2p) used by Ethereum currently does not employ any form of compression. This results in a massive amount of bandwidth wasted in the entire network, making both initial sync as well as normal operation slower and laggyer. +The base networking protocol (DEVp2p) used by Ethereum currently does not employ any form of compression. This results in a massive amount of bandwidth wasted in the entire network, making both initial sync as well as normal operation slower and laggier. -This EIP proposes a tiny extension to the devp2p protocol to enable [Snappy compression](https://en.wikipedia.org/wiki/Snappy_(compression)) on all message payloads after the initial handshake. After extensive benchmarks, results show that data traffic is decreased by 60-80% for initial sync. You can find exact numbers below. +This EIP proposes a tiny extension to the DEVp2p protocol to enable [Snappy compression](https://en.wikipedia.org/wiki/Snappy_(compression)) on all message payloads after the initial handshake. After extensive benchmarks, results show that data traffic is decreased by 60-80% for initial sync. You can find exact numbers below. ## Motivation Synchronizing the Ethereum main network (block 4,248,000) in Geth using fast sync currently consumes 1.01GB upload and 33.59GB download bandwidth. On the Rinkeby test network (block 852,000) it's 55.89MB upload and 2.51GB download. However, most of this data (blocks, transactions) are heavily compressable. By enabling compression at the message payload level, we can reduce the previous numbers to 1.01GB upload / 13.46GB download on the main network, and 46.21MB upload / 463.65MB download on the test network. -The motivation behind doing this at the devp2p level (opposed to eth for example) is that it would enable compression for all sub-protocols (eth, les, bzz) seamlessly, reducing any complexity those protocols might incur in trying to individually optimize for data traffic. +The motivation behind doing this at the DEVp2p level (opposed to eth for example) is that it would enable compression for all sub-protocols (eth, les, bzz) seamlessly, reducing any complexity those protocols might incur in trying to individually optimize for data traffic. ## Specification -Bump the advertised devp2p version number from `4` to `5`. If during handshake, the remote side advertises support only for version `4`, run the exact same protocol as until now. +Bump the advertised DEVp2p version number from `4` to `5`. If during handshake, the remote side advertises support only for version `4`, run the exact same protocol as until now. -If the remote side advertises a devp2p version `>= 5`, inject a Snappy compression step right before encrypting the devp2p message during sending: +If the remote side advertises a DEVp2p version `>= 5`, inject a Snappy compression step right before encrypting the DEVp2p message during sending: * A message consists of `{Code, Size, Payload}` * Compress the original payload with Snappy and store it in the same field. * Update the message size to the length of the compressed payload. * Encrypt and send the message as before, oblivious to compression. -Similarly to message sending, when receiving a devp2p v5 message from a remote node, insert a Snappy decompression step right after the decrypting the devp2p message: +Similarly to message sending, when receiving a DEVp2p v5 message from a remote node, insert a Snappy decompression step right after the decrypting the DEVp2p message: * A message consists of `{Code, Size, Payload}` * Decrypt the message payload as before, oblivious to compression. @@ -40,19 +40,19 @@ Similarly to message sending, when receiving a devp2p v5 message from a remote n Important caveats: * The handshake message is **never** compressed, since it is needed to negotiate the common version. - * Snappy framing is **not** used, since the devp2p protocol already message oriented. + * Snappy framing is **not** used, since the DEVp2p protocol already message oriented. ### Avoiding DOS attacks -Currently a devp2p message length is limited to 24 bits, amoutning to a maximum size of 16MB. With the introduction of Snappy compression, care must be taken not to blidly decompress messages, since they may get significantly larger than 16MB. +Currently a DEVp2p message length is limited to 24 bits, amounting to a maximum size of 16MB. With the introduction of Snappy compression, care must be taken not to blindy decompress messages, since they may get significantly larger than 16MB. -However, Snappy is capable of calculating the decompressed size of an input message without inflating it in memory. This can be used to discard any messages which decompress above some threshold. **The proposal is to use the same limit (16MB) as the threshold for decompressed messages.** This retains the same guarantees that the current devp2p protocol does, so there won't be surprises in application level protocols. +However, Snappy is capable of calculating the decompressed size of an input message without inflating it in memory. This can be used to discard any messages which decompress above some threshold. **The proposal is to use the same limit (16MB) as the threshold for decompressed messages.** This retains the same guarantees that the current DEVp2p protocol does, so there won't be surprises in application level protocols. ## Alternatives (discarded) **Alternative solutions to data compression that have been brought up and discarded are:** -Extend protocol `xyz` to support compressed messages versus doing it at devp2p level: +Extend protocol `xyz` to support compressed messages versus doing it at DEVp2p level: * **Pro**: Can be better optimized when to compress and when not to. * **Con**: Mixes in transport layer encoding into application layer logic. @@ -69,12 +69,12 @@ Introduce seamless variations of protocol such as `xyz` expanded with `xyz-compr Don't explicitly limit the decompressed message size, only the compressed one: - * **Pro**: Allows larger messages to traverse through devp2p. + * **Pro**: Allows larger messages to traverse through DEVp2p. * **Con**: Upper layer protocols need to check and discard large messages. * **Con**: Needs lazy decompression to allow size limitations without DOS. ## Backwards Compatibility -This proposal is fully backward compatible. Clients upgrading to the proposed devp2p protocol version `5` should still support skipping the compression step for connections that only advertise version `4` of the devp2p protocol. +This proposal is fully backward compatible. Clients upgrading to the proposed DEVp2p protocol version `5` should still support skipping the compression step for connections that only advertise version `4` of the DEVp2p protocol. ## Implementation You can find a reference implementation of this EIP in https://github.com/ethereum/go-ethereum/pull/15106. From 0724db30489091f32fd32c376b6eb6df9a044a4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 2 Oct 2017 17:52:25 +0300 Subject: [PATCH 0254/1085] Add spec references to the Snappy DEVp2p EIP. --- EIPS/eip-devp2p-snappy.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-devp2p-snappy.md b/EIPS/eip-devp2p-snappy.md index 57f714e5a7549..638b15646aad5 100644 --- a/EIPS/eip-devp2p-snappy.md +++ b/EIPS/eip-devp2p-snappy.md @@ -42,11 +42,13 @@ Important caveats: * The handshake message is **never** compressed, since it is needed to negotiate the common version. * Snappy framing is **not** used, since the DEVp2p protocol already message oriented. +*Note: Snappy supports uncompressed binary literals (up to 4GB) too, leaving room for fine-tuned future optimisations for already compressed or encrypted data that would have no gain of compression (Snappy usually detects this case automatically).* + ### Avoiding DOS attacks Currently a DEVp2p message length is limited to 24 bits, amounting to a maximum size of 16MB. With the introduction of Snappy compression, care must be taken not to blindy decompress messages, since they may get significantly larger than 16MB. -However, Snappy is capable of calculating the decompressed size of an input message without inflating it in memory. This can be used to discard any messages which decompress above some threshold. **The proposal is to use the same limit (16MB) as the threshold for decompressed messages.** This retains the same guarantees that the current DEVp2p protocol does, so there won't be surprises in application level protocols. +However, Snappy is capable of calculating the decompressed size of an input message without inflating it in memory (*[the stream starts with the uncompressed length up to a maximum of `2^32 - 1` stored as a little-endian varint](https://github.com/google/snappy/blob/master/format_description.txt#L20)*). This can be used to discard any messages which decompress above some threshold. **The proposal is to use the same limit (16MB) as the threshold for decompressed messages.** This retains the same guarantees that the current DEVp2p protocol does, so there won't be surprises in application level protocols. ## Alternatives (discarded) @@ -188,5 +190,10 @@ $ python main.py block.rlp block.py.snappy Yay, decompressed data matched provided plain text! ``` +## References + + * Snappy website: https://google.github.io/snappy/ + * Snappy specification: https://github.com/google/snappy/blob/master/format_description.txt + ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 25b284e3fb24a61267b9d5d90275d47f1dd13036 Mon Sep 17 00:00:00 2001 From: Maurelian Date: Fri, 8 Sep 2017 09:37:54 -0400 Subject: [PATCH 0255/1085] Add split metropolis HF names Maybe there's a better way to express this, but it seems there could be more clarity about the distinction between 'planned' and 'deferred'. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f5c0be9d167d5..941d289119a9a 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP * **Final** - an EIP that has been adopted in a previous hard fork (for Core/Consensus layer EIPs). * **Deferred** - an EIP that is not being considered for immediate adoption. May be reconsidered in the future for a subsequent hard fork. -# Accepted EIPs (planned for adoption) +# Accepted EIPs (planned for adoption in the Byzantium Metropolis hard fork) | Number |Title | Author | Layer | Status | | ------------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ------------| ----------| | [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Core | Accepted | @@ -23,7 +23,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [649](https://github.com/ethereum/EIPs/pull/669) | Metropolis Difficulty Bomb Delay and Issuance Reduction | Schoedon, Buterin | Core | Accepted | | [658](https://github.com/ethereum/EIPs/pull/658) | Embedding transaction return data in receipts | Nick Johnson | Core | Accepted | -# Deferred EIPs (adoption postponed) +# Deferred EIPs (adoption postponed until the Constantinople Metropolis hard fork) | Number |Title | Author | Layer | Status | | ------------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ------------| ----------| | [86](https://github.com/ethereum/EIPs/pull/208) | Abstraction of transaction origin and signature | Vitalik Buterin | Core | Deferred | From 7d9d8ecc6e859b90871f3ff9cee6e696e19f92a3 Mon Sep 17 00:00:00 2001 From: Hudson Jameson Date: Thu, 5 Oct 2017 12:10:31 -0500 Subject: [PATCH 0256/1085] Renamed file to math convention --- EIPS/{eip-devp2p-snappy.md => eip-706.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename EIPS/{eip-devp2p-snappy.md => eip-706.md} (100%) diff --git a/EIPS/eip-devp2p-snappy.md b/EIPS/eip-706.md similarity index 100% rename from EIPS/eip-devp2p-snappy.md rename to EIPS/eip-706.md From d28d8aca405b8f3e11d8c0359fab28a015c41c2a Mon Sep 17 00:00:00 2001 From: Hudson Jameson Date: Thu, 5 Oct 2017 12:13:54 -0500 Subject: [PATCH 0257/1085] Made final It was suppose to be final beforehand per the PR. --- EIPS/eip-190.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-190.md b/EIPS/eip-190.md index 7abdc30d669b0..f30697add8f35 100644 --- a/EIPS/eip-190.md +++ b/EIPS/eip-190.md @@ -2,7 +2,7 @@ EIP: Draft Title: Ethereum Smart Contract Packaging Standard Authors: Piper Merriam, Tim Coulter, Denis Erfurt (mhhf), RJ Catalano (VoR0220), Iuri Matias (iurimatias) -Status: Draft +Status: Final Type: Standards Track - ERC Created: 2017-01-10 ``` From a89ac4876a619a4b33daeed5fe2a08c28532c604 Mon Sep 17 00:00:00 2001 From: Hudson Jameson Date: Thu, 5 Oct 2017 12:15:43 -0500 Subject: [PATCH 0258/1085] Added final Should have been final before per https://github.com/ethereum/EIPs/pull/203 --- EIPS/eip-190.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-190.md b/EIPS/eip-190.md index f30697add8f35..30e592a43746e 100644 --- a/EIPS/eip-190.md +++ b/EIPS/eip-190.md @@ -1,5 +1,5 @@ ``` -EIP: Draft +EIP: 190 Title: Ethereum Smart Contract Packaging Standard Authors: Piper Merriam, Tim Coulter, Denis Erfurt (mhhf), RJ Catalano (VoR0220), Iuri Matias (iurimatias) Status: Final From 29754d7819a961abf7b0807197d24d3971baa9b8 Mon Sep 17 00:00:00 2001 From: Hudson Jameson Date: Thu, 5 Oct 2017 12:38:35 -0500 Subject: [PATCH 0259/1085] Added a lot of missing EIPs to the list of finalized EIPs --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 941d289119a9a..4d900de3ce8b3 100644 --- a/README.md +++ b/README.md @@ -37,9 +37,21 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Core | Final | | [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Networking | Final | | [20](EIPS/eip-20-token-standard.md) | ERC-20 Token Standard | Fabian Vogelsteller, Vitalik Buterin | ERC | Final | +| [55](EIPS/eip-55.md) | ERC-55 Mixed-case checksum address encoding | Vitalik Buterin | Core | Final | +| [137](EIPS/eip-137.md) | Ethereum Domain Name Service - Specification | Nick Johnson | ERC | Final | | [141](EIPS/eip-141.md) | Designated invalid EVM instruction | Alex Beregszaszi| Core | Final | +| [145](EIPS/eip-145.md) | Bitwise shifting instructions in EVM | Alex Beregszaszi, Paweł Bylica | Core | Final | | [150](EIPS/eip-150.md) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Core | Final | | [155](EIPS/eip-155.md) | Simple replay attack protection | Vitalik Buterin | Core | Final | | [160](EIPS/eip-160.md) | EXP cost increase | Vitalik Buterin | Core | Final | -| [161](EIPS/eip-161.md) | State trie clearing (invariant-preserving alternative) | Gavin Wood | Core | Final | +| [161](EIPS/eip-161.md) | State trie clearing (invariant-preserving alternative) | Gavin Wood | Core | Final | +| [162](EIPS/eip-162.md) | ERC-162 ENS support for reverse resolution of Ethereum addresses | Maurelian, Nick Johnson | ERC | Final | | [170](EIPS/eip-170.md) | Contract code size limit | Vitalik Buterin | Core | Final | +| [170](EIPS/eip-170.md) | Contract code size limit | Vitalik Buterin | Core | Final | +| [181](EIPS/eip-181.md) | ERC-181 ENS support for reverse resolution of Ethereum addresses | Nick Johnson | ERC | Final | +| [190](EIPS/eip-190.md) | ERC-190 Ethereum Smart Contract Packaging Standard | Piper Merriam, Tim Coulter, Denis Erfurt (mhhf), RJ Catalano (VoR0220), Iuri Matias (iurimatias) | ERC | Final | +| [606](EIPS/eip-606.md) | Hardfork Meta: Homestead | Alex Beregszaszi | Meta | Final | +| [607](EIPS/eip-607.md) | Hardfork Meta: Spurious Dragon | Alex Beregszaszi | Meta | Final | +| [608](EIPS/eip-608.md) | Hardfork Meta: Tangerine Whistle | Alex Beregszaszi | Meta | Final | +| [609](EIPS/eip-609.md) | Hardfork Meta: Byzantium | Alex Beregszaszi | Meta | Draft | +| [706](EIPS/eip-706.md) | DEVp2p snappy compression | Péter Szilágyi | Networking | Final | From 947e76504373558c1c7655c360a9d02840c539f9 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Mon, 9 Oct 2017 08:40:53 +0100 Subject: [PATCH 0260/1085] Update eip-draft-returndata.md --- EIPS/eip-draft-returndata.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-draft-returndata.md b/EIPS/eip-draft-returndata.md index 92041fb1c3373..6473da853e844 100644 --- a/EIPS/eip-draft-returndata.md +++ b/EIPS/eip-draft-returndata.md @@ -22,7 +22,7 @@ Full nodes can provide RPCs to get a transaction return status and value by repl Instead, we propose to replace the intermediate state root, already obsoleted by EIP98, with the return status (1 for success, 0 for failure). This both allows callers to determine success status, and remedies the previous omission of return data from the receipt. ## Specification -For blocks where block.number >= METROPOLIS_FORK_BLKNUM, the intermediate state root is replaced by a status code, a single byte with 0 indicating failure (due to any operation that can cause the transaction or top-level call to revert) and 1 indicating success. +For blocks where block.number >= METROPOLIS_FORK_BLKNUM, the intermediate state root is replaced by a status code, 0 indicating failure (due to any operation that can cause the transaction or top-level call to revert) and 1 indicating success. ## Rationale This constitutes a minimal possible change that permits fetching the success/failure state of transactions, preserving existing capabilities with minimum disruption or additional work for Metropolis. From 669e848dc449a1def9ac6c3ec89dbe6b69c72bbb Mon Sep 17 00:00:00 2001 From: Hudson Jameson Date: Wed, 11 Oct 2017 11:35:53 -0500 Subject: [PATCH 0261/1085] Move 145 to deferred. Deleted duplicate 170 and byz draft. --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 4d900de3ce8b3..59a4ef29ab352 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | ------------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ------------| ----------| | [86](https://github.com/ethereum/EIPs/pull/208) | Abstraction of transaction origin and signature | Vitalik Buterin | Core | Deferred | | [96](https://github.com/ethereum/EIPs/pull/210) | Blockhash refactoring | Vitalik Buterin | Core | Deferred | +| [145](EIPS/eip-145.md) | Bitwise shifting instructions in EVM | Alex Beregszaszi, Paweł Bylica | Core | Deferred | # Finalized EIPs (standards that have been adopted) | Number |Title | Author | Layer | Status | @@ -40,18 +41,15 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [55](EIPS/eip-55.md) | ERC-55 Mixed-case checksum address encoding | Vitalik Buterin | Core | Final | | [137](EIPS/eip-137.md) | Ethereum Domain Name Service - Specification | Nick Johnson | ERC | Final | | [141](EIPS/eip-141.md) | Designated invalid EVM instruction | Alex Beregszaszi| Core | Final | -| [145](EIPS/eip-145.md) | Bitwise shifting instructions in EVM | Alex Beregszaszi, Paweł Bylica | Core | Final | | [150](EIPS/eip-150.md) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Core | Final | | [155](EIPS/eip-155.md) | Simple replay attack protection | Vitalik Buterin | Core | Final | | [160](EIPS/eip-160.md) | EXP cost increase | Vitalik Buterin | Core | Final | | [161](EIPS/eip-161.md) | State trie clearing (invariant-preserving alternative) | Gavin Wood | Core | Final | | [162](EIPS/eip-162.md) | ERC-162 ENS support for reverse resolution of Ethereum addresses | Maurelian, Nick Johnson | ERC | Final | | [170](EIPS/eip-170.md) | Contract code size limit | Vitalik Buterin | Core | Final | -| [170](EIPS/eip-170.md) | Contract code size limit | Vitalik Buterin | Core | Final | | [181](EIPS/eip-181.md) | ERC-181 ENS support for reverse resolution of Ethereum addresses | Nick Johnson | ERC | Final | | [190](EIPS/eip-190.md) | ERC-190 Ethereum Smart Contract Packaging Standard | Piper Merriam, Tim Coulter, Denis Erfurt (mhhf), RJ Catalano (VoR0220), Iuri Matias (iurimatias) | ERC | Final | | [606](EIPS/eip-606.md) | Hardfork Meta: Homestead | Alex Beregszaszi | Meta | Final | | [607](EIPS/eip-607.md) | Hardfork Meta: Spurious Dragon | Alex Beregszaszi | Meta | Final | | [608](EIPS/eip-608.md) | Hardfork Meta: Tangerine Whistle | Alex Beregszaszi | Meta | Final | -| [609](EIPS/eip-609.md) | Hardfork Meta: Byzantium | Alex Beregszaszi | Meta | Draft | | [706](EIPS/eip-706.md) | DEVp2p snappy compression | Péter Szilágyi | Networking | Final | From 81e4cde6bef76b2ef3dcb34772e392258f7b4746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Lesaege?= Date: Thu, 12 Oct 2017 22:25:42 +0200 Subject: [PATCH 0262/1085] Fix misspelling in "compatibility" --- EIPS/eip-20-token-standard.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-20-token-standard.md b/EIPS/eip-20-token-standard.md index e1086c399ded8..4b209dcd0df95 100644 --- a/EIPS/eip-20-token-standard.md +++ b/EIPS/eip-20-token-standard.md @@ -128,7 +128,7 @@ Allows `_spender` to withdraw from your account multiple times, up to the `_valu **NOTE**: To prevent attack vectors like the one [described here](https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/) and discussed [here](https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729), clients SHOULD make sure to create user interfaces in such a way that they set the allowance first to `0` before setting it to another value for the same spender. -THOUGH The contract itself shouldn't enforce it, to allow backwards compatilibilty with contracts deployed before +THOUGH The contract itself shouldn't enforce it, to allow backwards compatibility with contracts deployed before ``` js function approve(address _spender, uint256 _value) returns (bool success) From a69fd09298f364f7dc70cb1520b5c8cd82b25357 Mon Sep 17 00:00:00 2001 From: sandakersmann Date: Tue, 17 Oct 2017 16:39:52 +0200 Subject: [PATCH 0263/1085] Byzantium is now live --- README.md | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 59a4ef29ab352..7b882107cfe4a 100644 --- a/README.md +++ b/README.md @@ -10,19 +10,6 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP * **Final** - an EIP that has been adopted in a previous hard fork (for Core/Consensus layer EIPs). * **Deferred** - an EIP that is not being considered for immediate adoption. May be reconsidered in the future for a subsequent hard fork. -# Accepted EIPs (planned for adoption in the Byzantium Metropolis hard fork) -| Number |Title | Author | Layer | Status | -| ------------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ------------| ----------| -| [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Core | Accepted | -| [140](https://github.com/ethereum/EIPs/pull/206) | REVERT instruction in the Ethereum Virtual Machine | Beregszaszi, Mushegian| Core | Accepted | -| [196](https://github.com/ethereum/EIPs/pull/213) | Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 | Reitwiessner | Core | Accepted | -| [197](https://github.com/ethereum/EIPs/pull/212) | Precompiled contracts for optimal Ate pairing check on the elliptic curve alt_bn128 | Buterin, Reitwiessner | Core | Accepted | -| [198](https://github.com/ethereum/EIPs/pull/198) | Precompiled contract for bigint modular exponentiation | Vitalik Buterin | Core | Accepted | -| [211](https://github.com/ethereum/EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner| Core | Accepted | -| [214](https://github.com/ethereum/EIPs/pull/214) | New opcode STATICCALL | Buterin, Reitwiessner | Core | Accepted | -| [649](https://github.com/ethereum/EIPs/pull/669) | Metropolis Difficulty Bomb Delay and Issuance Reduction | Schoedon, Buterin | Core | Accepted | -| [658](https://github.com/ethereum/EIPs/pull/658) | Embedding transaction return data in receipts | Nick Johnson | Core | Accepted | - # Deferred EIPs (adoption postponed until the Constantinople Metropolis hard fork) | Number |Title | Author | Layer | Status | | ------------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ------------| ----------| @@ -39,7 +26,9 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Networking | Final | | [20](EIPS/eip-20-token-standard.md) | ERC-20 Token Standard | Fabian Vogelsteller, Vitalik Buterin | ERC | Final | | [55](EIPS/eip-55.md) | ERC-55 Mixed-case checksum address encoding | Vitalik Buterin | Core | Final | +| [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Core | Final | | [137](EIPS/eip-137.md) | Ethereum Domain Name Service - Specification | Nick Johnson | ERC | Final | +| [140](https://github.com/ethereum/EIPs/pull/206) | REVERT instruction in the Ethereum Virtual Machine | Beregszaszi, Mushegian| Core | Final | | [141](EIPS/eip-141.md) | Designated invalid EVM instruction | Alex Beregszaszi| Core | Final | | [150](EIPS/eip-150.md) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Core | Final | | [155](EIPS/eip-155.md) | Simple replay attack protection | Vitalik Buterin | Core | Final | @@ -49,7 +38,14 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [170](EIPS/eip-170.md) | Contract code size limit | Vitalik Buterin | Core | Final | | [181](EIPS/eip-181.md) | ERC-181 ENS support for reverse resolution of Ethereum addresses | Nick Johnson | ERC | Final | | [190](EIPS/eip-190.md) | ERC-190 Ethereum Smart Contract Packaging Standard | Piper Merriam, Tim Coulter, Denis Erfurt (mhhf), RJ Catalano (VoR0220), Iuri Matias (iurimatias) | ERC | Final | +| [196](https://github.com/ethereum/EIPs/pull/213) | Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 | Reitwiessner | Core | Final | +| [197](https://github.com/ethereum/EIPs/pull/212) | Precompiled contracts for optimal Ate pairing check on the elliptic curve alt_bn128 | Buterin, Reitwiessner | Core | Final | +| [198](https://github.com/ethereum/EIPs/pull/198) | Precompiled contract for bigint modular exponentiation | Vitalik Buterin | Core | Final | +| [211](https://github.com/ethereum/EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner| Core | Final | +| [214](https://github.com/ethereum/EIPs/pull/214) | New opcode STATICCALL | Buterin, Reitwiessner | Core | Final | | [606](EIPS/eip-606.md) | Hardfork Meta: Homestead | Alex Beregszaszi | Meta | Final | | [607](EIPS/eip-607.md) | Hardfork Meta: Spurious Dragon | Alex Beregszaszi | Meta | Final | | [608](EIPS/eip-608.md) | Hardfork Meta: Tangerine Whistle | Alex Beregszaszi | Meta | Final | +| [649](https://github.com/ethereum/EIPs/pull/669) | Metropolis Difficulty Bomb Delay and Issuance Reduction | Schoedon, Buterin | Core | Final | +| [658](https://github.com/ethereum/EIPs/pull/658) | Embedding transaction return data in receipts | Nick Johnson | Core | Final | | [706](EIPS/eip-706.md) | DEVp2p snappy compression | Péter Szilágyi | Networking | Final | From c9e53026aa4da67df0c95bd902f0f3981da29b99 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Sat, 21 Oct 2017 09:29:39 -0700 Subject: [PATCH 0264/1085] eip-55 checksum_encode spec typo --- EIPS/eip-55.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-55.md b/EIPS/eip-55.md index d7f0369ca4010..e60dc159b334c 100644 --- a/EIPS/eip-55.md +++ b/EIPS/eip-55.md @@ -26,7 +26,7 @@ def checksum_encode(addr): # Takes a 20-byte binary address as input return '0x'+o def test(addrstr): - assert(addrstr == checksum_encode2(bytes.fromhex(addrstr[2:]))) + assert(addrstr == checksum_encode(bytes.fromhex(addrstr[2:]))) test('0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed') test('0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359') From afe03e700e381b7197d791f773b0220e94312dc1 Mon Sep 17 00:00:00 2001 From: "Daniel A. Nagy" Date: Wed, 1 Nov 2017 23:54:51 +0100 Subject: [PATCH 0265/1085] ERC: Added chain_id Support for testnets and private chains added. --- EIPS/pay_req_url_fmt.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/EIPS/pay_req_url_fmt.md b/EIPS/pay_req_url_fmt.md index 51fb5a84179a6..dcaf7f953e66b 100644 --- a/EIPS/pay_req_url_fmt.md +++ b/EIPS/pay_req_url_fmt.md @@ -8,7 +8,7 @@ Status: Draft Replaces: 67 Created: 2017-08-01 - Requires: 20 + Requires: 20, 137 ## Simple Summary A standard way of representing various transactions, especially payment requests in Ethers and ERC #20 tokens as URLs. @@ -26,8 +26,9 @@ This specification supersedes ERC #67, which is a URL format for representing ar ### Syntax Payment request URLs contain "ethereum" in their schema (protocol) part and are constructed as follows: - request = "ethereum" ":" target_address [ "/" function_name ] [ "?" parameters ] + request = "ethereum" ":" target_address [ "@" chain_id ] [ "/" function_name ] [ "?" parameters ] target_address = ethereum_address + chain_id = 1*DIGIT function_name = STRING ethereum_address = ( "0x" 40*40HEXDIG ) / ENS_NAME parameters = parameter *( "&" parameter ) @@ -55,6 +56,8 @@ For the syntax of ENS_NAME, please consult ERC #137 defining Ethereum Name Servi `target_address` is mandatory and denotes either the beneficiary of native token payment (see below) or the contract address with which the user is asked to interact. +`chain_id` is optional and contains the decimal chain ID, such that transactions on various test- and private networks can be requested. If no `chain_id` is present, the main network (1) is assumed. + If `function_name` is missing, then the URL is requesting payment in the native token of the blockchain, which is Ether in our case. The amount is specified in `value` parameter, in the atomic unit (i.e. Wei). The use of scientific notation is strongly encouraged. For example, requesting 2.014 ETH to address `0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359` would look as follows: [ethereum:0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359?value=2.014e18](ethereum:0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359?value=2.014e18) From 7eff5575dc47b7289540ff54f33b1f39c35daac6 Mon Sep 17 00:00:00 2001 From: "Daniel A. Nagy" Date: Thu, 2 Nov 2017 16:15:16 +0100 Subject: [PATCH 0266/1085] ERC: versioning --- EIPS/pay_req_url_fmt.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/EIPS/pay_req_url_fmt.md b/EIPS/pay_req_url_fmt.md index dcaf7f953e66b..d930cb5a7993b 100644 --- a/EIPS/pay_req_url_fmt.md +++ b/EIPS/pay_req_url_fmt.md @@ -73,3 +73,6 @@ Note that the indicated amount is only a suggestion (as are all the supplied arg ## Rationale The proposed format is chosen to resemble `bitcoin:` URLs as closely as possible, as both users and application programmers are already familiar with that format. In particular, this motivated the omission of the unit, which is often used in Ethereum ecosystem. Handling different orders of magnitude is delegated to the application, just like in the case of `bitcoin:`, but lacking access to the block chain, the application can take a hint from the exponent in the URL. Additional parameters may be added, if popular use cases requiring them emerge in practice. + +## Compatibility and Versioning +Future upgrades that are partially or fully incompatible with this proposal should introduce a version prefix to `target_address` that is separated by a dash (`-`) character from whatever follows it. Exact specifications lie outside the scope of this document. From e03547104e806aba4aa512fe5ade2febfde77856 Mon Sep 17 00:00:00 2001 From: "Daniel A. Nagy" Date: Fri, 3 Nov 2017 21:22:24 +0100 Subject: [PATCH 0267/1085] ERC: We are 681 --- EIPS/pay_req_url_fmt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/pay_req_url_fmt.md b/EIPS/pay_req_url_fmt.md index d930cb5a7993b..05dd7ed312966 100644 --- a/EIPS/pay_req_url_fmt.md +++ b/EIPS/pay_req_url_fmt.md @@ -1,6 +1,6 @@ ## Preamble - EIP: + EIP: 861 Title: URL Format for Transaction Requests Author: Daniel A. Nagy Type: Standard Track From b587225416564c2e65d970acc52806d2d4eff3d2 Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Sat, 4 Nov 2017 08:29:50 -0500 Subject: [PATCH 0268/1085] Change status to Final --- EIPS/eip-649.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index 8143e16a63320..b4e72a0e61c0b 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -5,7 +5,7 @@ Authors: Afri Schoedon, Vitalik Buterin Type: Standard Track Category: Core - Status: Accepted + Status: Final Created: 2017-06-21 Replaces: 186 From d46dd25cf088aebb9ae202a5f4cb726d2f8a60e8 Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Sat, 4 Nov 2017 08:38:32 -0500 Subject: [PATCH 0269/1085] Add other notable implementations --- EIPS/eip-649.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index b4e72a0e61c0b..ebdc9969ac410 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -60,8 +60,15 @@ The following clients implemented EIP-649: - Geth [#15028](https://github.com/ethereum/go-ethereum/pull/15028) - Parity [#5855](https://github.com/paritytech/parity/pull/5855) - EthereumJ [#927](https://github.com/ethereum/ethereumj/pull/927) +- Cpp-Ethereum [#4050](https://github.com/ethereum/cpp-ethereum/issues/4050) +- PyEthereum [#383](https://github.com/ethereum/pyethereum/pull/383) The Yellow Paper implements EIP-649 in [#333](https://github.com/ethereum/yellowpaper/pull/333). +Other notable implementations: + +- Eth-Isabelle [#459](https://github.com/pirapira/eth-isabelle/issues/459) +- Py-EVM [#123](https://github.com/pipermerriam/py-evm/pull/123) + ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 6a7aa9ffd768e2e3f6a33406e673731408415a8a Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Sat, 4 Nov 2017 08:39:19 -0500 Subject: [PATCH 0270/1085] Add tests --- EIPS/eip-649.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index ebdc9969ac410..8cf8896470a36 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -52,7 +52,7 @@ This was previously discussed at All Core Devs Meeting [#09](https://github.com/ This EIP is not forward compatible and introduces backwards incompatibilities in the difficulty calculation, as well as the block, uncle and nephew reward structure. Therefore, it should be included in a scheduled hardfork at a certain block number. It's suggested to include this EIP in the first of the two Metropolis hard-forks, the _Byzantium_ fork. ## Test Cases -No test cases exist yet. But will be easy to set up based on the rules specified above. +Test cases exist in ethereum/tests [#269](https://github.com/ethereum/tests/pull/269). ## Implementation The following clients implemented EIP-649: From c5b49c6af7fe7a54afd53aae024c7e8ad7e7273c Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Sat, 4 Nov 2017 08:43:56 -0500 Subject: [PATCH 0271/1085] Add missing core dev meeting links --- EIPS/eip-649.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index 8cf8896470a36..e2adda472a9fc 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -46,7 +46,7 @@ This is the existing pre-Metropolis formula for nephew rewards, simply adjusted ## Rationale This will delay the ice age by 42 million seconds (approximately 1.4 years), so the chain would be back at 30 second block times at the end of 2018. An alternate proposal was to add special rules to the difficulty calculation to effectively _pause_ the difficulty between different blocks. This would lead to similar results. -This was previously discussed at All Core Devs Meeting [#09](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%209.md#metropolis-timing-and-roadmap-discussion), [#12](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2012.md#5-metropolis-update), [#13](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2013.md#3-eip-186-reduce-eth-issuance-before-proof-of-stake-hudson), and [#14](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2014.md#1-eip-186-reduce-eth-issuance-before-proof-of-stake-core-devs). Consensus on the specification was achieved in All Core Devs Meeting [#19](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2019.md) and specification drafted in EIP issue [#649](https://github.com/ethereum/EIPs/issues/649). It was decided to replace EIP [#186](https://github.com/ethereum/EIPs/issues/186) and include the block reward reduction along with the difficulty bomb delay in All Core Devs Meeting [#20](#) and [#21](#); accepted in [#22](#). +This was previously discussed at All Core Devs Meeting [#09](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%209.md#metropolis-timing-and-roadmap-discussion), [#12](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2012.md#5-metropolis-update), [#13](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2013.md#3-eip-186-reduce-eth-issuance-before-proof-of-stake-hudson), and [#14](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2014.md#1-eip-186-reduce-eth-issuance-before-proof-of-stake-core-devs). Consensus on the specification was achieved in All Core Devs Meeting [#19](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2019.md) and specification drafted in EIP issue [#649](https://github.com/ethereum/EIPs/issues/649). It was decided to replace EIP [#186](https://github.com/ethereum/EIPs/issues/186) and include the block reward reduction along with the difficulty bomb delay in All Core Devs Meeting [#20](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2020.md) and [#21](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2021.md); accepted in [#22](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2022.md). ## Backwards Compatibility This EIP is not forward compatible and introduces backwards incompatibilities in the difficulty calculation, as well as the block, uncle and nephew reward structure. Therefore, it should be included in a scheduled hardfork at a certain block number. It's suggested to include this EIP in the first of the two Metropolis hard-forks, the _Byzantium_ fork. From 4eca54f2899e78ea7a91981aa42f0c4c34526946 Mon Sep 17 00:00:00 2001 From: "Daniel A. Nagy" Date: Tue, 7 Nov 2017 12:53:27 +0100 Subject: [PATCH 0272/1085] ERC: Corrected numbering typo and renamed file --- EIPS/{pay_req_url_fmt.md => eip-681.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename EIPS/{pay_req_url_fmt.md => eip-681.md} (99%) diff --git a/EIPS/pay_req_url_fmt.md b/EIPS/eip-681.md similarity index 99% rename from EIPS/pay_req_url_fmt.md rename to EIPS/eip-681.md index 05dd7ed312966..26b17bb3754e3 100644 --- a/EIPS/pay_req_url_fmt.md +++ b/EIPS/eip-681.md @@ -1,6 +1,6 @@ ## Preamble - EIP: 861 + EIP: 681 Title: URL Format for Transaction Requests Author: Daniel A. Nagy Type: Standard Track From a4938e4224f62b66db959d1ec14ce0ac496614c5 Mon Sep 17 00:00:00 2001 From: Jack Peterson Date: Thu, 9 Nov 2017 20:09:38 -0800 Subject: [PATCH 0273/1085] Added transaction return values EIP draft --- EIPS/eip-transaction_return_values.md | 55 +++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 EIPS/eip-transaction_return_values.md diff --git a/EIPS/eip-transaction_return_values.md b/EIPS/eip-transaction_return_values.md new file mode 100644 index 0000000000000..be340f977f7ce --- /dev/null +++ b/EIPS/eip-transaction_return_values.md @@ -0,0 +1,55 @@ +## Preamble + + EIP: + Title: Return values for eth_sendTransaction and eth_sendRawTransaction RPC requests + Author: Jack Peterson + Type: Standard Track + Category: Interface + Status: Draft + Created: 2017-11-09 + + +## Simple Summary +Provide a way for external callers to access return values of functions executed during Ethereum transactions. + +## Abstract +When a new transaction is submitted successfully to an Ethereum node, the node responds with the transaction's hash. If the transaction involved the execution of a contract function that returns a value, the return value is simply discarded. If the return value is state-dependent, which is common, there is not a straightforward way for the caller to access or compute the return value. This EIP proposes that when a transaction is submitted, the caller may subscribe to the transaction's hash. The Ethereum node would then push a notification to the caller when the transaction is sealed (and again if/when the transaction is affected by chain reorganizations). + +## Motivation +External callers presently have no way of accessing return values from Ethereum, if the function was executed via `eth_sendTransaction` or `eth_sendRawTransaction` RPC request. Access to return value is in many cases a desirable feature. Making return values available to external callers also addresses the inconsistency between _internal_ callers, which have access to return values within the context of the transaction, and external callers, which do not. The typical workaround is to log the return values, which is bad for several reasons: it contributes to chain bloat, it imposes additional gas costs on the caller, and it can result in many unused logs being written if the externally called function involves other (internal) function calls that log their return values. + +## Specification +A transaction is submitted via `eth_sendTransaction` or `eth_sendRawTransaction` RPC request and has the transaction hash `"0x00000000000000000000000000000000000000000000000000000000deadbeef"`. The sender can then subscribe to the transaction's return value by sending an `eth_subscribe` request with the transaction hash as a parameter: + +```json +{"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["0x00000000000000000000000000000000000000000000000000000000deadbeef"]} +``` + +The Ethereum node responds with a subscription ID: + +```json +{"jsonrpc": "2.0", "id": 1, "result": "0x00000000000000000000000000000b0b"} +``` + +When the transaction is sealed (mined), the Ethereum node computes the return value (`"0x000000000000000000000000000000000000000000000000000000000000002a"`) and pushes a notification to the subscriber: + +```json +{ + "jsonrpc": "2.0", + "method": "eth_subscription", + "params": { + "result": "0x000000000000000000000000000000000000000000000000000000000000002a", + "subscription": "0x00000000000000000000000000000b0b" + } +} +``` + +Unlike other subscriptions, the subscriber only receives notifications about a transaction's return value in two cases: first when the transaction is sealed, and again (with an extra `"removed": true` field) if the transaction is affected by a chain reorganization. + +## Rationale +[A recent EIP](https://github.com/ethereum/EIPs/pull/658) originally proposed adding return values to transaction receipts. However, return data is not charged for (as it is not presently stored on the blockchain), so adding it to transaction receipts could result in DoS and spam opportunities. Instead, a simple Boolean `status` field was added to transaction receipts. This was included in the Byzantium hard fork. + +The primary advantage of using a push notification is that no extra data needs to be stored on the blockchain. One ramification of this design is that after-the-fact lookups of the return value are impossible. However, this is consistent with how return values are normally used: they are only accessible to the caller when the function returns, and are not stored for later use. + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 069f75b0e59fd6c856916e2c7806707d438007ac Mon Sep 17 00:00:00 2001 From: Jack Peterson Date: Fri, 10 Nov 2017 22:09:42 -0800 Subject: [PATCH 0274/1085] Changed to single subscription for all return values; added polling notes --- EIPS/eip-transaction_return_values.md | 56 +++++++++++++++++++++------ 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/EIPS/eip-transaction_return_values.md b/EIPS/eip-transaction_return_values.md index be340f977f7ce..385c9114d10e4 100644 --- a/EIPS/eip-transaction_return_values.md +++ b/EIPS/eip-transaction_return_values.md @@ -1,7 +1,7 @@ ## Preamble EIP: - Title: Return values for eth_sendTransaction and eth_sendRawTransaction RPC requests + Title: Subscriptions and filters for transaction return data Author: Jack Peterson Type: Standard Track Category: Interface @@ -10,19 +10,21 @@ ## Simple Summary -Provide a way for external callers to access return values of functions executed during Ethereum transactions. +Provide a way for external callers to access the return data of functions executed during Ethereum transactions. ## Abstract -When a new transaction is submitted successfully to an Ethereum node, the node responds with the transaction's hash. If the transaction involved the execution of a contract function that returns a value, the return value is simply discarded. If the return value is state-dependent, which is common, there is not a straightforward way for the caller to access or compute the return value. This EIP proposes that when a transaction is submitted, the caller may subscribe to the transaction's hash. The Ethereum node would then push a notification to the caller when the transaction is sealed (and again if/when the transaction is affected by chain reorganizations). +When a new transaction is submitted successfully to an Ethereum node, the node responds with the transaction's hash. If the transaction involved the execution of a contract function that returns data, the data is discarded. If the return data is state-dependent, which is common, there is no straightforward way for the caller to access or compute the return data. This EIP proposes that callers should be able to subscribe to (or poll for) the return data of their transactions. The Ethereum node then sends the return data to the caller when the transactions are sealed. ## Motivation -External callers presently have no way of accessing return values from Ethereum, if the function was executed via `eth_sendTransaction` or `eth_sendRawTransaction` RPC request. Access to return value is in many cases a desirable feature. Making return values available to external callers also addresses the inconsistency between _internal_ callers, which have access to return values within the context of the transaction, and external callers, which do not. The typical workaround is to log the return values, which is bad for several reasons: it contributes to chain bloat, it imposes additional gas costs on the caller, and it can result in many unused logs being written if the externally called function involves other (internal) function calls that log their return values. +External callers presently have no way of accessing return data from Ethereum, if the function was executed via `eth_sendTransaction` or `eth_sendRawTransaction` RPC request. Access to function return data is in many cases a desirable feature. Making return data available to external callers also addresses the inconsistency between internal callers, which have access to return data within the context of the transaction, and external callers, which do not. Presently, a common workaround is to log the return data, which is bad for several reasons: it contributes to chain bloat, imposes additional gas costs on the caller, and can result in unused logs being written if the externally called function involves other (internal) function calls that log their return data. ## Specification -A transaction is submitted via `eth_sendTransaction` or `eth_sendRawTransaction` RPC request and has the transaction hash `"0x00000000000000000000000000000000000000000000000000000000deadbeef"`. The sender can then subscribe to the transaction's return value by sending an `eth_subscribe` request with the transaction hash as a parameter: + +### Subscriptions +A caller who wants to be notified of return data for their transactions sends an `eth_subscribe` RPC request with the parameter `"returnData"`: ```json -{"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["0x00000000000000000000000000000000000000000000000000000000deadbeef"]} +{"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["returnData"]} ``` The Ethereum node responds with a subscription ID: @@ -31,25 +33,57 @@ The Ethereum node responds with a subscription ID: {"jsonrpc": "2.0", "id": 1, "result": "0x00000000000000000000000000000b0b"} ``` -When the transaction is sealed (mined), the Ethereum node computes the return value (`"0x000000000000000000000000000000000000000000000000000000000000002a"`) and pushes a notification to the subscriber: +The caller submits a transaction via `eth_sendTransaction` or `eth_sendRawTransaction` RPC request which has the transaction hash `"0x00000000000000000000000000000000000000000000000000000000deadbeef"`. When the transaction is sealed (mined), the Ethereum node computes the return value (`"0x000000000000000000000000000000000000000000000000000000000000002a"`) and pushes a notification to the caller: ```json { "jsonrpc": "2.0", "method": "eth_subscription", "params": { - "result": "0x000000000000000000000000000000000000000000000000000000000000002a", + "result": { + "transactionHash": "0x00000000000000000000000000000000000000000000000000000000deadbeef", + "returnData": "0x000000000000000000000000000000000000000000000000000000000000002a" + }, "subscription": "0x00000000000000000000000000000b0b" } } ``` -Unlike other subscriptions, the subscriber only receives notifications about a transaction's return value in two cases: first when the transaction is sealed, and again (with an extra `"removed": true` field) if the transaction is affected by a chain reorganization. +The caller receives notifications about their transactions' return data in two cases: first when a transaction is sealed, and again (with an extra `"removed": true` field) if a transaction is affected by a chain reorganization. As with other subscriptions, the caller can send an `eth_unsubscribe` RPC request to stop receiving push notifications: + +```json +{"jsonrpc": "2.0", "id": 2, "method": "eth_unsubscribe", "params": ["0x00000000000000000000000000000b0b"]} +``` + +### Polling +Push notifications require full duplex connections (i.e., websocket or IPC). Instead of subscribing, callers using HTTP send an `eth_newFilter` request: + +```json +{"jsonrpc": "2.0", "id": 1, "method": "eth_newFilter", "params": ["returnData"]} +``` + +The Ethereum node responds with a filter ID: + +```json +{"jsonrpc": "2.0", "id": 1, "result": "0x1"} +``` + +When a transaction is submitted, the Ethereum node computes the return data and pushes it to a queue, which is emptied when the caller polls using `eth_getFilterChanges`: + +```json +{"jsonrpc": "2.0", "id": 2, "method": "eth_getFilterChanges", "params": ["0x1"]} +``` + +The node responds with an array of return data, in the order they were computed: + +```json +{"jsonrpc": "2.0", "id": 2, "result": ["0x000000000000000000000000000000000000000000000000000000000000002a"]} +``` ## Rationale -[A recent EIP](https://github.com/ethereum/EIPs/pull/658) originally proposed adding return values to transaction receipts. However, return data is not charged for (as it is not presently stored on the blockchain), so adding it to transaction receipts could result in DoS and spam opportunities. Instead, a simple Boolean `status` field was added to transaction receipts. This was included in the Byzantium hard fork. +[EIP 658](https://github.com/ethereum/EIPs/pull/658) originally proposed adding return data to transaction receipts. However, return data is not charged for (as it is not stored on the blockchain), so adding it to transaction receipts could result in DoS and spam opportunities. Instead, a simple Boolean `status` field was added to transaction receipts. This modified version of EIP 658 was included in the Byzantium hard fork. While the `status` field is useful, applications often need the return data as well. -The primary advantage of using a push notification is that no extra data needs to be stored on the blockchain. One ramification of this design is that after-the-fact lookups of the return value are impossible. However, this is consistent with how return values are normally used: they are only accessible to the caller when the function returns, and are not stored for later use. +The primary advantage of using the strategy outlined here is efficiency: no extra data needs to be stored on the blockchain, and minimal extra computational load is imposed on nodes. Since light clients have the current state, they can compute and send return data notifications without contacting a server. Although after-the-fact lookups of the return value would not be supported, this is consistent with the conventional use of return data, which are only accessible to the caller when the function returns, and are not stored for later use. ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 495e7d2b3111fe752dd3cb080660d30a0b317699 Mon Sep 17 00:00:00 2001 From: Jack Peterson Date: Sat, 11 Nov 2017 11:48:42 -0800 Subject: [PATCH 0275/1085] Added transactionHash to polling results array --- EIPS/eip-transaction_return_values.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-transaction_return_values.md b/EIPS/eip-transaction_return_values.md index 385c9114d10e4..97107279d93cf 100644 --- a/EIPS/eip-transaction_return_values.md +++ b/EIPS/eip-transaction_return_values.md @@ -20,7 +20,7 @@ External callers presently have no way of accessing return data from Ethereum, i ## Specification -### Subscriptions +### Subscription A caller who wants to be notified of return data for their transactions sends an `eth_subscribe` RPC request with the parameter `"returnData"`: ```json @@ -74,10 +74,17 @@ When a transaction is submitted, the Ethereum node computes the return data and {"jsonrpc": "2.0", "id": 2, "method": "eth_getFilterChanges", "params": ["0x1"]} ``` -The node responds with an array of return data, in the order they were computed: +The node responds with an array of transaction hashes and their corresponding return data, in the order they were computed: ```json -{"jsonrpc": "2.0", "id": 2, "result": ["0x000000000000000000000000000000000000000000000000000000000000002a"]} +{ + "jsonrpc": "2.0", + "id": 2, + "result": [{ + "transactionHash": "0x00000000000000000000000000000000000000000000000000000000deadbeef", + "returnData": "0x000000000000000000000000000000000000000000000000000000000000002a" + }] +} ``` ## Rationale From 6cf8628839dc9120ace1d9606344251d5385e7c9 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Fri, 17 Nov 2017 11:44:59 -0600 Subject: [PATCH 0276/1085] add Byzantium meta-EIP to Finalized table --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7b882107cfe4a..b1daa4512d9bc 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [606](EIPS/eip-606.md) | Hardfork Meta: Homestead | Alex Beregszaszi | Meta | Final | | [607](EIPS/eip-607.md) | Hardfork Meta: Spurious Dragon | Alex Beregszaszi | Meta | Final | | [608](EIPS/eip-608.md) | Hardfork Meta: Tangerine Whistle | Alex Beregszaszi | Meta | Final | +| [609](EIPS/eip-609.md) | Hardfork Meta: Byzantium | Alex Beregszaszi | Meta | Final | | [649](https://github.com/ethereum/EIPs/pull/669) | Metropolis Difficulty Bomb Delay and Issuance Reduction | Schoedon, Buterin | Core | Final | | [658](https://github.com/ethereum/EIPs/pull/658) | Embedding transaction return data in receipts | Nick Johnson | Core | Final | | [706](EIPS/eip-706.md) | DEVp2p snappy compression | Péter Szilágyi | Networking | Final | From 2145841c6ab56142d6c9beec5d2aaefd5bb52c3d Mon Sep 17 00:00:00 2001 From: cdetrio Date: Fri, 17 Nov 2017 11:56:30 -0600 Subject: [PATCH 0277/1085] update EIP editors list --- EIPS/eip-1.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index 1299f4238d565..c3ee19dfbc8f4 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -174,19 +174,13 @@ The current EIP editors are ` * Casey Detrio (@cdetrio)` -` * Fabian Vogelsteller (@frozeman)` - -` * Gavin Wood (@gavofyork)` - ` * Hudson Jameson (@Souptacular)` -` * Jeffrey Wilcke (@obscuren)` - ` * Martin Becze (@wanderer)` ` * Nick Johnson (@arachnid)` -` * Roman Mandeleil (@romanman)` +` * Yoichi Hirai (@pirapira)` ` * Vitalik Buterin (@vbuterin)` From 68fa87eb41bb26a550350db7e32550a6bc35907e Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 17 Nov 2017 19:38:33 +0100 Subject: [PATCH 0278/1085] Fix links --- EIPS/ecopts.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/ecopts.md b/EIPS/ecopts.md index 614f4ac1361b8..c5d32cb7747cf 100644 --- a/EIPS/ecopts.md +++ b/EIPS/ecopts.md @@ -94,12 +94,12 @@ Inputs to test: Implementation of these primitives are available here: - - [libff](https://github.com/scipr-lab/libff/blob/master/src/algebra/curves/alt_bn128/alt_bn128_g1.cpp) (C++) + - [libff](https://github.com/scipr-lab/libff/blob/master/libff/algebra/curves/alt_bn128/alt_bn128_g1.cpp) (C++) - [bn](https://github.com/zcash/bn/blob/master/src/groups/mod.rs) (Rust) In both codebases, a specific group on the curve alt_bn128 is used and is called G1. - - [Python](https://github.com/ethereum/research/blob/master/zksnark/py_pairing/py_pairing/bn128_curve.py) - probably most self-contained and best readable. + - [Python](https://github.com/ethereum/py_pairing/blob/master/py_ecc/bn128/bn128_curve.py) - probably most self-contained and best readable. ## Copyright From e0c717c96c9477691152dca53b82058a79e184ca Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 17 Nov 2017 19:40:05 +0100 Subject: [PATCH 0279/1085] Move ecopts.md to eip-213.md --- EIPS/{ecopts.md => eip-213.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename EIPS/{ecopts.md => eip-213.md} (100%) diff --git a/EIPS/ecopts.md b/EIPS/eip-213.md similarity index 100% rename from EIPS/ecopts.md rename to EIPS/eip-213.md From f37874200ad28bcf0cc3b171242174bdcf62559d Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 17 Nov 2017 19:46:47 +0100 Subject: [PATCH 0280/1085] Fix a typo https://github.com/ethereum/EIPs/pull/211#pullrequestreview-58334736 --- EIPS/returndatacopy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/returndatacopy.md b/EIPS/returndatacopy.md index f8b940854b458..2a8a358d7e31c 100644 --- a/EIPS/returndatacopy.md +++ b/EIPS/returndatacopy.md @@ -29,7 +29,7 @@ Note that this proposal also makes the EIP that proposes to allow to return data ## Specification -Add two new opcodes and amend the semantics of any opcode that creates a new call frame (like `CALL`, `CREATE`, `DELEGATECALL`, ...) called call-like opcodes in the following. It is assumed that the EVM (to be more specific: an EVM call frame) has a new internal buffer of variable size, called the return data buffer. This buffer is created empty for each new call frame. Upon executing any call-like opcode, the buffer is cleared (its size is set to zero). After executing a call-like opcode, the complete return data (or failure data, see EIP [206](https://github.com/ethereum/EIPs/pull/206)) of the call is stored in the return data buffer (of the caller), and its size changed accordingly. As an exception, `CREATE` and `CREATE2` are considered to return the empty buffer in the success case and the failure data in the failure case. If the call-like opcode is executed but does not really instanciate a call frame (for example due to insufficient funds for a value transfer or if the called contract does not exist), the return data buffer is empty. +Add two new opcodes and amend the semantics of any opcode that creates a new call frame (like `CALL`, `CREATE`, `DELEGATECALL`, ...) called call-like opcodes in the following. It is assumed that the EVM (to be more specific: an EVM call frame) has a new internal buffer of variable size, called the return data buffer. This buffer is created empty for each new call frame. Upon executing any call-like opcode, the buffer is cleared (its size is set to zero). After executing a call-like opcode, the complete return data (or failure data, see EIP [206](https://github.com/ethereum/EIPs/pull/206)) of the call is stored in the return data buffer (of the caller), and its size changed accordingly. As an exception, `CREATE` and `CREATE2` are considered to return the empty buffer in the success case and the failure data in the failure case. If the call-like opcode is executed but does not really instantiate a call frame (for example due to insufficient funds for a value transfer or if the called contract does not exist), the return data buffer is empty. As an optimization, it is possible to share the return data buffer across call frames because only one will be non-empty at any time. From 2f1e498112ce6d8f92f02a91a9714f09495ebd76 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 17 Nov 2017 19:47:23 +0100 Subject: [PATCH 0281/1085] Move returndatacopy.md to eip-211.md --- EIPS/{returndatacopy.md => eip-211.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename EIPS/{returndatacopy.md => eip-211.md} (100%) diff --git a/EIPS/returndatacopy.md b/EIPS/eip-211.md similarity index 100% rename from EIPS/returndatacopy.md rename to EIPS/eip-211.md From 14dc97daad12e204259a31632e20de3c3f199008 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 17 Nov 2017 20:04:39 +0100 Subject: [PATCH 0282/1085] Fix another typo --- EIPS/eip-211.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-211.md b/EIPS/eip-211.md index 2a8a358d7e31c..0711f0bad0bc6 100644 --- a/EIPS/eip-211.md +++ b/EIPS/eip-211.md @@ -13,7 +13,7 @@ ## Simple Summary -A mechanism to allow returning arbitrary-length data inside the EVM has been requested for quite a while now. Existing proposals always had very intricate problems associated with charging gas. This proposal solves the same problem while at the same time, it has a very simple gas charging mechanism and reqires minimal changes to the call opcodes. Its workings are very similar to the way calldata is handled already: After a call, return data is kept inside a virtual buffer from which the caller can copy it (or parts thereof) into memory. At the next call, the buffer is overwritten. This mechanism is 100% backwards compatible. +A mechanism to allow returning arbitrary-length data inside the EVM has been requested for quite a while now. Existing proposals always had very intricate problems associated with charging gas. This proposal solves the same problem while at the same time, it has a very simple gas charging mechanism and requires minimal changes to the call opcodes. Its workings are very similar to the way calldata is handled already: After a call, return data is kept inside a virtual buffer from which the caller can copy it (or parts thereof) into memory. At the next call, the buffer is overwritten. This mechanism is 100% backwards compatible. ## Abstract From 61a3f8292f9b8258415c3a72a2774f6380a80991 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 17 Nov 2017 20:04:50 +0100 Subject: [PATCH 0283/1085] Mention the Byzantium block number --- EIPS/eip-211.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-211.md b/EIPS/eip-211.md index 0711f0bad0bc6..75b0e40f1cf5d 100644 --- a/EIPS/eip-211.md +++ b/EIPS/eip-211.md @@ -29,7 +29,7 @@ Note that this proposal also makes the EIP that proposes to allow to return data ## Specification -Add two new opcodes and amend the semantics of any opcode that creates a new call frame (like `CALL`, `CREATE`, `DELEGATECALL`, ...) called call-like opcodes in the following. It is assumed that the EVM (to be more specific: an EVM call frame) has a new internal buffer of variable size, called the return data buffer. This buffer is created empty for each new call frame. Upon executing any call-like opcode, the buffer is cleared (its size is set to zero). After executing a call-like opcode, the complete return data (or failure data, see EIP [206](https://github.com/ethereum/EIPs/pull/206)) of the call is stored in the return data buffer (of the caller), and its size changed accordingly. As an exception, `CREATE` and `CREATE2` are considered to return the empty buffer in the success case and the failure data in the failure case. If the call-like opcode is executed but does not really instantiate a call frame (for example due to insufficient funds for a value transfer or if the called contract does not exist), the return data buffer is empty. +If `block.number >= BYZANTIUM_FORK_BLKNUM`, add two new opcodes and amend the semantics of any opcode that creates a new call frame (like `CALL`, `CREATE`, `DELEGATECALL`, ...) called call-like opcodes in the following. It is assumed that the EVM (to be more specific: an EVM call frame) has a new internal buffer of variable size, called the return data buffer. This buffer is created empty for each new call frame. Upon executing any call-like opcode, the buffer is cleared (its size is set to zero). After executing a call-like opcode, the complete return data (or failure data, see EIP [206](https://github.com/ethereum/EIPs/pull/206)) of the call is stored in the return data buffer (of the caller), and its size changed accordingly. As an exception, `CREATE` and `CREATE2` are considered to return the empty buffer in the success case and the failure data in the failure case. If the call-like opcode is executed but does not really instantiate a call frame (for example due to insufficient funds for a value transfer or if the called contract does not exist), the return data buffer is empty. As an optimization, it is possible to share the return data buffer across call frames because only one will be non-empty at any time. From 0ea86f8583d2a195b7861609e321d5a0da8c35c7 Mon Sep 17 00:00:00 2001 From: 5chdn <5chdn@users.noreply.github.com> Date: Sat, 18 Nov 2017 11:26:09 +0100 Subject: [PATCH 0284/1085] Clean up formatting of README.md --- README.md | 74 +++++++++++++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index a58cb15aafbe6..9a8119fbdd967 100644 --- a/README.md +++ b/README.md @@ -11,42 +11,42 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP * **Deferred** - an EIP that is not being considered for immediate adoption. May be reconsidered in the future for a subsequent hard fork. # Deferred EIPs (adoption postponed until the Constantinople Metropolis hard fork) -| Number |Title | Author | Layer | Status | -| ------------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------- | ------------| ----------| -| [86](https://github.com/ethereum/EIPs/pull/208) | Abstraction of transaction origin and signature | Vitalik Buterin | Core | Deferred | -| [96](https://github.com/ethereum/EIPs/pull/210) | Blockhash refactoring | Vitalik Buterin | Core | Deferred | -| [145](EIPS/eip-145.md) | Bitwise shifting instructions in EVM | Alex Beregszaszi, Paweł Bylica | Core | Deferred | +| Number | Title | Author | Layer | Status | +| -------------------------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------ | ---------- | -------- | +| [86](https://github.com/ethereum/EIPs/pull/208) | Abstraction of transaction origin and signature | Vitalik Buterin | Core | Deferred | +| [96](https://github.com/ethereum/EIPs/pull/210) | Blockhash refactoring | Vitalik Buterin | Core | Deferred | +| [145](EIPS/eip-145.md) | Bitwise shifting instructions in EVM | Alex Beregszaszi, Paweł Bylica | Core | Deferred | # Finalized EIPs (standards that have been adopted) -| Number |Title | Author | Layer | Status | -| ------------------------------------------------------- | ----------------------------------------------------------- | ----------------| ------------| --------| -| [2](EIPS/eip-2.md) | Homestead Hard-fork Changes | Vitalik Buterin | Core | Final | -| [6](EIPS/eip-6.md) | Renaming Suicide Opcode | Hudson Jameson | Interface | Final | -| [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Core | Final | -| [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Networking | Final | -| [20](EIPS/eip-20-token-standard.md) | ERC-20 Token Standard | Fabian Vogelsteller, Vitalik Buterin | ERC | Final | -| [55](EIPS/eip-55.md) | ERC-55 Mixed-case checksum address encoding | Vitalik Buterin | Core | Final | -| [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Core | Final | -| [137](EIPS/eip-137.md) | Ethereum Domain Name Service - Specification | Nick Johnson | ERC | Final | -| [140](https://github.com/ethereum/EIPs/pull/206) | REVERT instruction in the Ethereum Virtual Machine | Beregszaszi, Mushegian| Core | Final | -| [141](EIPS/eip-141.md) | Designated invalid EVM instruction | Alex Beregszaszi| Core | Final | -| [150](EIPS/eip-150.md) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Core | Final | -| [155](EIPS/eip-155.md) | Simple replay attack protection | Vitalik Buterin | Core | Final | -| [160](EIPS/eip-160.md) | EXP cost increase | Vitalik Buterin | Core | Final | -| [161](EIPS/eip-161.md) | State trie clearing (invariant-preserving alternative) | Gavin Wood | Core | Final | -| [162](EIPS/eip-162.md) | ERC-162 ENS support for reverse resolution of Ethereum addresses | Maurelian, Nick Johnson | ERC | Final | -| [170](EIPS/eip-170.md) | Contract code size limit | Vitalik Buterin | Core | Final | -| [181](EIPS/eip-181.md) | ERC-181 ENS support for reverse resolution of Ethereum addresses | Nick Johnson | ERC | Final | -| [190](EIPS/eip-190.md) | ERC-190 Ethereum Smart Contract Packaging Standard | Piper Merriam, Tim Coulter, Denis Erfurt (mhhf), RJ Catalano (VoR0220), Iuri Matias (iurimatias) | ERC | Final | -| [196](https://github.com/ethereum/EIPs/pull/213) | Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 | Reitwiessner | Core | Final | -| [197](https://github.com/ethereum/EIPs/pull/212) | Precompiled contracts for optimal Ate pairing check on the elliptic curve alt_bn128 | Buterin, Reitwiessner | Core | Final | -| [198](https://github.com/ethereum/EIPs/pull/198) | Precompiled contract for bigint modular exponentiation | Vitalik Buterin | Core | Final | -| [211](https://github.com/ethereum/EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner| Core | Final | -| [214](https://github.com/ethereum/EIPs/pull/214) | New opcode STATICCALL | Buterin, Reitwiessner | Core | Final | -| [606](EIPS/eip-606.md) | Hardfork Meta: Homestead | Alex Beregszaszi | Meta | Final | -| [607](EIPS/eip-607.md) | Hardfork Meta: Spurious Dragon | Alex Beregszaszi | Meta | Final | -| [608](EIPS/eip-608.md) | Hardfork Meta: Tangerine Whistle | Alex Beregszaszi | Meta | Final | -| [609](EIPS/eip-609.md) | Hardfork Meta: Byzantium | Alex Beregszaszi | Meta | Final | -| [649](https://github.com/ethereum/EIPs/pull/669) | Metropolis Difficulty Bomb Delay and Block Reward Reduction | Schoedon, Buterin | Core | Final | -| [658](https://github.com/ethereum/EIPs/pull/658) | Embedding transaction return data in receipts | Nick Johnson | Core | Final | -| [706](EIPS/eip-706.md) | DEVp2p snappy compression | Péter Szilágyi | Networking | Final | +| Number | Title | Author | Layer | Status | +| -------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------| ---------- | -------- | +| [2](EIPS/eip-2.md) | Homestead Hard-fork Changes | Vitalik Buterin | Core | Final | +| [6](EIPS/eip-6.md) | Renaming Suicide Opcode | Hudson Jameson | Interface | Final | +| [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Core | Final | +| [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Networking | Final | +| [20](EIPS/eip-20-token-standard.md) | ERC-20 Token Standard | Fabian Vogelsteller, Vitalik Buterin | ERC | Final | +| [55](EIPS/eip-55.md) | ERC-55 Mixed-case checksum address encoding | Vitalik Buterin | Core | Final | +| [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Core | Final | +| [137](EIPS/eip-137.md) | Ethereum Domain Name Service - Specification | Nick Johnson | ERC | Final | +| [140](https://github.com/ethereum/EIPs/pull/206) | REVERT instruction in the Ethereum Virtual Machine | Alex Beregszaszi, Nikolai Mushegian | Core | Final | +| [141](EIPS/eip-141.md) | Designated invalid EVM instruction | Alex Beregszaszi | Core | Final | +| [150](EIPS/eip-150.md) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Core | Final | +| [155](EIPS/eip-155.md) | Simple replay attack protection | Vitalik Buterin | Core | Final | +| [160](EIPS/eip-160.md) | EXP cost increase | Vitalik Buterin | Core | Final | +| [161](EIPS/eip-161.md) | State trie clearing (invariant-preserving alternative) | Gavin Wood | Core | Final | +| [162](EIPS/eip-162.md) | ERC-162 ENS support for reverse resolution of Ethereum addresses | Maurelian, Nick Johnson | ERC | Final | +| [170](EIPS/eip-170.md) | Contract code size limit | Vitalik Buterin | Core | Final | +| [181](EIPS/eip-181.md) | ERC-181 ENS support for reverse resolution of Ethereum addresses | Nick Johnson | ERC | Final | +| [190](EIPS/eip-190.md) | ERC-190 Ethereum Smart Contract Packaging Standard | Merriam, Coulter, Erfurt, Catalano, Matias | ERC | Final | +| [196](https://github.com/ethereum/EIPs/pull/213) | Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 | Christian Reitwiessner | Core | Final | +| [197](https://github.com/ethereum/EIPs/pull/212) | Precompiled contracts for optimal Ate pairing check on the elliptic curve alt_bn128 | Vitalik Buterin, Christian Reitwiessner | Core | Final | +| [198](https://github.com/ethereum/EIPs/pull/198) | Precompiled contract for bigint modular exponentiation | Vitalik Buterin | Core | Final | +| [211](https://github.com/ethereum/EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner | Core | Final | +| [214](https://github.com/ethereum/EIPs/pull/214) | New opcode STATICCALL | Vitalik Buterin, Christian Reitwiessner | Core | Final | +| [606](EIPS/eip-606.md) | Hardfork Meta: Homestead | Alex Beregszaszi | Meta | Final | +| [607](EIPS/eip-607.md) | Hardfork Meta: Spurious Dragon | Alex Beregszaszi | Meta | Final | +| [608](EIPS/eip-608.md) | Hardfork Meta: Tangerine Whistle | Alex Beregszaszi | Meta | Final | +| [609](EIPS/eip-609.md) | Hardfork Meta: Byzantium | Alex Beregszaszi | Meta | Final | +| [649](https://github.com/ethereum/EIPs/pull/669) | Metropolis Difficulty Bomb Delay and Block Reward Reduction | Afri Schoedon, Vitalik Buterin | Core | Final | +| [658](https://github.com/ethereum/EIPs/pull/658) | Embedding transaction return data in receipts | Nick Johnson | Core | Final | +| [706](EIPS/eip-706.md) | DEVp2p snappy compression | Péter Szilágyi | Networking | Final | From 5843a29215e796e42752c1cb9f5159eddf999436 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Sat, 18 Nov 2017 19:02:03 -0600 Subject: [PATCH 0285/1085] add activation block numbers to Byzantium meta-EIP --- EIPS/eip-609.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-609.md b/EIPS/eip-609.md index 714a5bdeacbf4..4ac787814216f 100644 --- a/EIPS/eip-609.md +++ b/EIPS/eip-609.md @@ -18,7 +18,8 @@ This specifies the changes included in the hard fork named Byzantium. - Codename: Byzantium - Aliases: Metropolis/Byzantium, Metropolis part 1 - Activation: - - Block not specified yet + - Block >= 4,370,000 on Mainnet + - Block >= 1,700,000 on Ropsten testnet - Included EIPs: - EIP 100 (Change difficulty adjustment to target mean block time including uncles) - EIP 140 (REVERT instruction in the Ethereum Virtual Machine) @@ -29,6 +30,10 @@ This specifies the changes included in the hard fork named Byzantium. - EIP 214 (New opcode STATICCALL) - EIP 649 (Difficulty Bomb Delay and Block Reward Reduction) - EIP 658 (Embedding transaction return data in receipts) + +## References + +1. https://blog.ethereum.org/2017/10/12/byzantium-hf-announcement/ ## Copyright From 23fb01ac0d233a384ad9b3c67be87023e4052206 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Tue, 18 Jul 2017 18:37:16 -0400 Subject: [PATCH 0286/1085] add table of HF meta-EIPs --- README.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9a8119fbdd967..e801fb248f1e0 100644 --- a/README.md +++ b/README.md @@ -43,10 +43,15 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [198](https://github.com/ethereum/EIPs/pull/198) | Precompiled contract for bigint modular exponentiation | Vitalik Buterin | Core | Final | | [211](https://github.com/ethereum/EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner | Core | Final | | [214](https://github.com/ethereum/EIPs/pull/214) | New opcode STATICCALL | Vitalik Buterin, Christian Reitwiessner | Core | Final | -| [606](EIPS/eip-606.md) | Hardfork Meta: Homestead | Alex Beregszaszi | Meta | Final | -| [607](EIPS/eip-607.md) | Hardfork Meta: Spurious Dragon | Alex Beregszaszi | Meta | Final | -| [608](EIPS/eip-608.md) | Hardfork Meta: Tangerine Whistle | Alex Beregszaszi | Meta | Final | -| [609](EIPS/eip-609.md) | Hardfork Meta: Byzantium | Alex Beregszaszi | Meta | Final | | [649](https://github.com/ethereum/EIPs/pull/669) | Metropolis Difficulty Bomb Delay and Block Reward Reduction | Afri Schoedon, Vitalik Buterin | Core | Final | | [658](https://github.com/ethereum/EIPs/pull/658) | Embedding transaction return data in receipts | Nick Johnson | Core | Final | | [706](EIPS/eip-706.md) | DEVp2p snappy compression | Péter Szilágyi | Networking | Final | + +# Past Hard Forks +| Codename | Aliases | Block number | Date (UTC) | +|-------------------------------------- |---------------------------- |----------------|------------| +| [Homestead](EIPS/eip-606.md) | | 1,150,000 | 2016-03-14 | +| DAO Fork | | 1,920,000 | 2016-07-20 | +| [Tangerine Whistle](EIPS/eip-608.md) | Anti-DoS, EIP 150 | 2,463,000 | 2016-10-18 | +| [Spurious Dragon](EIPS/eip-607.md) | State-clearing, EIP 158/161 | 2,675,000 | 2016-11-22 | +| [Byzantium](EIPS/eip-609.md) | Metropolis: Part 1 | 4,730,000 | 2017-10-16 | From 00230328ec847663df0a62b563210cdd562c5440 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 20 Nov 2017 12:08:59 +0100 Subject: [PATCH 0287/1085] Replace a METROPOLIS with BYZANTIUM --- EIPS/eip-100.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-100.md b/EIPS/eip-100.md index 2d631de37100e..6bb6dcfc8273c 100644 --- a/EIPS/eip-100.md +++ b/EIPS/eip-100.md @@ -18,7 +18,7 @@ child_diff = int(max(parent.difficulty + (parent.difficulty // BLOCK_DIFF_FACTOR ... ``` -If `block.number >= METROPOLIS_FORK_BLKNUM`, we change the first line to the following: +If `block.number >= BYZANTIUM_FORK_BLKNUM`, we change the first line to the following: ``` python adj_factor = max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99) From c22ad19a7dc1f4a793363c414facc8a3f81fb43c Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 20 Nov 2017 12:13:52 +0100 Subject: [PATCH 0288/1085] Change how to refer to EIP-140 Following https://github.com/ethereum/EIPs/pull/211#discussion_r151791340 --- EIPS/eip-140.md | 1 + EIPS/eip-211.md | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 EIPS/eip-140.md diff --git a/EIPS/eip-140.md b/EIPS/eip-140.md new file mode 100644 index 0000000000000..c766244c556b3 --- /dev/null +++ b/EIPS/eip-140.md @@ -0,0 +1 @@ +Reserved for https://github.com/ethereum/EIPs/pull/206 diff --git a/EIPS/eip-211.md b/EIPS/eip-211.md index 75b0e40f1cf5d..2bfb9228b7460 100644 --- a/EIPS/eip-211.md +++ b/EIPS/eip-211.md @@ -25,11 +25,11 @@ In some situations, it is vital for a function to be able to return data whose l Compiler implementors are advised to reserve a zero-length area for return data if the size of the return data is unknown before the call and then use `RETURNDATACOPY` in conjunction with `RETURNDATASIZE` to actually retrieve the data. -Note that this proposal also makes the EIP that proposes to allow to return data in case of an intentional state reversion (EIP [206](https://github.com/ethereum/EIPs/pull/206)) much more useful. Since the size of the failure data might be larger than the regular return data (or even unknown), it is possible to retrieve the failure data after the CALL opcode has signalled a failure, even if the regular output area is not large enough to hold the data. +Note that this proposal also makes the EIP that proposes to allow to return data in case of an intentional state reversion ([EIP-140](./eip-140.md)) much more useful. Since the size of the failure data might be larger than the regular return data (or even unknown), it is possible to retrieve the failure data after the CALL opcode has signalled a failure, even if the regular output area is not large enough to hold the data. ## Specification -If `block.number >= BYZANTIUM_FORK_BLKNUM`, add two new opcodes and amend the semantics of any opcode that creates a new call frame (like `CALL`, `CREATE`, `DELEGATECALL`, ...) called call-like opcodes in the following. It is assumed that the EVM (to be more specific: an EVM call frame) has a new internal buffer of variable size, called the return data buffer. This buffer is created empty for each new call frame. Upon executing any call-like opcode, the buffer is cleared (its size is set to zero). After executing a call-like opcode, the complete return data (or failure data, see EIP [206](https://github.com/ethereum/EIPs/pull/206)) of the call is stored in the return data buffer (of the caller), and its size changed accordingly. As an exception, `CREATE` and `CREATE2` are considered to return the empty buffer in the success case and the failure data in the failure case. If the call-like opcode is executed but does not really instantiate a call frame (for example due to insufficient funds for a value transfer or if the called contract does not exist), the return data buffer is empty. +If `block.number >= BYZANTIUM_FORK_BLKNUM`, add two new opcodes and amend the semantics of any opcode that creates a new call frame (like `CALL`, `CREATE`, `DELEGATECALL`, ...) called call-like opcodes in the following. It is assumed that the EVM (to be more specific: an EVM call frame) has a new internal buffer of variable size, called the return data buffer. This buffer is created empty for each new call frame. Upon executing any call-like opcode, the buffer is cleared (its size is set to zero). After executing a call-like opcode, the complete return data (or failure data, see [EIP-140](./eip-140.md)) of the call is stored in the return data buffer (of the caller), and its size changed accordingly. As an exception, `CREATE` and `CREATE2` are considered to return the empty buffer in the success case and the failure data in the failure case. If the call-like opcode is executed but does not really instantiate a call frame (for example due to insufficient funds for a value transfer or if the called contract does not exist), the return data buffer is empty. As an optimization, it is possible to share the return data buffer across call frames because only one will be non-empty at any time. From 12257d516de8e9d020cee2a021ddd9ad1693d495 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 20 Nov 2017 12:33:33 +0100 Subject: [PATCH 0289/1085] Move static_call.md to eip-214.md --- EIPS/{static_call.md => eip-214.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename EIPS/{static_call.md => eip-214.md} (100%) diff --git a/EIPS/static_call.md b/EIPS/eip-214.md similarity index 100% rename from EIPS/static_call.md rename to EIPS/eip-214.md From 47e30db9f3d9c446552c3bb1d80ce1b3648d25d7 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Mon, 20 Nov 2017 13:06:48 +0000 Subject: [PATCH 0290/1085] Update eip-draft-returndata.md --- EIPS/eip-draft-returndata.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/EIPS/eip-draft-returndata.md b/EIPS/eip-draft-returndata.md index 6473da853e844..09afc15ec28dc 100644 --- a/EIPS/eip-draft-returndata.md +++ b/EIPS/eip-draft-returndata.md @@ -1,11 +1,11 @@ ## Preamble - EIP: - Title: Embedding transaction return data in receipts + EIP: 658 + Title: Embedding transaction status code in receipts Author: Nick Johnson Type: Standard Track Category Core - Status: Draft + Status: Final Created: 2017-06-30 Requires: 140 Replaces: 98 @@ -22,7 +22,7 @@ Full nodes can provide RPCs to get a transaction return status and value by repl Instead, we propose to replace the intermediate state root, already obsoleted by EIP98, with the return status (1 for success, 0 for failure). This both allows callers to determine success status, and remedies the previous omission of return data from the receipt. ## Specification -For blocks where block.number >= METROPOLIS_FORK_BLKNUM, the intermediate state root is replaced by a status code, 0 indicating failure (due to any operation that can cause the transaction or top-level call to revert) and 1 indicating success. +For blocks where block.number >= BYZANTIUM_FORK_BLKNUM, the intermediate state root is replaced by a status code, 0 indicating failure (due to any operation that can cause the transaction or top-level call to revert) and 1 indicating success. ## Rationale This constitutes a minimal possible change that permits fetching the success/failure state of transactions, preserving existing capabilities with minimum disruption or additional work for Metropolis. From d1ae915d079293480bd6abb0187976c230d57903 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Mon, 20 Nov 2017 13:19:19 +0000 Subject: [PATCH 0291/1085] Rename eip-draft-returndata.md to eip-658.md --- EIPS/{eip-draft-returndata.md => eip-658.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename EIPS/{eip-draft-returndata.md => eip-658.md} (100%) diff --git a/EIPS/eip-draft-returndata.md b/EIPS/eip-658.md similarity index 100% rename from EIPS/eip-draft-returndata.md rename to EIPS/eip-658.md From d534a1bdb4afd052de68a21d0af58eb611cc041b Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 20 Nov 2017 15:12:34 +0100 Subject: [PATCH 0292/1085] A colon cannot separate sentences --- EIPS/eip-211.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-211.md b/EIPS/eip-211.md index 2bfb9228b7460..caf6bb4c27e77 100644 --- a/EIPS/eip-211.md +++ b/EIPS/eip-211.md @@ -13,7 +13,7 @@ ## Simple Summary -A mechanism to allow returning arbitrary-length data inside the EVM has been requested for quite a while now. Existing proposals always had very intricate problems associated with charging gas. This proposal solves the same problem while at the same time, it has a very simple gas charging mechanism and requires minimal changes to the call opcodes. Its workings are very similar to the way calldata is handled already: After a call, return data is kept inside a virtual buffer from which the caller can copy it (or parts thereof) into memory. At the next call, the buffer is overwritten. This mechanism is 100% backwards compatible. +A mechanism to allow returning arbitrary-length data inside the EVM has been requested for quite a while now. Existing proposals always had very intricate problems associated with charging gas. This proposal solves the same problem while at the same time, it has a very simple gas charging mechanism and requires minimal changes to the call opcodes. Its workings are very similar to the way calldata is handled already; after a call, return data is kept inside a virtual buffer from which the caller can copy it (or parts thereof) into memory. At the next call, the buffer is overwritten. This mechanism is 100% backwards compatible. ## Abstract @@ -21,7 +21,7 @@ Please see summary. ## Motivation -In some situations, it is vital for a function to be able to return data whose length cannot be anticipated before the call. In principle, this can be solved without alterations to the EVM, for example by splitting the call into two calls where the first is used to compute only the size. All of these mechanisms, though, are very expensive in at least some situations. A very useful example of such a worst-case situation is a generic forwarding contract: A contract that takes call data, potentially makes some checks and then forwards it as is to another contract. The return data should of course be transferred in a similar way to the original caller. Since the contract is generic and does not know about the contract it calls, there is no way to determine the size of the output without adapting the called contract accordingly or trying a logarithmic number of calls. +In some situations, it is vital for a function to be able to return data whose length cannot be anticipated before the call. In principle, this can be solved without alterations to the EVM, for example by splitting the call into two calls where the first is used to compute only the size. All of these mechanisms, though, are very expensive in at least some situations. A very useful example of such a worst-case situation is a generic forwarding contract; a contract that takes call data, potentially makes some checks and then forwards it as is to another contract. The return data should of course be transferred in a similar way to the original caller. Since the contract is generic and does not know about the contract it calls, there is no way to determine the size of the output without adapting the called contract accordingly or trying a logarithmic number of calls. Compiler implementors are advised to reserve a zero-length area for return data if the size of the return data is unknown before the call and then use `RETURNDATACOPY` in conjunction with `RETURNDATASIZE` to actually retrieve the data. @@ -50,7 +50,7 @@ Other solutions that would allow returning dynamic data were considered, but the Note that the EVM implementation needs to keep the return data until the next call or the return from the current call. Since this resource was already paid for as part of the memory of the callee, it should not be a problem. Implementations may either choose to keep the full memory of the callee alive until the next call or copy only the return data to a special memory area. -Keeping the memory of the callee until the next call-like opcode does not increase the peak memory usage in the following sense: Any memory allocation in the caller's frame that happens after the return from the call can be moved before the call without a change in gas costs, but will add this allocation to the peak allocation. +Keeping the memory of the callee until the next call-like opcode does not increase the peak memory usage in the following sense; any memory allocation in the caller's frame that happens after the return from the call can be moved before the call without a change in gas costs, but will add this allocation to the peak allocation. The number values of the opcodes were allocated in the same nibble block that also contains `CALLDATASIZE` and `CALLDATACOPY`. From 0fe1eb7c46663a74561f0920c352f7e15b4fd75f Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 20 Nov 2017 15:13:05 +0100 Subject: [PATCH 0293/1085] Status is now Final --- EIPS/eip-211.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-211.md b/EIPS/eip-211.md index caf6bb4c27e77..22d89bb5ad99f 100644 --- a/EIPS/eip-211.md +++ b/EIPS/eip-211.md @@ -5,7 +5,7 @@ Author: Christian Reitwiessner Type: Standard Track Category Core - Status: Draft + Status: Final Created: 2017-02-13 Requires: Replaces: 5/8 From 329591a77eb000ecdf603312781a62ebdbdc2dde Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 23 Nov 2017 11:56:54 +0100 Subject: [PATCH 0294/1085] eip-778: Ethereum Node Records --- EIPS/eip-778.md | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 EIPS/eip-778.md diff --git a/EIPS/eip-778.md b/EIPS/eip-778.md new file mode 100644 index 0000000000000..4e7c957754e47 --- /dev/null +++ b/EIPS/eip-778.md @@ -0,0 +1,104 @@ +# Preamble + + EIP: 778 + Title: Ethereum Node Records (ENR) + Author: Felix Lange + Type: Standard Track + Category Networking + Status: Draft + Created: 2017-05-17 + +# Abstract + +This EIP defines Ethereum Node Records, an open format for p2p connectivity information. + +# Motivation + +Ethereum nodes discover each other through the node discovery protocol. The purpose of +that protocol is relaying node identity public keys (on the secp256k1 curve), their IP +address and two port numbers. No other information can be relayed. + +This specification seeks to lift the restrictions of the discovery v4 protocol by defining +a flexible format, the *node record*, for connectivity-related information. Node records +can be relayed through a future version of the node discovery protocol. They can also be +relayed through arbitrary other mechanisms such as DNS, ENS, a devp2p subprotocol, etc. + +Node records improve cryptographic agility and handling of protocol upgrades. A record can +contain information about arbitrary transport protocols and public key material associated +with them. + +Another goal of the new format is to provide authoritative updates of connectivity +information. If a node changes its endpoint and publishes a new record, other nodes should +be able to determine which record is newer. + +# Specification + +The components of a node record are: + +- `signature`: cryptographic signature of record contents +- `seq`: A sequence number. Nodes should increase the number whenever the record changes + and republish the record. +- The remainder of the record consists of arbitrary key/value pairs, which must be sorted + by key. + +A record's signature is made and validated according to an *identy scheme*. The identity +scheme is also responsible for deriving a node's address in the DHT. + +### RLP Encoding + +The canonical encoding of a node record is an RLP list of `[signature, seq, k, v, ...]`. +The maximum encoded size of a node record is 300 bytes. Implementations should reject +records larger than this size. + +Records are signed and encoded as follows: + + content = rlp(seq) || rlp(k) || rlp(v) || ... + signature = rlp(sign(rlp_list(content))) + record = rlp_list(signature || content) + +### Key/Value Pairs + +Key/Value keys can be any byte sequence, but should be text. The following keys are +pre-defined: + +| Key | Value | +|:-------------|:-------------------------------------------------| +| `id` | name of identity scheme, e.g. "secp256k1-keccak" | +| `secp256k1` | compressed secp256k1 public key | +| `ip4` | IPv4 address, 4 bytes | +| `ip6` | IPv6 address, 16 bytes | +| `discv5` | UDP port for discovery v5 | + +### secp256k1-keccak Identity Scheme + +This specification defines a single scheme to be used as the default: "secp256k1-keccak". + +- To sign record `content` with this scheme, apply the keccak256[^1] hash function to + `content`, then create a signature of the hash. The resulting 64-byte signature is + encoded as the concatenation of `r` and `s`. +- To verify a record, check that the signature was made by the public key in the + "secp256k1" key/value pair. +- To derive a node address, take the keccak256 hash of the public key. + +[^1]: As used by the EVM + +# Rationale + +The format is meant to suit future needs in two ways: + +- Adding new key/value pairs: This is always possible and doesn't require implementation + consensus. Existing clients will accept any key/value pairs regardless of whether they + can interpret their content. +- Adding identity schemes: these need implementation consensus because the network won't + accept the signature otherwise. To introduce a new identity scheme, propose an EIP and + get it implemented. The scheme can be used as soon as most clients accept it. + +The size of a record is limited because records are relayed frequently and may be included +in size-constrained protocols such as DNS. A record containing IPv4 address, when signed +using the "secp256k1-keccak" scheme occupies roughly 120 bytes, leaving plenty of room for +additional metadata. + +# Copyright + +Copyright and related rights waived via CC0. + From 7aef5b609f934a50754b1671b9d48be63c4cca41 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 23 Nov 2017 13:19:26 +0100 Subject: [PATCH 0295/1085] eip-778: clarify k/v key encoding --- EIPS/eip-778.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-778.md b/EIPS/eip-778.md index 4e7c957754e47..5398dafbc68c4 100644 --- a/EIPS/eip-778.md +++ b/EIPS/eip-778.md @@ -58,8 +58,8 @@ Records are signed and encoded as follows: ### Key/Value Pairs -Key/Value keys can be any byte sequence, but should be text. The following keys are -pre-defined: +The keys in key/value pairs can technically be any byte sequence, but ASCII text is +preferred. The following keys are pre-defined: | Key | Value | |:-------------|:-------------------------------------------------| From 095488a2f663290b53156c4f881e6681843e32c3 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 23 Nov 2017 13:20:21 +0100 Subject: [PATCH 0296/1085] eip-778: fix date --- EIPS/eip-778.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-778.md b/EIPS/eip-778.md index 5398dafbc68c4..e4274a6d9f22f 100644 --- a/EIPS/eip-778.md +++ b/EIPS/eip-778.md @@ -6,7 +6,7 @@ Type: Standard Track Category Networking Status: Draft - Created: 2017-05-17 + Created: 2017-11-23 # Abstract From b550ed71b899f3e85921b90da2c2d6ab50080817 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 27 Nov 2017 17:58:21 +0100 Subject: [PATCH 0297/1085] Tiny fixes --- EIPS/eip-214.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-214.md b/EIPS/eip-214.md index 41163a22aba7e..1427b8514f9d1 100644 --- a/EIPS/eip-214.md +++ b/EIPS/eip-214.md @@ -5,7 +5,7 @@ Author: Vitalik Buterin , Christian Reitwiessner ; Type: Standard Track Category: Core - Status: Draft + Status: Accepted Created: 2017-02-13 ## Simple Summary @@ -18,9 +18,9 @@ This proposal adds a new opcode that can be used to call another contract (or it ## Motivation -Currently, there is no restriction about what a called contract can do, as long as the computation can be performed with the amount of gas provided. This poses certain difficulties about smart contract engineers: After a regular call, unless you know the called contract, you cannot make any assumptions about the state of the contracts. Furthermore, because you cannot know the order of transactions before they are confirmed by miners, not even an outside observer can be sure about that in all cases. +Currently, there is no restriction about what a called contract can do, as long as the computation can be performed with the amount of gas provided. This poses certain difficulties about smart contract engineers; after a regular call, unless you know the called contract, you cannot make any assumptions about the state of the contracts. Furthermore, because you cannot know the order of transactions before they are confirmed by miners, not even an outside observer can be sure about that in all cases. -This EIP adds a way to call other contracts and restrict what they can do in the simplest way. It can be safely assumed that the state of all contracts is the same before and after a static call. +This EIP adds a way to call other contracts and restrict what they can do in the simplest way. It can be safely assumed that the state of all accounts is the same before and after a static call. ## Specification From d8f5c84717a491563925fa223a4b77144bcbf379 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 27 Nov 2017 18:03:03 +0100 Subject: [PATCH 0298/1085] The status is already Final --- EIPS/eip-214.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-214.md b/EIPS/eip-214.md index 1427b8514f9d1..1bc58474603e9 100644 --- a/EIPS/eip-214.md +++ b/EIPS/eip-214.md @@ -5,7 +5,7 @@ Author: Vitalik Buterin , Christian Reitwiessner ; Type: Standard Track Category: Core - Status: Accepted + Status: Final Created: 2017-02-13 ## Simple Summary From 3355c0903cb8af2621242c821340197e7a5efe80 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Thu, 30 Nov 2017 17:16:14 +0100 Subject: [PATCH 0299/1085] Limit the backward compatibility https://github.com/ethereum/EIPs/pull/206#discussion_r151943639 --- EIPS/eip-140.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-140.md b/EIPS/eip-140.md index 94e89bd8a1b31..40f31f6122449 100644 --- a/EIPS/eip-140.md +++ b/EIPS/eip-140.md @@ -40,7 +40,7 @@ The content of the optionally provided memory section is not defined by this EIP ## Backwards Compatibility -This change has no effect on contracts created in the past. +This change has no effect on contracts created in the past unless they contain `0xfd` as an instruction. ## Test Cases From 1d93a80c64b5b78e61786a65eada50dc4d08d9b9 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Thu, 30 Nov 2017 17:18:39 +0100 Subject: [PATCH 0300/1085] Change the status to Final --- EIPS/eip-140.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-140.md b/EIPS/eip-140.md index 40f31f6122449..b7262a0140ff2 100644 --- a/EIPS/eip-140.md +++ b/EIPS/eip-140.md @@ -5,7 +5,7 @@ Author: Alex Beregszaszi, Nikolai Mushegian (nikolai@nexusdev.us) Type: Standard Track Category: Core - Status: Accepted + Status: Final Created: 2017-02-06 ## Simple Summary From 8e92d5b2e10fc5a17c901b684332b89514f09f0a Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Thu, 30 Nov 2017 17:22:02 +0100 Subject: [PATCH 0301/1085] Improvements after a week of silence on https://github.com/ethereum/EIPs/pull/206 --- EIPS/eip-140.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-140.md b/EIPS/eip-140.md index b7262a0140ff2..e449caf0d1c7c 100644 --- a/EIPS/eip-140.md +++ b/EIPS/eip-140.md @@ -18,11 +18,11 @@ The `REVERT` instruction will stop execution, roll back all state changes done s ## Motivation -Currently this is not possible. There are two practical ways to revert a transaction from within a contract: running out of gas or executing an invalid instruction. Both of these options will consume all remaining gas. Additionally, reverting a transaction means that all changes, including LOGs, are lost and there is no way to convey a reason for aborting a transaction. +Currently this is not possible. There are two practical ways to revert a transaction from within a contract: running out of gas or executing an invalid instruction. Both of these options will consume all remaining gas. Additionally, reverting an EVM execution means that all changes, including LOGs, are lost and there is no way to convey a reason for aborting an EVM execution. ## Specification -The `REVERT` instruction is introduced at `0xfd`. It expects two stack items, the top item is the `memory_offset` followed by `memory_length`. It does not return anything because it stops execution. +The `REVERT` instruction is introduced at `0xfd`. It expects two stack items, the top item is the `memory_offset` followed by `memory_length`. It does not produce any stack elements because it stops execution. The semantics of `REVERT` with respect to memory and memory cost are identical to those of `RETURN`. The sequence of bytes given by `memory_offset` and `memory_length` is called "error message" in the following. @@ -49,7 +49,7 @@ This change has no effect on contracts created in the past unless they contain ` ``` should: -- return `726576657274206d657373616765` as `REVERT` data, +- return `0x726576657274206d657373616765` as `REVERT` data, - the storage at key `0x0` should be left as unset and - use 20024 gas in total. From f05cbebb1a43477bd3c6827ea4703295f25b6fc6 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 1 Dec 2017 13:03:29 +0100 Subject: [PATCH 0302/1085] Put eip-1.md under public domain --- EIPS/eip-1.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index d70d10923ed73..eb3315e1b1794 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -254,3 +254,8 @@ February 1, 2016: EIP 1 has added editors, made draft improvements to process, a [README.md]: README.md "wikilink" [Bitcoin's BIP-0001]: https://github.com/bitcoin/bips [Python's PEP-0001]: https://www.python.org/dev/peps/ + +Copyright +--------- + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 9930119df1e33731e1cbaea02328c66251efc654 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 1 Dec 2017 13:15:58 +0100 Subject: [PATCH 0303/1085] Fix a title of a Byzantium EIP --- EIPS/eip-609.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-609.md b/EIPS/eip-609.md index 4ac787814216f..45c7728e8b246 100644 --- a/EIPS/eip-609.md +++ b/EIPS/eip-609.md @@ -21,15 +21,15 @@ This specifies the changes included in the hard fork named Byzantium. - Block >= 4,370,000 on Mainnet - Block >= 1,700,000 on Ropsten testnet - Included EIPs: - - EIP 100 (Change difficulty adjustment to target mean block time including uncles) + - [EIP 100](./eip-100.md) (Change difficulty adjustment to target mean block time including uncles) - EIP 140 (REVERT instruction in the Ethereum Virtual Machine) - EIP 196 (Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128) - EIP 197 (Precompiled contracts for optimal ate pairing check on the elliptic curve alt_bn128) - EIP 198 (Precompiled contract for bigint modular exponentiation) - EIP 211 (New opcodes: RETURNDATASIZE and RETURNDATACOPY) - EIP 214 (New opcode STATICCALL) - - EIP 649 (Difficulty Bomb Delay and Block Reward Reduction) - - EIP 658 (Embedding transaction return data in receipts) + - [EIP 649](./eip-649.md) (Difficulty Bomb Delay and Block Reward Reduction) + - [EIP 658](./eip-658.md) (Embedding transaction status code in receipts) ## References From 8f686cc31176f368000d8c16a6ba2c4bf120f550 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 1 Dec 2017 13:27:09 +0100 Subject: [PATCH 0304/1085] Fix the link format --- EIPS/eip-212.md | 1 + EIPS/eip-213.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 EIPS/eip-212.md diff --git a/EIPS/eip-212.md b/EIPS/eip-212.md new file mode 100644 index 0000000000000..02462ab6c63e8 --- /dev/null +++ b/EIPS/eip-212.md @@ -0,0 +1 @@ +Reserved for https://github.com/ethereum/EIPs/pull/212 diff --git a/EIPS/eip-213.md b/EIPS/eip-213.md index c5d32cb7747cf..9c3551adc84f0 100644 --- a/EIPS/eip-213.md +++ b/EIPS/eip-213.md @@ -15,7 +15,7 @@ Precompiled contracts for elliptic curve operations are required in order to per ## Abstract -This EIP suggests to add precompiled contracts for addition and scalar multiplication on a specific pairing-friendly elliptic curve. This can in turn be combined with https://github.com/ethereum/EIPs/pull/212 to verify zkSNARKs in Ethereum smart contracts. The general benefit of zkSNARKs for Ethereum is that it will increase the privacy for users (because of the Zero-Knowledge property) and might also be a scalability solution (because of the succinctness and efficient verifiability property). +This EIP suggests to add precompiled contracts for addition and scalar multiplication on a specific pairing-friendly elliptic curve. This can in turn be combined with [EIP-212](./eip-212.md) to verify zkSNARKs in Ethereum smart contracts. The general benefit of zkSNARKs for Ethereum is that it will increase the privacy for users (because of the Zero-Knowledge property) and might also be a scalability solution (because of the succinctness and efficient verifiability property). ## Motivation From a0b9771aded733c8e81e7f43beb6adbf97eefdfc Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 1 Dec 2017 13:41:11 +0100 Subject: [PATCH 0305/1085] Specify the block number and make the status final --- EIPS/eip-213.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-213.md b/EIPS/eip-213.md index 9c3551adc84f0..4b651fd1c7a20 100644 --- a/EIPS/eip-213.md +++ b/EIPS/eip-213.md @@ -6,7 +6,7 @@ Author: Christian Reitwiessner Type: Standard Track Category: Core - Status: Draft + Status: Final Created: 2017-02-02 ## Simple Summary @@ -26,7 +26,7 @@ Note that while fixing these parameters might look like limiting the use-cases f ## Specification -Add precompiled contracts for point addition (ADD) and scalar multiplication (MUL) on the elliptic curve "alt_bn128". +If `block.number >= BYZANTIUM_FORK_BLKNUM`, add precompiled contracts for point addition (ADD) and scalar multiplication (MUL) on the elliptic curve "alt_bn128". Address of ADD: 0x6 Address for MUL: 0x7 From 9706f4fecc6bad77ce5de918973c4bad5c9e355e Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 1 Dec 2017 13:47:06 +0100 Subject: [PATCH 0306/1085] Move pairings.md into eip-212.md --- EIPS/{pairings.md => eip-212.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename EIPS/{pairings.md => eip-212.md} (100%) diff --git a/EIPS/pairings.md b/EIPS/eip-212.md similarity index 100% rename from EIPS/pairings.md rename to EIPS/eip-212.md From daa7689ce831f10d0520ec40c1ab402e994ebde2 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 1 Dec 2017 13:51:11 +0100 Subject: [PATCH 0307/1085] Assign an EIP number and fix a link --- EIPS/eip-212.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-212.md b/EIPS/eip-212.md index 793cd3e1bc7cc..692ad7bf6a38a 100644 --- a/EIPS/eip-212.md +++ b/EIPS/eip-212.md @@ -1,6 +1,6 @@ ## Preamble - EIP: to be assigned + EIP: 212 Title: Precompiled contracts for optimal ate pairing check on the elliptic curve alt_bn128 Author: Vitalik Buterin , Christian Reitwiessner @@ -15,7 +15,7 @@ Precompiled contracts for elliptic curve pairing operations are required in orde ## Abstract -This EIP suggests to add precompiled contracts for a pairing function on a specific pairing-friendly elliptic curve. This can in turn be combined with https://github.com/ethereum/EIPs/issues/196 to verify zkSNARKs in Ethereum smart contracts. The general benefit of zkSNARKs for Ethereum is that it will increase the privacy for users (because of the Zero-Knowledge property) and might also be a scalability solution (because of the succinctness and efficient verifiability property). +This EIP suggests to add precompiled contracts for a pairing function on a specific pairing-friendly elliptic curve. This can in turn be combined with [EIP-213](./eip-213.md) to verify zkSNARKs in Ethereum smart contracts. The general benefit of zkSNARKs for Ethereum is that it will increase the privacy for users (because of the Zero-Knowledge property) and might also be a scalability solution (because of the succinctness and efficient verifiability property). ## Motivation From 9b9e9c86b8aa7f5077fdcb5030f80484dcbf079e Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 1 Dec 2017 14:03:44 +0100 Subject: [PATCH 0308/1085] Add the starting block --- EIPS/eip-212.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-212.md b/EIPS/eip-212.md index 692ad7bf6a38a..768b549b4eec5 100644 --- a/EIPS/eip-212.md +++ b/EIPS/eip-212.md @@ -28,7 +28,7 @@ Pairing functions can be used to perform a limited form of multiplicatively homo ## Specification -Add a precompiled contracts for a bilinear function on groups on the elliptic curve "alt_bn128". We will define the precompiled contract in terms of a discrete logarithm. The discrete logarithm is of course assumed to be hard to compute, but we will give an equivalent specification that makes use of elliptic curve pairing functions which can be efficiently computed below. +For blocks where `block.number >= BYZANTIUM_FORK_BLKNUM`, add a precompiled contracts for a bilinear function on groups on the elliptic curve "alt_bn128". We will define the precompiled contract in terms of a discrete logarithm. The discrete logarithm is of course assumed to be hard to compute, but we will give an equivalent specification that makes use of elliptic curve pairing functions which can be efficiently computed below. Address: 0x8 From cbe317dcd650c15e431f85410e3cbeda3bd31dc1 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 1 Dec 2017 17:54:17 +0100 Subject: [PATCH 0309/1085] Rather pedantic edits --- EIPS/eip-211.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-211.md b/EIPS/eip-211.md index 22d89bb5ad99f..14f65f917b756 100644 --- a/EIPS/eip-211.md +++ b/EIPS/eip-211.md @@ -31,7 +31,7 @@ Note that this proposal also makes the EIP that proposes to allow to return data If `block.number >= BYZANTIUM_FORK_BLKNUM`, add two new opcodes and amend the semantics of any opcode that creates a new call frame (like `CALL`, `CREATE`, `DELEGATECALL`, ...) called call-like opcodes in the following. It is assumed that the EVM (to be more specific: an EVM call frame) has a new internal buffer of variable size, called the return data buffer. This buffer is created empty for each new call frame. Upon executing any call-like opcode, the buffer is cleared (its size is set to zero). After executing a call-like opcode, the complete return data (or failure data, see [EIP-140](./eip-140.md)) of the call is stored in the return data buffer (of the caller), and its size changed accordingly. As an exception, `CREATE` and `CREATE2` are considered to return the empty buffer in the success case and the failure data in the failure case. If the call-like opcode is executed but does not really instantiate a call frame (for example due to insufficient funds for a value transfer or if the called contract does not exist), the return data buffer is empty. -As an optimization, it is possible to share the return data buffer across call frames because only one will be non-empty at any time. +As an optimization, it is possible to share the return data buffer across call frames because at most one will be non-empty at any time. `RETURNDATASIZE`: `0x3d` @@ -40,7 +40,7 @@ Gas costs: 2 (same as `CALLDATASIZE`) `RETURNDATACOPY`: `0x3e` -This opcode has similar semantics to `CALLDATACOPY`, but instead of copying data from the call data, it copies data from the return data buffer. Furthermore, accessing the return data buffer beyond its size results in a failure, i.e. if `start + length` overflows or results in a value larger than `RETURNDATASIZE`, the current call stops in an out-of-gas condition. In particular, reading 0 bytes from the end of the buffer will read 0 bytes; reading 0 bytes from one-byte out of the buffer causes an exception. +This opcode has similar semantics to `CALLDATACOPY`, but instead of copying data from the call data, it copies data from the return data buffer. Furthermore, accessing the return data buffer beyond its size results in a failure; i.e. if `start + length` overflows or results in a value larger than `RETURNDATASIZE`, the current call stops in an out-of-gas condition. In particular, reading 0 bytes from the end of the buffer will read 0 bytes; reading 0 bytes from one-byte out of the buffer causes an exception. Gas costs: `3 + 3 * ceil(amount / 32)` (same as `CALLDATACOPY`) From 2216e5afae5e021f5cb0505b2b48bac920c4d16f Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 1 Dec 2017 17:59:50 +0100 Subject: [PATCH 0310/1085] Fix links --- EIPS/eip-212.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-212.md b/EIPS/eip-212.md index 768b549b4eec5..ce47582cc4214 100644 --- a/EIPS/eip-212.md +++ b/EIPS/eip-212.md @@ -133,6 +133,6 @@ And thus, the precompiled contract can be implemented by verifying that Implementations are available here: - - [libsnark](https://github.com/scipr-lab/libsnark/blob/master/src/algebra/curves/alt_bn128/alt_bn128_g1.hpp) (C++) + - [libff](https://github.com/scipr-lab/libff/blob/master/libff/algebra/curves/alt_bn128/alt_bn128_g1.hpp) (C++) - [bn](https://github.com/zcash/bn/blob/master/src/groups/mod.rs) (Rust) - - [Python](https://github.com/ethereum/research/blob/master/zksnark/bn128_pairing.py) + - [Python](https://github.com/ethereum/py_pairing/blob/master/py_ecc/bn128/bn128_pairing.py) From 18bdc96dcf39c13ae268dec565d7f99f1b9bd20a Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 1 Dec 2017 22:12:33 +0100 Subject: [PATCH 0311/1085] Fix EIP numbers --- EIPS/{eip-213.md => eip-196.md} | 2 +- EIPS/{eip-212.md => eip-197.md} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename EIPS/{eip-213.md => eip-196.md} (98%) rename EIPS/{eip-212.md => eip-197.md} (100%) diff --git a/EIPS/eip-213.md b/EIPS/eip-196.md similarity index 98% rename from EIPS/eip-213.md rename to EIPS/eip-196.md index 4b651fd1c7a20..d4300a21f0df0 100644 --- a/EIPS/eip-213.md +++ b/EIPS/eip-196.md @@ -15,7 +15,7 @@ Precompiled contracts for elliptic curve operations are required in order to per ## Abstract -This EIP suggests to add precompiled contracts for addition and scalar multiplication on a specific pairing-friendly elliptic curve. This can in turn be combined with [EIP-212](./eip-212.md) to verify zkSNARKs in Ethereum smart contracts. The general benefit of zkSNARKs for Ethereum is that it will increase the privacy for users (because of the Zero-Knowledge property) and might also be a scalability solution (because of the succinctness and efficient verifiability property). +This EIP suggests to add precompiled contracts for addition and scalar multiplication on a specific pairing-friendly elliptic curve. This can in turn be combined with [EIP-197](./eip-197.md) to verify zkSNARKs in Ethereum smart contracts. The general benefit of zkSNARKs for Ethereum is that it will increase the privacy for users (because of the Zero-Knowledge property) and might also be a scalability solution (because of the succinctness and efficient verifiability property). ## Motivation diff --git a/EIPS/eip-212.md b/EIPS/eip-197.md similarity index 100% rename from EIPS/eip-212.md rename to EIPS/eip-197.md From d67fea0a1cab737ed3ee31f3a81521ac47822566 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 1 Dec 2017 22:15:51 +0100 Subject: [PATCH 0312/1085] Fix EIP numbers --- EIPS/{eip-213.md => eip-196.md} | 0 EIPS/{eip-212.md => eip-197.md} | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename EIPS/{eip-213.md => eip-196.md} (100%) rename EIPS/{eip-212.md => eip-197.md} (99%) diff --git a/EIPS/eip-213.md b/EIPS/eip-196.md similarity index 100% rename from EIPS/eip-213.md rename to EIPS/eip-196.md diff --git a/EIPS/eip-212.md b/EIPS/eip-197.md similarity index 99% rename from EIPS/eip-212.md rename to EIPS/eip-197.md index ce47582cc4214..d8ea5f1d6762e 100644 --- a/EIPS/eip-212.md +++ b/EIPS/eip-197.md @@ -15,7 +15,7 @@ Precompiled contracts for elliptic curve pairing operations are required in orde ## Abstract -This EIP suggests to add precompiled contracts for a pairing function on a specific pairing-friendly elliptic curve. This can in turn be combined with [EIP-213](./eip-213.md) to verify zkSNARKs in Ethereum smart contracts. The general benefit of zkSNARKs for Ethereum is that it will increase the privacy for users (because of the Zero-Knowledge property) and might also be a scalability solution (because of the succinctness and efficient verifiability property). +This EIP suggests to add precompiled contracts for a pairing function on a specific pairing-friendly elliptic curve. This can in turn be combined with [EIP-196](./eip-196.md) to verify zkSNARKs in Ethereum smart contracts. The general benefit of zkSNARKs for Ethereum is that it will increase the privacy for users (because of the Zero-Knowledge property) and might also be a scalability solution (because of the succinctness and efficient verifiability property). ## Motivation From 7c448166de919e543cfaa002b75e94955f524734 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 1 Dec 2017 22:17:50 +0100 Subject: [PATCH 0313/1085] Fix a number in the header as well --- EIPS/eip-196.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-196.md b/EIPS/eip-196.md index d4300a21f0df0..3eaa411ee285e 100644 --- a/EIPS/eip-196.md +++ b/EIPS/eip-196.md @@ -1,6 +1,6 @@ ## Preamble - EIP: 213 + EIP: 196 Title: Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 Author: Christian Reitwiessner From a9e828bf1c95c72c5ec2f56361639e7d5cb1ebbc Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 1 Dec 2017 22:19:06 +0100 Subject: [PATCH 0314/1085] Also change the number in the header --- EIPS/eip-197.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-197.md b/EIPS/eip-197.md index d8ea5f1d6762e..93f80c37badd3 100644 --- a/EIPS/eip-197.md +++ b/EIPS/eip-197.md @@ -1,6 +1,6 @@ ## Preamble - EIP: 212 + EIP: 197 Title: Precompiled contracts for optimal ate pairing check on the elliptic curve alt_bn128 Author: Vitalik Buterin , Christian Reitwiessner From 9783ecdff7fa5d897d5e862a933e1a68a1a043e5 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 1 Dec 2017 23:13:52 +0100 Subject: [PATCH 0315/1085] EIP-100 is already active on the mainnet, so its status should be Final --- EIPS/eip-100.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-100.md b/EIPS/eip-100.md index 6bb6dcfc8273c..12d7dda24a85e 100644 --- a/EIPS/eip-100.md +++ b/EIPS/eip-100.md @@ -4,7 +4,7 @@ Title: Change difficulty adjustment to target mean block time including uncles Author: Vitalik Buterin Type: Standard Track Category: Core -Status: Accepted +Status: Final Created: 2016-04-28 ``` From fcff7637d7bf67a2fd4dfdf7313f4d5e1a0ae443 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Sun, 26 Nov 2017 12:06:46 -0500 Subject: [PATCH 0316/1085] add informational EIP for DAO HF --- EIPS/eip-779.md | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 EIPS/eip-779.md diff --git a/EIPS/eip-779.md b/EIPS/eip-779.md new file mode 100644 index 0000000000000..08568a51d2ddf --- /dev/null +++ b/EIPS/eip-779.md @@ -0,0 +1,63 @@ +## Preamble + + EIP: 779 + Title: Hardfork Info: DAO Fork + Author: Casey Detrio + Type: Informational + Status: Final + Created: 2017-11-26 + +## Abstract + +This documents the changes included in the hard fork named "DAO Fork". Unlike other hard forks, the DAO Fork did not change the protocol; all EVM opcodes, transaction format, block structure, and so on remained the same. Rather, the DAO Fork was an "irregular state change" that transferred ether balances from a list of accounts ("child DAO" contracts) into a specified account (the "WithdrawDAO" contract). + +## Specification + +- Codename: DAO Fork +- Activation: + - Block == 1,920,000 on Mainnet + +See references [1] and [2] for the original, full specification. It is summarized here for convenience. + +At block 1880000, the following accounts are encoded into a list `L`: +* The DAO (`0xbb9bc244d798123fde783fcc1c72d3bb8c189413`) +* its extraBalance (`0x807640a13483f8ac783c557fcdf27be11ea4ac7a`) +* all children of the DAO creator (`0x4a574510c7014e4ae985403536074abe582adfc8`) +* and the extraBalance of each child + +At the beginning of block 1920000, all ether throughout all accounts in `L` will be transferred to a contract deployed at `0xbf4ed7b27f1d666546e30d74d50d173d20bca754`. The contract was created from the following Solidity code (compiler version `v0.3.5-2016-07-01-48238c9`): + +``` +// Deployed on mainnet at 0xbf4ed7b27f1d666546e30d74d50d173d20bca754 + +contract DAO { + function balanceOf(address addr) returns (uint); + function transferFrom(address from, address to, uint balance) returns (bool); + uint public totalSupply; +} + +contract WithdrawDAO { + DAO constant public mainDAO = DAO(0xbb9bc244d798123fde783fcc1c72d3bb8c189413); + address public trustee = 0xda4a4626d3e16e094de3225a751aab7128e96526; + + function withdraw(){ + uint balance = mainDAO.balanceOf(msg.sender); + + if (!mainDAO.transferFrom(msg.sender, this, balance) || !msg.sender.send(balance)) + throw; + } + + function trusteeWithdraw() { + trustee.send((this.balance + mainDAO.balanceOf(this)) - mainDAO.totalSupply()); + } +} +``` + +## References + +1. https://blog.slock.it/hard-fork-specification-24b889e70703 +2. https://blog.ethereum.org/2016/07/15/to-fork-or-not-to-fork/ + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 7fd6a3d979347e45203f582b60d00062bdce3c5a Mon Sep 17 00:00:00 2001 From: cdetrio Date: Sat, 2 Dec 2017 15:08:26 -0500 Subject: [PATCH 0317/1085] add test cases to EIP-55 --- EIPS/eip-55.md | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/EIPS/eip-55.md b/EIPS/eip-55.md index e60dc159b334c..8979a77257e2b 100644 --- a/EIPS/eip-55.md +++ b/EIPS/eip-55.md @@ -37,6 +37,13 @@ test('0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb') In English, convert the address to hex, but if the `i`th digit is a letter (ie. it's one of `abcdef`) print it in uppercase if the `4*i`th bit of the hash of the lowercase hexadecimal address is 1 otherwise print it in lowercase. +# Rationale + +Benefits: +- Backwards compatible with many hex parsers that accept mixed case, allowing it to be easily introduced over time +- Keeps the length at 40 characters +- On average there will be 15 check bits per address, and the net probability that a randomly generated address if mistyped will accidentally pass a check is 0.0247%. This is a ~50x improvement over ICAP, but not as good as a 4-byte check code. + # Implementation In javascript: @@ -72,12 +79,21 @@ Note that the input to the Keccak256 hash is the lowercase hexadecimal string (i var hash = createKeccakHash('keccak256').update(Buffer.from(address.toLowerCase(), 'ascii')).digest() ``` -# Rationale +# Test Cases -Benefits: -- Backwards compatible with many hex parsers that accept mixed case, allowing it to be easily introduced over time -- Keeps the length at 40 characters -- On average there will be 15 check bits per address, and the net probability that a randomly generated address if mistyped will accidentally pass a check is 0.0247%. This is a ~50x improvement over ICAP, but not as good as a 4-byte check code. +``` +# All caps +0x52908400098527886E0F7030069857D2E4169EE7 +0x8617E340B3D01FA5F11F306F4090FD50E238070D +# All Lower +0xde709f2102306220921060314715629080e2fb77 +0x27b1fdb04752bbc536007a920d24acb045561c26 +# Normal +0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed +0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359 +0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB +0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb +``` # Adoption From b1623c2f5f3b6350d74d7bf54115c8657aaab602 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 4 Dec 2017 11:13:15 +0100 Subject: [PATCH 0318/1085] Update eip-214.md --- EIPS/eip-214.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/EIPS/eip-214.md b/EIPS/eip-214.md index 1bc58474603e9..2e5756c0c57e0 100644 --- a/EIPS/eip-214.md +++ b/EIPS/eip-214.md @@ -46,3 +46,7 @@ To be written. ## Implementation +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). + From a8494952b0e5143bf083b78b761f6d7c8b6d39e4 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 4 Dec 2017 11:13:46 +0100 Subject: [PATCH 0319/1085] Update eip-197.md --- EIPS/eip-197.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/EIPS/eip-197.md b/EIPS/eip-197.md index 93f80c37badd3..d061d17faa463 100644 --- a/EIPS/eip-197.md +++ b/EIPS/eip-197.md @@ -136,3 +136,7 @@ Implementations are available here: - [libff](https://github.com/scipr-lab/libff/blob/master/libff/algebra/curves/alt_bn128/alt_bn128_g1.hpp) (C++) - [bn](https://github.com/zcash/bn/blob/master/src/groups/mod.rs) (Rust) - [Python](https://github.com/ethereum/py_pairing/blob/master/py_ecc/bn128/bn128_pairing.py) + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 22afa8088e602802c184966da43d82a71ff2864f Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 4 Dec 2017 13:03:41 +0100 Subject: [PATCH 0320/1085] Update the Byzantium list --- EIPS/eip-609.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-609.md b/EIPS/eip-609.md index 4ac787814216f..3549b17be5c5e 100644 --- a/EIPS/eip-609.md +++ b/EIPS/eip-609.md @@ -24,7 +24,7 @@ This specifies the changes included in the hard fork named Byzantium. - EIP 100 (Change difficulty adjustment to target mean block time including uncles) - EIP 140 (REVERT instruction in the Ethereum Virtual Machine) - EIP 196 (Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128) - - EIP 197 (Precompiled contracts for optimal ate pairing check on the elliptic curve alt_bn128) + - [EIP 197](./eip-197.md) (Precompiled contracts for optimal ate pairing check on the elliptic curve alt_bn128) - EIP 198 (Precompiled contract for bigint modular exponentiation) - EIP 211 (New opcodes: RETURNDATASIZE and RETURNDATACOPY) - EIP 214 (New opcode STATICCALL) From 3977ac9fc14db5a23395c657bf1a1845b435f15f Mon Sep 17 00:00:00 2001 From: Nick Savers Date: Mon, 4 Dec 2017 16:50:09 +0100 Subject: [PATCH 0321/1085] Correct EIP-55 layer to ERC --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9a8119fbdd967..c461f0998538e 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Core | Final | | [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Networking | Final | | [20](EIPS/eip-20-token-standard.md) | ERC-20 Token Standard | Fabian Vogelsteller, Vitalik Buterin | ERC | Final | -| [55](EIPS/eip-55.md) | ERC-55 Mixed-case checksum address encoding | Vitalik Buterin | Core | Final | +| [55](EIPS/eip-55.md) | ERC-55 Mixed-case checksum address encoding | Vitalik Buterin | ERC | Final | | [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Core | Final | | [137](EIPS/eip-137.md) | Ethereum Domain Name Service - Specification | Nick Johnson | ERC | Final | | [140](https://github.com/ethereum/EIPs/pull/206) | REVERT instruction in the Ethereum Virtual Machine | Alex Beregszaszi, Nikolai Mushegian | Core | Final | From f61b4665fb36c4e4642a88dfdf5045f4055b78cf Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 4 Dec 2017 21:37:16 +0100 Subject: [PATCH 0322/1085] Make eip-197.md Final The EIP is already active on the main net. --- EIPS/eip-197.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-197.md b/EIPS/eip-197.md index d061d17faa463..2197e5d81a1ec 100644 --- a/EIPS/eip-197.md +++ b/EIPS/eip-197.md @@ -6,7 +6,7 @@ Author: Vitalik Buterin , Christian Reitwiessner Type: Standard Track Category: Core - Status: Draft + Status: Final Created: 2017-02-06 ## Simple Summary From 231cba1730650a38810fca1cfcda4ef0d1dd6873 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 4 Dec 2017 21:53:01 +0100 Subject: [PATCH 0323/1085] Trying to explain why a generator appears --- EIPS/eip-197.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-197.md b/EIPS/eip-197.md index 2197e5d81a1ec..7e5064784bd0c 100644 --- a/EIPS/eip-197.md +++ b/EIPS/eip-197.md @@ -34,7 +34,7 @@ Address: 0x8 For a cyclic group `G` (written additively) of prime order `q` let `log_P: G -> F_q` be the discrete logarithm on this group with respect to a generator `P`, i.e. `log_P(x)` is the smallest non-negative integer `n` such that `n * P = x`. -The precompiled contract is defined as follows, where the two groups `G_1` and `G_2` and their generators `P_1` and `P_2` are defined below. Both generators have the same prime order `q` and the actual choice of the generators does not matter, as long as they have order `q`. +The precompiled contract is defined as follows, where the two groups `G_1` and `G_2` are defined by their generators `P_1` and `P_2` below. Both generators have the same prime order `q`. ``` Input: (a1, b1, a2, b2, ..., ak, bk) from (G_1 x G_2)^k @@ -68,7 +68,7 @@ P2 = ( ) ``` -Note that `G_2` is the only group of order `q` of that elliptic curve over the field `F_p^2`. +Note that `G_2` is the only group of order `q` of that elliptic curve over the field `F_p^2`. Any other generator of order `q` instead of `P2` would define the same `G_2`. However, a skeptical reader can compare `q * P2` and `P2` to check the existence of a group of order `q` on `G_2`. ### Encoding From 1231f25e4751362c029f539f011a5048feba0f46 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 4 Dec 2017 22:03:33 +0100 Subject: [PATCH 0324/1085] Clearer explanation why P2 appears --- EIPS/eip-197.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-197.md b/EIPS/eip-197.md index 7e5064784bd0c..0f5534721ddd2 100644 --- a/EIPS/eip-197.md +++ b/EIPS/eip-197.md @@ -68,7 +68,7 @@ P2 = ( ) ``` -Note that `G_2` is the only group of order `q` of that elliptic curve over the field `F_p^2`. Any other generator of order `q` instead of `P2` would define the same `G_2`. However, a skeptical reader can compare `q * P2` and `P2` to check the existence of a group of order `q` on `G_2`. +Note that `G_2` is the only group of order `q` of that elliptic curve over the field `F_p^2`. Any other generator of order `q` instead of `P2` would define the same `G_2`. However, the concrete value of `P2` is useful for skeptical readers who doubt the existence of a group of order `q`. They can be instructed to compare the concrete values of `q * P2` and `P2`. ### Encoding @@ -92,7 +92,7 @@ points or, equivalently, the length of the input divided by 192. The specific curve `alt_bn128` was chosen because it is particularly well-suited for zkSNARKs, or, more specifically their verification building block of pairing functions. Furthermore, by choosing this curve, we can use synergy effects with ZCash and re-use some of their components and artifacts. -The feature of adding curve and field parameters to the inputs was considered but ultimately rejected since it complicates the specification: The gas costs are much harder to determine and it would be possible to call the contracts on something which is not an actual elliptic curve or does not admit an efficient pairing implementation. +The feature of adding curve and field parameters to the inputs was considered but ultimately rejected since it complicates the specification; the gas costs are much harder to determine and it would be possible to call the contracts on something which is not an actual elliptic curve or does not admit an efficient pairing implementation. A non-compact point encoding was chosen since it still allows to perform some operations in the smart contract itself (inclusion of the full y coordinate) and two encoded points can be compared for equality (no third projective coordinate). From bccf7d1a3f942e99bef2541092fb9540238b1e34 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 5 Dec 2017 00:59:18 +0000 Subject: [PATCH 0325/1085] Simplify the title --- EIPS/eip-140.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-140.md b/EIPS/eip-140.md index fe897d2dc8bb7..1e205e5fabfc4 100644 --- a/EIPS/eip-140.md +++ b/EIPS/eip-140.md @@ -1,7 +1,7 @@ ## Preamble EIP: 140 - Title: REVERT instruction in the Ethereum Virtual Machine + Title: REVERT instruction Author: Alex Beregszaszi, Nikolai Mushegian (nikolai@nexusdev.us) Type: Standard Track Category: Core From a64d8d08db4af3d90c01697807a3e9cf96dbd4dc Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Tue, 5 Dec 2017 12:37:32 +0100 Subject: [PATCH 0326/1085] Add 'Copyright Waiver' to 'What belongs in a successful EIP?' --- EIPS/eip-1.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index eb3315e1b1794..77b7f7a77f71b 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -103,6 +103,10 @@ Each EIP should have the following parts: - Implementations - The implementations must be completed before any EIP is given status “Final”, but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of “rough consensus and running code” is still useful when it comes to resolving many discussions of API details. + + +- Copyright Waiver - All EIPs must be in public domain. See the bottom of this EIP for an example copyright waiver. + EIP Formats and Templates ------------------------- From 427163cdd411fb970f9b4676ddd4641b4465da26 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 5 Dec 2017 15:27:16 +0100 Subject: [PATCH 0327/1085] eip-778: clarify signature encoding even more --- EIPS/eip-778.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-778.md b/EIPS/eip-778.md index e4274a6d9f22f..9e245a3498b8e 100644 --- a/EIPS/eip-778.md +++ b/EIPS/eip-778.md @@ -75,7 +75,7 @@ This specification defines a single scheme to be used as the default: "secp256k1 - To sign record `content` with this scheme, apply the keccak256[^1] hash function to `content`, then create a signature of the hash. The resulting 64-byte signature is - encoded as the concatenation of `r` and `s`. + encoded as the concatenation of the `r` and `s` signature values. - To verify a record, check that the signature was made by the public key in the "secp256k1" key/value pair. - To derive a node address, take the keccak256 hash of the public key. From cf3c8d86cd78c9b368d5e7674511e01e5cd300c6 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Tue, 5 Dec 2017 16:28:17 +0100 Subject: [PATCH 0328/1085] Accept eip-758 --- EIPS/eip-transaction_return_values.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-transaction_return_values.md b/EIPS/eip-transaction_return_values.md index 97107279d93cf..f38666dc13637 100644 --- a/EIPS/eip-transaction_return_values.md +++ b/EIPS/eip-transaction_return_values.md @@ -1,11 +1,11 @@ ## Preamble - EIP: + EIP: 758 Title: Subscriptions and filters for transaction return data Author: Jack Peterson Type: Standard Track Category: Interface - Status: Draft + Status: Accepted Created: 2017-11-09 From e15c813149a7c129917ed47451d1d2e161f6e3c0 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Tue, 5 Dec 2017 16:29:51 +0100 Subject: [PATCH 0329/1085] Rename into eip-758.md --- EIPS/{eip-transaction_return_values.md => eip-758.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename EIPS/{eip-transaction_return_values.md => eip-758.md} (100%) diff --git a/EIPS/eip-transaction_return_values.md b/EIPS/eip-758.md similarity index 100% rename from EIPS/eip-transaction_return_values.md rename to EIPS/eip-758.md From c01e809802c426bf6e0ed88c82789a9e9c1cb4bf Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Tue, 5 Dec 2017 16:30:35 +0100 Subject: [PATCH 0330/1085] Linking to an EIP by filename --- EIPS/eip-758.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-758.md b/EIPS/eip-758.md index f38666dc13637..a485b246fa23a 100644 --- a/EIPS/eip-758.md +++ b/EIPS/eip-758.md @@ -88,7 +88,7 @@ The node responds with an array of transaction hashes and their corresponding re ``` ## Rationale -[EIP 658](https://github.com/ethereum/EIPs/pull/658) originally proposed adding return data to transaction receipts. However, return data is not charged for (as it is not stored on the blockchain), so adding it to transaction receipts could result in DoS and spam opportunities. Instead, a simple Boolean `status` field was added to transaction receipts. This modified version of EIP 658 was included in the Byzantium hard fork. While the `status` field is useful, applications often need the return data as well. +[EIP 658](./eip-658.md) originally proposed adding return data to transaction receipts. However, return data is not charged for (as it is not stored on the blockchain), so adding it to transaction receipts could result in DoS and spam opportunities. Instead, a simple Boolean `status` field was added to transaction receipts. This modified version of EIP 658 was included in the Byzantium hard fork. While the `status` field is useful, applications often need the return data as well. The primary advantage of using the strategy outlined here is efficiency: no extra data needs to be stored on the blockchain, and minimal extra computational load is imposed on nodes. Since light clients have the current state, they can compute and send return data notifications without contacting a server. Although after-the-fact lookups of the return value would not be supported, this is consistent with the conventional use of return data, which are only accessible to the caller when the function returns, and are not stored for later use. From 69194eab82b73bb029ed450b56a079731f353ab0 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Tue, 5 Dec 2017 16:37:56 +0100 Subject: [PATCH 0331/1085] Update eip-758.md --- EIPS/eip-758.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-758.md b/EIPS/eip-758.md index a485b246fa23a..9d96bce84d3f9 100644 --- a/EIPS/eip-758.md +++ b/EIPS/eip-758.md @@ -5,7 +5,7 @@ Author: Jack Peterson Type: Standard Track Category: Interface - Status: Accepted + Status: Draft Created: 2017-11-09 From 964104b784be58cd61592edb4516809c373fdfc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Lesaege?= Date: Tue, 5 Dec 2017 17:33:26 +0100 Subject: [PATCH 0332/1085] Move the sentence about Transfer event at creation In the current file, the sentence "A token contract which creates new tokens SHOULD trigger a Transfer event with the _from address set to 0x0 when tokens are created." is part of the "transfer" method section. This sentences is linked to the "Transfer" event, not the "transfer" method. I suggest to move it to the appropriate "Transfer" section. --- EIPS/eip-20-token-standard.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-20-token-standard.md b/EIPS/eip-20-token-standard.md index 4b209dcd0df95..05ad25d7d1739 100644 --- a/EIPS/eip-20-token-standard.md +++ b/EIPS/eip-20-token-standard.md @@ -96,8 +96,6 @@ function balanceOf(address _owner) constant returns (uint256 balance) Transfers `_value` amount of tokens to address `_to`, and MUST fire the `Transfer` event. The function SHOULD `throw` if the `_from` account balance does not have enough tokens to spend. -A token contract which creates new tokens SHOULD trigger a Transfer event with the `_from` address set to `0x0` when tokens are created. - *Note* Transfers of 0 values MUST be treated as normal transfers and fire the `Transfer` event. ``` js @@ -152,6 +150,8 @@ function allowance(address _owner, address _spender) constant returns (uint256 r MUST trigger when tokens are transferred, including zero value transfers. +A token contract which creates new tokens SHOULD trigger a Transfer event with the `_from` address set to `0x0` when tokens are created. + ``` js event Transfer(address indexed _from, address indexed _to, uint256 _value) ``` From 93ddda2dd666160246d36332036c7ebbf5e1617e Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Fri, 8 Dec 2017 13:59:12 +1100 Subject: [PATCH 0333/1085] eip55: consistent JS syntax --- EIPS/eip-55.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-55.md b/EIPS/eip-55.md index 8979a77257e2b..b428ab38be410 100644 --- a/EIPS/eip-55.md +++ b/EIPS/eip-55.md @@ -52,7 +52,7 @@ In javascript: const createKeccakHash = require('keccak') function toChecksumAddress (address) { - address = address.toLowerCase().replace('0x',''); + address = address.toLowerCase().replace('0x', '') var hash = createKeccakHash('keccak256').update(address).digest('hex') var ret = '0x' From 75121e281a8737f979a969394b4360d4d277c115 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 8 Dec 2017 11:59:47 +0100 Subject: [PATCH 0334/1085] Update eip-140.md --- EIPS/eip-140.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-140.md b/EIPS/eip-140.md index 1e205e5fabfc4..026e30255ae66 100644 --- a/EIPS/eip-140.md +++ b/EIPS/eip-140.md @@ -22,7 +22,7 @@ Currently this is not possible. There are two practical ways to revert a transac ## Specification -The `REVERT` instruction is introduced at `0xfd`. It expects two stack items, the top item is the `memory_offset` followed by `memory_length`. It does not produce any stack elements because it stops execution. +On blocks with `block.number >= BYZANTIUM_FORK_BLKNUM`, the `REVERT` instruction is introduced at `0xfd`. It expects two stack items, the top item is the `memory_offset` followed by `memory_length`. It does not produce any stack elements because it stops execution. The semantics of `REVERT` with respect to memory and memory cost are identical to those of `RETURN`. The sequence of bytes given by `memory_offset` and `memory_length` is called "error message" in the following. @@ -55,4 +55,4 @@ should: ## Copyright -Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From fc9749ba727929302b2a2c40e1eda47a67059bbd Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 8 Dec 2017 13:49:43 +0100 Subject: [PATCH 0335/1085] eip-778: clarify size of public key --- EIPS/eip-778.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-778.md b/EIPS/eip-778.md index 9e245a3498b8e..854c3f82d9f98 100644 --- a/EIPS/eip-778.md +++ b/EIPS/eip-778.md @@ -64,7 +64,7 @@ preferred. The following keys are pre-defined: | Key | Value | |:-------------|:-------------------------------------------------| | `id` | name of identity scheme, e.g. "secp256k1-keccak" | -| `secp256k1` | compressed secp256k1 public key | +| `secp256k1` | compressed secp256k1 public key, 33 bytes | | `ip4` | IPv4 address, 4 bytes | | `ip6` | IPv6 address, 16 bytes | | `discv5` | UDP port for discovery v5 | From 95e28ff61408c8c1fd4d38c961290419323edbca Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 8 Dec 2017 13:50:15 +0100 Subject: [PATCH 0336/1085] eip-778: clarify size of sequence number --- EIPS/eip-778.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-778.md b/EIPS/eip-778.md index 854c3f82d9f98..0c1df1273c0b8 100644 --- a/EIPS/eip-778.md +++ b/EIPS/eip-778.md @@ -36,8 +36,8 @@ be able to determine which record is newer. The components of a node record are: - `signature`: cryptographic signature of record contents -- `seq`: A sequence number. Nodes should increase the number whenever the record changes - and republish the record. +- `seq`: The sequence number, a 64 bit integer. Nodes should increase the number whenever + the record changes and republish the record. - The remainder of the record consists of arbitrary key/value pairs, which must be sorted by key. From f80eb12f22f178c81dc2a6de4be0c73cd302b73b Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Sat, 9 Dec 2017 23:44:30 +0100 Subject: [PATCH 0337/1085] eip-778: fix typo --- EIPS/eip-778.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-778.md b/EIPS/eip-778.md index 0c1df1273c0b8..3b3708c77a962 100644 --- a/EIPS/eip-778.md +++ b/EIPS/eip-778.md @@ -41,7 +41,7 @@ The components of a node record are: - The remainder of the record consists of arbitrary key/value pairs, which must be sorted by key. -A record's signature is made and validated according to an *identy scheme*. The identity +A record's signature is made and validated according to an *identity scheme*. The identity scheme is also responsible for deriving a node's address in the DHT. ### RLP Encoding From 54abd912e3d6a7ae369492f589522dcf7ea8009f Mon Sep 17 00:00:00 2001 From: juanchel Date: Sun, 10 Dec 2017 11:47:24 -0800 Subject: [PATCH 0338/1085] Update EIP609 status to final --- EIPS/eip-609.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-609.md b/EIPS/eip-609.md index fae5e306a1336..de996c69d0c8b 100644 --- a/EIPS/eip-609.md +++ b/EIPS/eip-609.md @@ -5,7 +5,7 @@ Author: Alex Beregszaszi Type: Standard Track Category: Core - Status: Draft + Status: Final Created: 2017-04-23 Requires: 100, 140, 196, 197, 198, 211, 214, 649, 658 From 0c8620d7459314f867af24224815498f4042f0f5 Mon Sep 17 00:00:00 2001 From: Nick Savers Date: Mon, 11 Dec 2017 21:30:38 +0100 Subject: [PATCH 0339/1085] Update links to EIPs in Byzantium Informational --- EIPS/eip-609.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/EIPS/eip-609.md b/EIPS/eip-609.md index de996c69d0c8b..c849c24bad326 100644 --- a/EIPS/eip-609.md +++ b/EIPS/eip-609.md @@ -22,12 +22,12 @@ This specifies the changes included in the hard fork named Byzantium. - Block >= 1,700,000 on Ropsten testnet - Included EIPs: - [EIP 100](./eip-100.md) (Change difficulty adjustment to target mean block time including uncles) - - EIP 140 (REVERT instruction in the Ethereum Virtual Machine) - - EIP 196 (Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128) + - [EIP 140](./eip-140.md) (REVERT instruction in the Ethereum Virtual Machine) + - [EIP 196](./eip-196.md) (Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128) - [EIP 197](./eip-197.md) (Precompiled contracts for optimal ate pairing check on the elliptic curve alt_bn128) - EIP 198 (Precompiled contract for bigint modular exponentiation) - - EIP 211 (New opcodes: RETURNDATASIZE and RETURNDATACOPY) - - EIP 214 (New opcode STATICCALL) + - [EIP 211](./eip-211.md) (New opcodes: RETURNDATASIZE and RETURNDATACOPY) + - [EIP 214](./eip-214.md) (New opcode STATICCALL) - [EIP 649](./eip-649.md) (Difficulty Bomb Delay and Block Reward Reduction) - [EIP 658](./eip-658.md) (Embedding transaction status code in receipts) From 32add27038525316d5434fd4b472ad6edb36c5b4 Mon Sep 17 00:00:00 2001 From: Micah Zoltu Date: Wed, 13 Dec 2017 09:43:10 -0800 Subject: [PATCH 0340/1085] Assigns EIP number. --- EIPS/{EIP-draft-getLogs-by-block-hash.md => eip-234.md} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename EIPS/{EIP-draft-getLogs-by-block-hash.md => eip-234.md} (98%) diff --git a/EIPS/EIP-draft-getLogs-by-block-hash.md b/EIPS/eip-234.md similarity index 98% rename from EIPS/EIP-draft-getLogs-by-block-hash.md rename to EIPS/eip-234.md index 38bfeef414aa8..7d8403e476a8c 100644 --- a/EIPS/EIP-draft-getLogs-by-block-hash.md +++ b/EIPS/eip-234.md @@ -1,6 +1,6 @@ ## Preamble ``` -EIP: +EIP: 234 Title: Add `blockHash` to JSON-RPC filter options. Author: Micah Zoltu Type: Standard Track @@ -47,4 +47,4 @@ The only potential issue here is the `fromBlock` and `toBlock` fields. It would ## Copyright -Copyright and related rights waived via CC0. +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 522584f0409e734aba3521bb8a03373657d6dd1c Mon Sep 17 00:00:00 2001 From: Jack Peterson Date: Fri, 15 Dec 2017 11:36:59 -0800 Subject: [PATCH 0341/1085] Clarify for which transactions the client is notified --- EIPS/eip-758.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-758.md b/EIPS/eip-758.md index 9d96bce84d3f9..04424d05c4bda 100644 --- a/EIPS/eip-758.md +++ b/EIPS/eip-758.md @@ -49,7 +49,7 @@ The caller submits a transaction via `eth_sendTransaction` or `eth_sendRawTransa } ``` -The caller receives notifications about their transactions' return data in two cases: first when a transaction is sealed, and again (with an extra `"removed": true` field) if a transaction is affected by a chain reorganization. As with other subscriptions, the caller can send an `eth_unsubscribe` RPC request to stop receiving push notifications: +The caller receives notifications about their transactions' return data in two cases: first when a transaction is sealed, and again (with an extra `"removed": true` field) if a transaction is affected by a chain reorganization. Notifications are sent to the client for all transactions submitted from the client that are sealed _after_ subscribing. As with other subscriptions, the caller can send an `eth_unsubscribe` RPC request to stop receiving push notifications: ```json {"jsonrpc": "2.0", "id": 2, "method": "eth_unsubscribe", "params": ["0x00000000000000000000000000000b0b"]} @@ -87,6 +87,9 @@ The node responds with an array of transaction hashes and their corresponding re } ``` +All transactions submitted by the client that were sealed _after_ the initial `eth_newFilter` request are included in this array. + + ## Rationale [EIP 658](./eip-658.md) originally proposed adding return data to transaction receipts. However, return data is not charged for (as it is not stored on the blockchain), so adding it to transaction receipts could result in DoS and spam opportunities. Instead, a simple Boolean `status` field was added to transaction receipts. This modified version of EIP 658 was included in the Byzantium hard fork. While the `status` field is useful, applications often need the return data as well. From 49cfee12d4bb0bb4925d8b97fda25be100d8dd04 Mon Sep 17 00:00:00 2001 From: ligi Date: Sun, 17 Dec 2017 03:46:58 +0100 Subject: [PATCH 0342/1085] Introduce (warrant) Canary ERC --- EIPS/eip-canary-standard.md | 122 ++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 EIPS/eip-canary-standard.md diff --git a/EIPS/eip-canary-standard.md b/EIPS/eip-canary-standard.md new file mode 100644 index 0000000000000..2ef68d9e142a9 --- /dev/null +++ b/EIPS/eip-canary-standard.md @@ -0,0 +1,122 @@ +## Preamble + + EIP: 801 + Title: ERC-801 Canary Standard + Author: ligi + Type: Standard + Category: ERC + Status: Draft + Created: 2017-12-16 + + +## Simple Summary + +A standard interface for canary contracts. + +## Abstract + +The following standard allows the implementation of canaries within contracts. +This standard provides basic functionality to check if a canary is alive, keeping the canary alive and optionally manage feeders. + +## Motivation + +The canary can e.g. be used as a [warrant canary](https://en.wikipedia.org/wiki/Warrant_canary). +A standard interface allows other applications to easily interface with canaries on Ethereum - e.g. for visualizing the state, automated alarms, applications to feed the canary or contracts (e.g. insurance) that use the state. + +## Specification + +### Methods + +#### isAlive() + +Returns if the canary was feed properly to signal e.g. that no warrant was received. + +``` js +function isAlive() constant returns (bool alive) +``` + +#### timeToLive() + +The time in seconds that can elapse between feed() calls without starving the canary dead. + +``` js +function timeToLive() constant returns (uint256 ttl) +``` + +#### feed() + +Extend the life of the canary by timeToLive() seconds. + +**NOTE**: this should trigger the event listed below + +``` js +function feed() +``` + +#### poison() + +Kills the canary instantly. E.g. in a urgent case when a warrant was received. + +``` js +function poison() +``` + +#### (optional) addFeeder(address feeder) + +Add address that is allowed to feed (and therefore also poison) the canary. + +``` js +function addFeeder(address feeder) +``` + +#### (optional) removeFeeder(address feeder) + +Remove address that is allowed to feed the canary. + +``` js +function removeFeeder(address feeder) +``` + +#### (optional) getFeederCount() + +Returns the count of addresses that are allowed to feed the canary. + +``` js +function getFeederCount() constant returns (int count) +``` + +#### (optional) getFeederByIndex(unit8 index) + +Returns the address of the feeder at the given index. + +``` js +function getFeederByIndex(unit8 index) constant returns (address feederAddress) +``` + +#### (optional) needsAllFeeders() + +When true: all feeders need to call feed() in the intervals defined by timeToLive() - analog to a multisig. +When false: all the feeders can extend the lifespan of the canary. + +This does not affect poisoning - one feeder is always enough to kill the canary. + +``` js +function needsAllFeeders() constant returns (bool needsAllFeeders) +``` + +### Events + +#### Feed + +MUST trigger when the canary got food. + +``` js +event Feed(address feeder) +``` + +## Implementation + +TODO + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 37cfc31665b10964e3239712e1dff5b2272c8c56 Mon Sep 17 00:00:00 2001 From: ligi Date: Tue, 19 Dec 2017 11:58:50 +0100 Subject: [PATCH 0343/1085] Simplify - the essence of a Canary --- EIPS/eip-canary-standard.md | 81 +++++++++---------------------------- 1 file changed, 19 insertions(+), 62 deletions(-) diff --git a/EIPS/eip-canary-standard.md b/EIPS/eip-canary-standard.md index 2ef68d9e142a9..d0a7dff5dbdc4 100644 --- a/EIPS/eip-canary-standard.md +++ b/EIPS/eip-canary-standard.md @@ -2,7 +2,7 @@ EIP: 801 Title: ERC-801 Canary Standard - Author: ligi + Author: ligi Type: Standard Category: ERC Status: Draft @@ -29,89 +29,46 @@ A standard interface allows other applications to easily interface with canaries #### isAlive() -Returns if the canary was feed properly to signal e.g. that no warrant was received. +Returns if the canary was fed properly to signal e.g. that no warrant was received. ``` js function isAlive() constant returns (bool alive) ``` -#### timeToLive() +#### getBlockOfDeath() -The time in seconds that can elapse between feed() calls without starving the canary dead. +Returns the block the canary died. +Throws if the canary is alive. ``` js -function timeToLive() constant returns (uint256 ttl) +function getBlockOfDeath() constant returns (uint256 block) ``` -#### feed() +#### getType() -Extend the life of the canary by timeToLive() seconds. +Returns the type of the canary: -**NOTE**: this should trigger the event listed below +* `1` = Simple (just the pure interface as defined in this ERC) +* `2` = Single feeder (as defined in ERC-TBD) +* `3` = Single feeder with bad food (as defined in ERC-TBD) +* `4` = Multiple feeders (as defined in ERC-TBD) +* `5` = Multiple mandatory feeders (as defined in ERC-TBD) +* `6` = IOT (as defined in ERC-TBD) -``` js -function feed() -``` - -#### poison() - -Kills the canary instantly. E.g. in a urgent case when a warrant was received. - -``` js -function poison() -``` - -#### (optional) addFeeder(address feeder) - -Add address that is allowed to feed (and therefore also poison) the canary. - -``` js -function addFeeder(address feeder) -``` - -#### (optional) removeFeeder(address feeder) - -Remove address that is allowed to feed the canary. - -``` js -function removeFeeder(address feeder) -``` - -#### (optional) getFeederCount() - -Returns the count of addresses that are allowed to feed the canary. - -``` js -function getFeederCount() constant returns (int count) -``` - -#### (optional) getFeederByIndex(unit8 index) - -Returns the address of the feeder at the given index. - -``` js -function getFeederByIndex(unit8 index) constant returns (address feederAddress) -``` - -#### (optional) needsAllFeeders() - -When true: all feeders need to call feed() in the intervals defined by timeToLive() - analog to a multisig. -When false: all the feeders can extend the lifespan of the canary. - -This does not affect poisoning - one feeder is always enough to kill the canary. +`1` might also be used for a special purpose contract that does not need a special type but still want to expose the functions and provide events as defined in this ERC. ``` js -function needsAllFeeders() constant returns (bool needsAllFeeders) +function getType() constant returns (uint8 type) ``` ### Events -#### Feed +#### RIP -MUST trigger when the canary got food. +MUST trigger when the canary died. ``` js -event Feed(address feeder) +event RIP() ``` ## Implementation From 26fe3aa246506fb42ae082a31dda50177aef8645 Mon Sep 17 00:00:00 2001 From: Jack Peterson Date: Tue, 19 Dec 2017 12:54:04 -0800 Subject: [PATCH 0344/1085] Removed light client comment --- EIPS/eip-758.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-758.md b/EIPS/eip-758.md index 04424d05c4bda..edb102c9478a8 100644 --- a/EIPS/eip-758.md +++ b/EIPS/eip-758.md @@ -93,7 +93,7 @@ All transactions submitted by the client that were sealed _after_ the initial `e ## Rationale [EIP 658](./eip-658.md) originally proposed adding return data to transaction receipts. However, return data is not charged for (as it is not stored on the blockchain), so adding it to transaction receipts could result in DoS and spam opportunities. Instead, a simple Boolean `status` field was added to transaction receipts. This modified version of EIP 658 was included in the Byzantium hard fork. While the `status` field is useful, applications often need the return data as well. -The primary advantage of using the strategy outlined here is efficiency: no extra data needs to be stored on the blockchain, and minimal extra computational load is imposed on nodes. Since light clients have the current state, they can compute and send return data notifications without contacting a server. Although after-the-fact lookups of the return value would not be supported, this is consistent with the conventional use of return data, which are only accessible to the caller when the function returns, and are not stored for later use. +The primary advantage of using the strategy outlined here is efficiency: no extra data needs to be stored on the blockchain, and minimal extra computational load is imposed on nodes. Although after-the-fact lookups of the return value would not be supported, this is consistent with the conventional use of return data, which are only accessible to the caller when the function returns, and are not stored for later use. ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 7c75cab96408b729a3d0e1dc861a647b63730718 Mon Sep 17 00:00:00 2001 From: ligi Date: Fri, 22 Dec 2017 11:24:31 +0100 Subject: [PATCH 0345/1085] Make requested changes --- EIPS/{eip-canary-standard.md => eip-801.md} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename EIPS/{eip-canary-standard.md => eip-801.md} (90%) diff --git a/EIPS/eip-canary-standard.md b/EIPS/eip-801.md similarity index 90% rename from EIPS/eip-canary-standard.md rename to EIPS/eip-801.md index d0a7dff5dbdc4..0862d6916aeab 100644 --- a/EIPS/eip-canary-standard.md +++ b/EIPS/eip-801.md @@ -55,7 +55,7 @@ Returns the type of the canary: * `5` = Multiple mandatory feeders (as defined in ERC-TBD) * `6` = IOT (as defined in ERC-TBD) -`1` might also be used for a special purpose contract that does not need a special type but still want to expose the functions and provide events as defined in this ERC. +`1` might also be used for a special purpose contract that does not need a special type but still wants to expose the functions and provide events as defined in this ERC. ``` js function getType() constant returns (uint8 type) @@ -65,7 +65,7 @@ function getType() constant returns (uint8 type) #### RIP -MUST trigger when the canary died. +MUST trigger when the contract is called the first time after the canary died. ``` js event RIP() From 857906808f11552adf8d108267067de984ad72fb Mon Sep 17 00:00:00 2001 From: Luke Schoen Date: Mon, 25 Dec 2017 21:58:44 +1100 Subject: [PATCH 0346/1085] Fix broken ConsenSys link in eip-20-token-standard.md Fix broken link to https://github.com/ConsenSys/Tokens/blob/master/contracts/StandardToken.sol, as ConsenSys renamed it to https://github.com/ConsenSys/Tokens/blob/master/contracts/eip20/EIP20.sol and made other associated changes recently in this commit https://github.com/ConsenSys/Tokens/commit/44c3a1e46dc9b5e49c65f20bddad1f7ad9e7e3fa --- EIPS/eip-20-token-standard.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-20-token-standard.md b/EIPS/eip-20-token-standard.md index 05ad25d7d1739..2e38870e290d8 100644 --- a/EIPS/eip-20-token-standard.md +++ b/EIPS/eip-20-token-standard.md @@ -175,7 +175,7 @@ Different implementations have been written by various teams that have different #### Example implementations are available at - https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/StandardToken.sol -- https://github.com/ConsenSys/Tokens/blob/master/contracts/StandardToken.sol +- https://github.com/ConsenSys/Tokens/blob/master/contracts/eip20/EIP20.sol #### Implementation of adding the force to 0 before calling "approve" again: - https://github.com/Giveth/minime/blob/master/contracts/MiniMeToken.sol From a75c904f7f271fb4b8ac06dfe3917a59030835fd Mon Sep 17 00:00:00 2001 From: nicksavers Date: Wed, 3 Jan 2018 19:10:31 +0100 Subject: [PATCH 0347/1085] Link to DAO Fork EIP --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e801fb248f1e0..db375a9a274b3 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | Codename | Aliases | Block number | Date (UTC) | |-------------------------------------- |---------------------------- |----------------|------------| | [Homestead](EIPS/eip-606.md) | | 1,150,000 | 2016-03-14 | -| DAO Fork | | 1,920,000 | 2016-07-20 | +| [DAO Fork](EIPS/eip-779.md) | | 1,920,000 | 2016-07-20 | | [Tangerine Whistle](EIPS/eip-608.md) | Anti-DoS, EIP 150 | 2,463,000 | 2016-10-18 | | [Spurious Dragon](EIPS/eip-607.md) | State-clearing, EIP 158/161 | 2,675,000 | 2016-11-22 | | [Byzantium](EIPS/eip-609.md) | Metropolis: Part 1 | 4,730,000 | 2017-10-16 | From 5e53ebaa1c305bef00a84065895b5b7331d5d80b Mon Sep 17 00:00:00 2001 From: Nick Savers Date: Wed, 3 Jan 2018 19:23:42 +0100 Subject: [PATCH 0348/1085] Update status EIP-141 to Final --- EIPS/eip-141.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-141.md b/EIPS/eip-141.md index f1346380bec92..fed18d6d1dc7a 100644 --- a/EIPS/eip-141.md +++ b/EIPS/eip-141.md @@ -5,7 +5,7 @@ Author: Alex Beregszaszi Type: Standard Track Category: Core - Status: Accepted + Status: Final Created: 2017-02-09 ## Abstract From 3da0abfdcb2c75c1f556fbfddd350a9e51e744af Mon Sep 17 00:00:00 2001 From: Nick Savers Date: Wed, 3 Jan 2018 19:59:34 +0100 Subject: [PATCH 0349/1085] Clarify EIP-190 header with category --- EIPS/eip-190.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-190.md b/EIPS/eip-190.md index 30e592a43746e..7ef046e91e509 100644 --- a/EIPS/eip-190.md +++ b/EIPS/eip-190.md @@ -3,7 +3,8 @@ EIP: 190 Title: Ethereum Smart Contract Packaging Standard Authors: Piper Merriam, Tim Coulter, Denis Erfurt (mhhf), RJ Catalano (VoR0220), Iuri Matias (iurimatias) Status: Final -Type: Standards Track - ERC +Type: Standards Track +Category: ERC Created: 2017-01-10 ``` From db14da1956b857680477c48a85a3d566f69aa2e4 Mon Sep 17 00:00:00 2001 From: Nick Savers Date: Wed, 3 Jan 2018 20:30:47 +0100 Subject: [PATCH 0350/1085] Update status EIP-1 according to own specification --- EIPS/eip-1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index 77b7f7a77f71b..0e5569b89e128 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -1,6 +1,6 @@ EIP: 1 Title: EIP Purpose and Guidelines - Status: Draft + Status: Active Type: Meta Author: Martin Becze , Hudson Jameson Created: 2015-10-27, 2017-02-01 From a7436f8cef80e96583c18f474d51aa09102f2c43 Mon Sep 17 00:00:00 2001 From: Nick Savers Date: Wed, 3 Jan 2018 20:45:38 +0100 Subject: [PATCH 0351/1085] List all non-final EIPs in README table --- README.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c461f0998538e..de15dcfab3843 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,27 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP * **Final** - an EIP that has been adopted in a previous hard fork (for Core/Consensus layer EIPs). * **Deferred** - an EIP that is not being considered for immediate adoption. May be reconsidered in the future for a subsequent hard fork. -# Deferred EIPs (adoption postponed until the Constantinople Metropolis hard fork) +# Non-final EIPs +| Number | Title | Author | Layer | Status | +| -------------------------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------ | ---------- | -------- | +| [3](EIPS/eip-3.mediawiki) | Addition of CALLDEPTH opcode | Martin Holst Swende | Core | Draft | +| [4](EIPS/eip-4.mediawiki) | EIP Classification | Eric Lombrozo | Meta | Draft | +| [5](EIPS/eip-5.md) | Gas Usage for `RETURN` and `CALL*` | Christian Reitwiessner | Core | Draft | +| [101](EIPS/eip-101.md) | Serenity Currency and Crypto Abstraction | Vitalik Buterin | | Active | +| [234](EIPS/eip-234.md) | Add `blockHash` to JSON-RPC filter options | Micah Zoltu | Interface | Draft | +| [615](EIPS/eip-615.md) | Subroutines and Static Jumps for the EVM | Greg Colvin | Core | Draft | +| [616](EIPS/eip-616.md) | SIMD Operations for the EVM | Greg Colvin | Core | Draft | +| [758](EIPS/eip-758.md) | Subscriptions and filters for transaction return data | Jack Peterson | Interface | Draft | +| [801](EIPS/eip-801.md) | ERC-801 Canary Standard | ligi | Interface | Draft | + +# Deferred EIPs | Number | Title | Author | Layer | Status | | -------------------------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------ | ---------- | -------- | | [86](https://github.com/ethereum/EIPs/pull/208) | Abstraction of transaction origin and signature | Vitalik Buterin | Core | Deferred | | [96](https://github.com/ethereum/EIPs/pull/210) | Blockhash refactoring | Vitalik Buterin | Core | Deferred | | [145](EIPS/eip-145.md) | Bitwise shifting instructions in EVM | Alex Beregszaszi, Paweł Bylica | Core | Deferred | +| [145](EIPS/eip-145.md) | Bitwise shifting instructions in EVM | Alex Beregszaszi, Paweł Bylica | Core | Deferred | +| [158](EIPS/eip-158.md) | State clearing | Vitalik Buterin | Core | Superseded | # Finalized EIPs (standards that have been adopted) | Number | Title | Author | Layer | Status | From 5696e36a648d2a0472e4d9c9f57ecdabf42ca15d Mon Sep 17 00:00:00 2001 From: nicksavers Date: Wed, 3 Jan 2018 20:57:05 +0100 Subject: [PATCH 0352/1085] Move EIP-158 to non-final table --- README.md | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index de15dcfab3843..d6671c4728309 100644 --- a/README.md +++ b/README.md @@ -11,17 +11,18 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP * **Deferred** - an EIP that is not being considered for immediate adoption. May be reconsidered in the future for a subsequent hard fork. # Non-final EIPs -| Number | Title | Author | Layer | Status | -| -------------------------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------ | ---------- | -------- | -| [3](EIPS/eip-3.mediawiki) | Addition of CALLDEPTH opcode | Martin Holst Swende | Core | Draft | -| [4](EIPS/eip-4.mediawiki) | EIP Classification | Eric Lombrozo | Meta | Draft | -| [5](EIPS/eip-5.md) | Gas Usage for `RETURN` and `CALL*` | Christian Reitwiessner | Core | Draft | -| [101](EIPS/eip-101.md) | Serenity Currency and Crypto Abstraction | Vitalik Buterin | | Active | -| [234](EIPS/eip-234.md) | Add `blockHash` to JSON-RPC filter options | Micah Zoltu | Interface | Draft | -| [615](EIPS/eip-615.md) | Subroutines and Static Jumps for the EVM | Greg Colvin | Core | Draft | -| [616](EIPS/eip-616.md) | SIMD Operations for the EVM | Greg Colvin | Core | Draft | -| [758](EIPS/eip-758.md) | Subscriptions and filters for transaction return data | Jack Peterson | Interface | Draft | -| [801](EIPS/eip-801.md) | ERC-801 Canary Standard | ligi | Interface | Draft | +| Number | Title | Author | Layer | Status | +| ------------------------- | ------------------------------------------------------- | ----------------------------- | --------- | ---------- | +| [3](EIPS/eip-3.mediawiki) | Addition of CALLDEPTH opcode | Martin Holst Swende | Core | Draft | +| [4](EIPS/eip-4.mediawiki) | EIP Classification | Eric Lombrozo | Meta | Draft | +| [5](EIPS/eip-5.md) | Gas Usage for `RETURN` and `CALL*` | Christian Reitwiessner | Core | Draft | +| [101](EIPS/eip-101.md) | Serenity Currency and Crypto Abstraction | Vitalik Buterin | | Active | +| [158](EIPS/eip-158.md) | State clearing | Vitalik Buterin | Core | Superseded | +| [234](EIPS/eip-234.md) | Add `blockHash` to JSON-RPC filter options | Micah Zoltu | Interface | Draft | +| [615](EIPS/eip-615.md) | Subroutines and Static Jumps for the EVM | Greg Colvin | Core | Draft | +| [616](EIPS/eip-616.md) | SIMD Operations for the EVM | Greg Colvin | Core | Draft | +| [758](EIPS/eip-758.md) | Subscriptions and filters for transaction return data | Jack Peterson | Interface | Draft | +| [801](EIPS/eip-801.md) | ERC-801 Canary Standard | ligi | Interface | Draft | # Deferred EIPs | Number | Title | Author | Layer | Status | @@ -29,8 +30,6 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [86](https://github.com/ethereum/EIPs/pull/208) | Abstraction of transaction origin and signature | Vitalik Buterin | Core | Deferred | | [96](https://github.com/ethereum/EIPs/pull/210) | Blockhash refactoring | Vitalik Buterin | Core | Deferred | | [145](EIPS/eip-145.md) | Bitwise shifting instructions in EVM | Alex Beregszaszi, Paweł Bylica | Core | Deferred | -| [145](EIPS/eip-145.md) | Bitwise shifting instructions in EVM | Alex Beregszaszi, Paweł Bylica | Core | Deferred | -| [158](EIPS/eip-158.md) | State clearing | Vitalik Buterin | Core | Superseded | # Finalized EIPs (standards that have been adopted) | Number | Title | Author | Layer | Status | @@ -40,7 +39,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Core | Final | | [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Networking | Final | | [20](EIPS/eip-20-token-standard.md) | ERC-20 Token Standard | Fabian Vogelsteller, Vitalik Buterin | ERC | Final | -| [55](EIPS/eip-55.md) | ERC-55 Mixed-case checksum address encoding | Vitalik Buterin | ERC | Final | +| [55](EIPS/eip-55.md) | ERC-55 Mixed-case checksum address encoding | Vitalik Buterin | ERC | Final | | [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Core | Final | | [137](EIPS/eip-137.md) | Ethereum Domain Name Service - Specification | Nick Johnson | ERC | Final | | [140](https://github.com/ethereum/EIPs/pull/206) | REVERT instruction in the Ethereum Virtual Machine | Alex Beregszaszi, Nikolai Mushegian | Core | Final | From d18175ff0973202364aa5d0228e121aeb490507e Mon Sep 17 00:00:00 2001 From: Nick Savers Date: Wed, 3 Jan 2018 21:06:17 +0100 Subject: [PATCH 0353/1085] Fix link to EIP-616 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d6671c4728309..2079cd3a60065 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [158](EIPS/eip-158.md) | State clearing | Vitalik Buterin | Core | Superseded | | [234](EIPS/eip-234.md) | Add `blockHash` to JSON-RPC filter options | Micah Zoltu | Interface | Draft | | [615](EIPS/eip-615.md) | Subroutines and Static Jumps for the EVM | Greg Colvin | Core | Draft | -| [616](EIPS/eip-616.md) | SIMD Operations for the EVM | Greg Colvin | Core | Draft | +| [616](EIPS/eip-EIPS/eip-616.md) | SIMD Operations for the EVM | Greg Colvin | Core | Draft | | [758](EIPS/eip-758.md) | Subscriptions and filters for transaction return data | Jack Peterson | Interface | Draft | | [801](EIPS/eip-801.md) | ERC-801 Canary Standard | ligi | Interface | Draft | From 63fb672175faccbbf295d94a13015619dbe914e7 Mon Sep 17 00:00:00 2001 From: nicksavers Date: Wed, 3 Jan 2018 22:33:53 +0100 Subject: [PATCH 0354/1085] Update EIP-162 as Standards Track with category ERC --- EIPS/eip-162.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-162.md b/EIPS/eip-162.md index e0d46e9580bfc..ec6fd158fddc8 100644 --- a/EIPS/eip-162.md +++ b/EIPS/eip-162.md @@ -3,7 +3,8 @@ EIP: 162 Title: Initial ENS Hash Registrar Author: Maurelian and Nick Johnson Status: Final -Type: Informational +Type: Standards Track +Category: ERC Created: 2016-10-25 ``` From b603cdc9e65f89bc03c9da65380143a0616a25a9 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Tue, 9 Jan 2018 17:50:27 +1100 Subject: [PATCH 0355/1085] Add links to issues 90 and 114. --- EIPS/eip-150.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-150.md b/EIPS/eip-150.md index 012f76e3b2705..ebc5effe855af 100644 --- a/EIPS/eip-150.md +++ b/EIPS/eip-150.md @@ -21,7 +21,7 @@ If `block.number >= FORK_BLKNUM`, then: - If SELFDESTRUCT hits a newly created account, it triggers an additional gas cost of 25000 (similar to CALLs) - Increase the recommended gas limit target to 5.5 million - Define "all but one 64th" of `N` as `N - floor(N / 64)` -- If a call asks for more gas than the maximum allowed amount (ie. total amount of gas remaining in the parent after subtracting the gas cost of the call and memory expansion), do not return an OOG error; instead, if a call asks for more gas than all but one 64th of the maximum allowed amount, call with all but one 64th of the maximum allowed amount of gas (this is equivalent to a version of #90 plus #114). CREATE only provides all but one 64th of the parent gas to the child call. +- If a call asks for more gas than the maximum allowed amount (ie. total amount of gas remaining in the parent after subtracting the gas cost of the call and memory expansion), do not return an OOG error; instead, if a call asks for more gas than all but one 64th of the maximum allowed amount, call with all but one 64th of the maximum allowed amount of gas (this is equivalent to a version of [#90](https://github.com/ethereum/EIPs/issues/90) plus [#114](https://github.com/ethereum/EIPs/issues/114)). CREATE only provides all but one 64th of the parent gas to the child call. That is, substitute: From fbdfb8673287e710331c1d1c31f5f169d1ab4ee8 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Wed, 10 Jan 2018 21:23:41 +1100 Subject: [PATCH 0356/1085] Modify links based on feedback --- EIPS/eip-150.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-150.md b/EIPS/eip-150.md index ebc5effe855af..4b8af5a1966b0 100644 --- a/EIPS/eip-150.md +++ b/EIPS/eip-150.md @@ -21,7 +21,7 @@ If `block.number >= FORK_BLKNUM`, then: - If SELFDESTRUCT hits a newly created account, it triggers an additional gas cost of 25000 (similar to CALLs) - Increase the recommended gas limit target to 5.5 million - Define "all but one 64th" of `N` as `N - floor(N / 64)` -- If a call asks for more gas than the maximum allowed amount (ie. total amount of gas remaining in the parent after subtracting the gas cost of the call and memory expansion), do not return an OOG error; instead, if a call asks for more gas than all but one 64th of the maximum allowed amount, call with all but one 64th of the maximum allowed amount of gas (this is equivalent to a version of [#90](https://github.com/ethereum/EIPs/issues/90) plus [#114](https://github.com/ethereum/EIPs/issues/114)). CREATE only provides all but one 64th of the parent gas to the child call. +- If a call asks for more gas than the maximum allowed amount (ie. total amount of gas remaining in the parent after subtracting the gas cost of the call and memory expansion), do not return an OOG error; instead, if a call asks for more gas than all but one 64th of the maximum allowed amount, call with all but one 64th of the maximum allowed amount of gas (this is equivalent to a version of [EIP-90](ethereum/EIPs/issues/90) plus [EIP-114](ethereum/EIPs/issues/114)). CREATE only provides all but one 64th of the parent gas to the child call. That is, substitute: From a8fb2597d100ace63d24a46b1c076dc2f400d8d1 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Wed, 10 Jan 2018 21:27:44 +1100 Subject: [PATCH 0357/1085] Further modifications to links, more in line with Wikipedia style --- EIPS/eip-150.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-150.md b/EIPS/eip-150.md index 4b8af5a1966b0..72ab1efd2418d 100644 --- a/EIPS/eip-150.md +++ b/EIPS/eip-150.md @@ -21,7 +21,7 @@ If `block.number >= FORK_BLKNUM`, then: - If SELFDESTRUCT hits a newly created account, it triggers an additional gas cost of 25000 (similar to CALLs) - Increase the recommended gas limit target to 5.5 million - Define "all but one 64th" of `N` as `N - floor(N / 64)` -- If a call asks for more gas than the maximum allowed amount (ie. total amount of gas remaining in the parent after subtracting the gas cost of the call and memory expansion), do not return an OOG error; instead, if a call asks for more gas than all but one 64th of the maximum allowed amount, call with all but one 64th of the maximum allowed amount of gas (this is equivalent to a version of [EIP-90](ethereum/EIPs/issues/90) plus [EIP-114](ethereum/EIPs/issues/114)). CREATE only provides all but one 64th of the parent gas to the child call. +- If a call asks for more gas than the maximum allowed amount (ie. total amount of gas remaining in the parent after subtracting the gas cost of the call and memory expansion), do not return an OOG error; instead, if a call asks for more gas than all but one 64th of the maximum allowed amount, call with all but one 64th of the maximum allowed amount of gas (this is equivalent to a version of EIP-90[1](ethereum/EIPs/issues/90) plus EIP-114[2](ethereum/EIPs/issues/114)). CREATE only provides all but one 64th of the parent gas to the child call. That is, substitute: From b926c9020cfec6cc811b375f9a68af861c3c315e Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Wed, 10 Jan 2018 21:32:57 +1100 Subject: [PATCH 0358/1085] Modify links, references sections --- EIPS/eip-150.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-150.md b/EIPS/eip-150.md index 72ab1efd2418d..8231cf81e9859 100644 --- a/EIPS/eip-150.md +++ b/EIPS/eip-150.md @@ -21,7 +21,7 @@ If `block.number >= FORK_BLKNUM`, then: - If SELFDESTRUCT hits a newly created account, it triggers an additional gas cost of 25000 (similar to CALLs) - Increase the recommended gas limit target to 5.5 million - Define "all but one 64th" of `N` as `N - floor(N / 64)` -- If a call asks for more gas than the maximum allowed amount (ie. total amount of gas remaining in the parent after subtracting the gas cost of the call and memory expansion), do not return an OOG error; instead, if a call asks for more gas than all but one 64th of the maximum allowed amount, call with all but one 64th of the maximum allowed amount of gas (this is equivalent to a version of EIP-90[1](ethereum/EIPs/issues/90) plus EIP-114[2](ethereum/EIPs/issues/114)). CREATE only provides all but one 64th of the parent gas to the child call. +- If a call asks for more gas than the maximum allowed amount (ie. total amount of gas remaining in the parent after subtracting the gas cost of the call and memory expansion), do not return an OOG error; instead, if a call asks for more gas than all but one 64th of the maximum allowed amount, call with all but one 64th of the maximum allowed amount of gas (this is equivalent to a version of EIP-90[1](https://github.com/ethereum/EIPs/issues/90) plus EIP-114[2](https://github.com/ethereum/EIPs/issues/114)). CREATE only provides all but one 64th of the parent gas to the child call. That is, substitute: @@ -57,3 +57,8 @@ This EIP aims to be simple, and adds a flat penalty of 300 gas on top of the cos The EIP 90 gas mechanic is introduced because without it, all current contracts that make calls would stop working as they use an expression like `msg.gas - 40` to determine how much gas to make a call with, relying on the gas cost of calls being 40. Additionally, EIP 114 is introduced because, given that we are making the cost of a call higher and less predictable, we have an opportunity to do it at no extra cost to currently available guarantees, and so we also achieve the benefit of replacing the call stack depth limit with a "softer" gas-based restriction, thereby eliminating call stack depth attacks as a class of attack that contract developers have to worry about and hence increasing contract programming safety. Note that with the given parameters, the de-facto maximum call stack depth is limited to ~340 (down from ~1024), mitigating the harm caused by any further potential quadratic-complexity DoS attacks that rely on calls. The gas limit increase is recommended so as to preserve the de-facto transactions-per-second processing capability of the system for average contracts. + +## References + +1. EIP-90, https://github.com/ethereum/EIPs/issues/90 +2. EIP-114, https://github.com/ethereum/EIPs/issues/114 From e9f195a7e766c904cee83199ed07dfcfdccd0a1b Mon Sep 17 00:00:00 2001 From: Fabian Vogelsteller Date: Fri, 12 Jan 2018 09:09:09 +0100 Subject: [PATCH 0359/1085] added historical links --- EIPS/eip-20-token-standard.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/EIPS/eip-20-token-standard.md b/EIPS/eip-20-token-standard.md index 2e38870e290d8..0faf6cf424cf6 100644 --- a/EIPS/eip-20-token-standard.md +++ b/EIPS/eip-20-token-standard.md @@ -180,5 +180,17 @@ Different implementations have been written by various teams that have different #### Implementation of adding the force to 0 before calling "approve" again: - https://github.com/Giveth/minime/blob/master/contracts/MiniMeToken.sol + + +## History + +Historical links releated to this standard: + +- Orginial proposal from Vitalik Buterin: https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs/499c882f3ec123537fc2fccd57eaa29e6032fe4a +- Reddit discussion: https://www.reddit.com/r/ethereum/comments/3n8fkn/lets_talk_about_the_coin_standard/ +- Original Issue #20: https://github.com/ethereum/EIPs/issues/20 + + + ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From f6233468d97d2e261fe134971666e6772931ee72 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Sun, 14 Jan 2018 21:21:58 -0500 Subject: [PATCH 0360/1085] Delete old process image That's why we have git history. --- EIPS/eip-1/old_process.png | Bin 20813 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 EIPS/eip-1/old_process.png diff --git a/EIPS/eip-1/old_process.png b/EIPS/eip-1/old_process.png deleted file mode 100644 index 51eb2b25826c3f97b38a4fa17425a86d27c0d962..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20813 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 From b5444e4c94d0d402ae6b4d1de42652a861e36f39 Mon Sep 17 00:00:00 2001 From: "Daniel A. Nagy" Date: Mon, 15 Jan 2018 15:05:27 +0100 Subject: [PATCH 0361/1085] Update eip-681.md [ERC] default chain_id behavior changed for backwards compatibility. --- EIPS/eip-681.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-681.md b/EIPS/eip-681.md index 26b17bb3754e3..6ba40af1b513b 100644 --- a/EIPS/eip-681.md +++ b/EIPS/eip-681.md @@ -56,7 +56,7 @@ For the syntax of ENS_NAME, please consult ERC #137 defining Ethereum Name Servi `target_address` is mandatory and denotes either the beneficiary of native token payment (see below) or the contract address with which the user is asked to interact. -`chain_id` is optional and contains the decimal chain ID, such that transactions on various test- and private networks can be requested. If no `chain_id` is present, the main network (1) is assumed. +`chain_id` is optional and contains the decimal chain ID, such that transactions on various test- and private networks can be requested. If no `chain_id` is present, the client's current network setting remains effective. If `function_name` is missing, then the URL is requesting payment in the native token of the blockchain, which is Ether in our case. The amount is specified in `value` parameter, in the atomic unit (i.e. Wei). The use of scientific notation is strongly encouraged. For example, requesting 2.014 ETH to address `0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359` would look as follows: [ethereum:0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359?value=2.014e18](ethereum:0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359?value=2.014e18) From f4ba09d033f7ea3f08b96922be0f8e1ae90971f9 Mon Sep 17 00:00:00 2001 From: "Daniel A. Nagy" Date: Mon, 15 Jan 2018 15:14:16 +0100 Subject: [PATCH 0362/1085] [EIP] Optional pay- prefix. If no prefix exists, pay- is assumed. --- EIPS/eip-681.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-681.md b/EIPS/eip-681.md index 6ba40af1b513b..1b1f27c3390b5 100644 --- a/EIPS/eip-681.md +++ b/EIPS/eip-681.md @@ -26,7 +26,7 @@ This specification supersedes ERC #67, which is a URL format for representing ar ### Syntax Payment request URLs contain "ethereum" in their schema (protocol) part and are constructed as follows: - request = "ethereum" ":" target_address [ "@" chain_id ] [ "/" function_name ] [ "?" parameters ] + request = "ethereum" ":" [ "pay-" ]target_address [ "@" chain_id ] [ "/" function_name ] [ "?" parameters ] target_address = ethereum_address chain_id = 1*DIGIT function_name = STRING From a870e8b88b09c835c9b6640f0c599344e3bb85db Mon Sep 17 00:00:00 2001 From: ligi Date: Mon, 15 Jan 2018 15:59:50 +0100 Subject: [PATCH 0363/1085] Add URL Format ERC --- EIPS/eip-831.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 EIPS/eip-831.md diff --git a/EIPS/eip-831.md b/EIPS/eip-831.md new file mode 100644 index 0000000000000..a1f30343e18a2 --- /dev/null +++ b/EIPS/eip-831.md @@ -0,0 +1,42 @@ +## Preamble + + EIP: 831 + Title: URL Format for Ethereum + Author: ligi + Type: Standard Track + Category: ERC + Status: Draft + Replaces: 67 + Created: 2018-01-15 + +## Simple Summary + +A standard way of creating Ethereum URLs for various use-cases. + +## Abstract + +URLs embedded in QR-codes, hyperlinks in web-pages, emails or chat messages provide for robust cross-application signaling between very loosely coupled applications. A standardized URL format allows for instant invocation of the user's preferred wallet application. + +## Motivation + +The need for this ERC emerged when refining ERC-681. We need a container ERC that does not carry the weight of the use-cases and just serves the container for them. + +## Specification + +### Syntax + +Ethereum URLs contain "ethereum" in their schema (protocol) part and are constructed as follows: + + request = "ethereum" ":" [ prefix "-" ] payload + prefix = STRING + payload = STRING + +### Semantics + +`prefix` is optional and defines the use-case for this URL. If no prefix is given "pay-" is assumed to be concise and ensure backward compatibility to ERC-67 + +`payload` is mandatory and the content depends on the prefix. Structuring of the content is defined in the ERC for the specific use-case and not in the scope of this document. One example is ERC-681 for the pay- prefix. + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From f156733da0fb8d99eefe34aed70ef62b2c39d74a Mon Sep 17 00:00:00 2001 From: ligi Date: Tue, 16 Jan 2018 15:41:50 +0100 Subject: [PATCH 0364/1085] Add period --- EIPS/eip-831.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-831.md b/EIPS/eip-831.md index a1f30343e18a2..2a01ab9f43d7f 100644 --- a/EIPS/eip-831.md +++ b/EIPS/eip-831.md @@ -33,7 +33,7 @@ Ethereum URLs contain "ethereum" in their schema (protocol) part and are constru ### Semantics -`prefix` is optional and defines the use-case for this URL. If no prefix is given "pay-" is assumed to be concise and ensure backward compatibility to ERC-67 +`prefix` is optional and defines the use-case for this URL. If no prefix is given "pay-" is assumed to be concise and ensure backward compatibility to ERC-67. `payload` is mandatory and the content depends on the prefix. Structuring of the content is defined in the ERC for the specific use-case and not in the scope of this document. One example is ERC-681 for the pay- prefix. From e76ac41a5dff020cb443a1bd8fdabd9cb548fba7 Mon Sep 17 00:00:00 2001 From: Micah Zoltu Date: Tue, 16 Jan 2018 10:56:10 -0800 Subject: [PATCH 0365/1085] Adds fork block number. Acquired from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md --- EIPS/eip-155.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-155.md b/EIPS/eip-155.md index 869a842e16004..9e18730b0a95f 100644 --- a/EIPS/eip-155.md +++ b/EIPS/eip-155.md @@ -10,7 +10,7 @@ Created: 2016-10-14 ``` ### Parameters -- `FORK_BLKNUM`: TBA +- `FORK_BLKNUM`: 2,675,000 - `CHAIN_ID`: 1 ### Specification From 519b7018fcb53104dc5d94312e86b6b512f97e4b Mon Sep 17 00:00:00 2001 From: William Entriken Date: Tue, 16 Jan 2018 00:14:59 -0500 Subject: [PATCH 0366/1085] Add EIP-1 to the Finalized EIPs list --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 70b75d13a72b9..99ae86f256851 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP # Finalized EIPs (standards that have been adopted) | Number | Title | Author | Layer | Status | | -------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------| ---------- | -------- | +| [1](EIPS/eip-1.md) | EIP Purpose and Guidelines | Martin Becze, Hudson Jameson | Meta | Final | | [2](EIPS/eip-2.md) | Homestead Hard-fork Changes | Vitalik Buterin | Core | Final | | [6](EIPS/eip-6.md) | Renaming Suicide Opcode | Hudson Jameson | Interface | Final | | [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Core | Final | From 24a128788b9b1de30a962cfd50015a8cb133ff6e Mon Sep 17 00:00:00 2001 From: Jack Peterson Date: Tue, 9 Jan 2018 11:33:29 -0800 Subject: [PATCH 0367/1085] Updated EIP 140 and 658 titles --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 99ae86f256851..a7f1fdc773996 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [55](EIPS/eip-55.md) | ERC-55 Mixed-case checksum address encoding | Vitalik Buterin | ERC | Final | | [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Core | Final | | [137](EIPS/eip-137.md) | Ethereum Domain Name Service - Specification | Nick Johnson | ERC | Final | -| [140](https://github.com/ethereum/EIPs/pull/206) | REVERT instruction in the Ethereum Virtual Machine | Alex Beregszaszi, Nikolai Mushegian | Core | Final | +| [140](https://github.com/ethereum/EIPs/pull/206) | REVERT instruction | Alex Beregszaszi, Nikolai Mushegian | Core | Final | | [141](EIPS/eip-141.md) | Designated invalid EVM instruction | Alex Beregszaszi | Core | Final | | [150](EIPS/eip-150.md) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Core | Final | | [155](EIPS/eip-155.md) | Simple replay attack protection | Vitalik Buterin | Core | Final | @@ -59,7 +59,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [211](https://github.com/ethereum/EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner | Core | Final | | [214](https://github.com/ethereum/EIPs/pull/214) | New opcode STATICCALL | Vitalik Buterin, Christian Reitwiessner | Core | Final | | [649](https://github.com/ethereum/EIPs/pull/669) | Metropolis Difficulty Bomb Delay and Block Reward Reduction | Afri Schoedon, Vitalik Buterin | Core | Final | -| [658](https://github.com/ethereum/EIPs/pull/658) | Embedding transaction return data in receipts | Nick Johnson | Core | Final | +| [658](https://github.com/ethereum/EIPs/pull/658) | Embedding transaction status code in receipts | Nick Johnson | Core | Final | | [706](EIPS/eip-706.md) | DEVp2p snappy compression | Péter Szilágyi | Networking | Final | # Past Hard Forks From d90db8361e6f3a12c03dee4d24f4c22092ebe72d Mon Sep 17 00:00:00 2001 From: ligi Date: Mon, 22 Jan 2018 11:34:12 +0100 Subject: [PATCH 0368/1085] Remove "Replaces: 67" and move to Rationale that replaces Motivation ERC-67 was used but never merged - so there can be no replacemenmt Using Rationale as it is a better fit and leaving out optional Motivation --- EIPS/eip-831.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/EIPS/eip-831.md b/EIPS/eip-831.md index 2a01ab9f43d7f..82800d8d49552 100644 --- a/EIPS/eip-831.md +++ b/EIPS/eip-831.md @@ -6,7 +6,6 @@ Type: Standard Track Category: ERC Status: Draft - Replaces: 67 Created: 2018-01-15 ## Simple Summary @@ -17,10 +16,6 @@ A standard way of creating Ethereum URLs for various use-cases. URLs embedded in QR-codes, hyperlinks in web-pages, emails or chat messages provide for robust cross-application signaling between very loosely coupled applications. A standardized URL format allows for instant invocation of the user's preferred wallet application. -## Motivation - -The need for this ERC emerged when refining ERC-681. We need a container ERC that does not carry the weight of the use-cases and just serves the container for them. - ## Specification ### Syntax @@ -37,6 +32,12 @@ Ethereum URLs contain "ethereum" in their schema (protocol) part and are constru `payload` is mandatory and the content depends on the prefix. Structuring of the content is defined in the ERC for the specific use-case and not in the scope of this document. One example is ERC-681 for the pay- prefix. + +## Rationale + +The need for this ERC emerged when refining ERC-681. We need a container that does not carry the weight of the use-cases. ERC-67 was the first standard defining Ethereum-URLs - this ERC tries to keep backward compatibibility and not break existing flows. This means ERC-67 URLs should still be valid and readable. But if the prefix feature is used - ERC-67 parsers might break. + + ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 359f34523d9818d7846968b0b4d1cb19b55818c0 Mon Sep 17 00:00:00 2001 From: ligi Date: Tue, 23 Jan 2018 17:03:08 +0100 Subject: [PATCH 0369/1085] Fix a problem with separating prefixes from payload --- EIPS/eip-831.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-831.md b/EIPS/eip-831.md index 82800d8d49552..da4a938cc91ae 100644 --- a/EIPS/eip-831.md +++ b/EIPS/eip-831.md @@ -28,14 +28,14 @@ Ethereum URLs contain "ethereum" in their schema (protocol) part and are constru ### Semantics -`prefix` is optional and defines the use-case for this URL. If no prefix is given "pay-" is assumed to be concise and ensure backward compatibility to ERC-67. +`prefix` is optional and defines the use-case for this URL. If no prefix is given: "pay-" is assumed to be concise and ensure backward compatibility to ERC-67. When the prefix is omitted - the payload must start with `0x`. Also prefixes must not start with `0x`. So starting with `0x` can be used as a clear signal that there is no prefix. `payload` is mandatory and the content depends on the prefix. Structuring of the content is defined in the ERC for the specific use-case and not in the scope of this document. One example is ERC-681 for the pay- prefix. ## Rationale -The need for this ERC emerged when refining ERC-681. We need a container that does not carry the weight of the use-cases. ERC-67 was the first standard defining Ethereum-URLs - this ERC tries to keep backward compatibibility and not break existing flows. This means ERC-67 URLs should still be valid and readable. But if the prefix feature is used - ERC-67 parsers might break. +The need for this ERC emerged when refining ERC-681. We need a container that does not carry the weight of the use-cases. ERC-67 was the first attempt on defining Ethereum-URLs - this ERC tries to keep backward compatibibility and not break existing flows. This means ERC-67 URLs should still be valid and readable. But if the prefix feature is used - ERC-67 parsers might break. ## Copyright From 25eaa57d524e4039056418866c1ee694028d3421 Mon Sep 17 00:00:00 2001 From: ligi Date: Tue, 23 Jan 2018 17:43:43 +0100 Subject: [PATCH 0370/1085] Improve rationale --- EIPS/eip-831.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-831.md b/EIPS/eip-831.md index da4a938cc91ae..0cf8d332b76db 100644 --- a/EIPS/eip-831.md +++ b/EIPS/eip-831.md @@ -35,7 +35,7 @@ Ethereum URLs contain "ethereum" in their schema (protocol) part and are constru ## Rationale -The need for this ERC emerged when refining ERC-681. We need a container that does not carry the weight of the use-cases. ERC-67 was the first attempt on defining Ethereum-URLs - this ERC tries to keep backward compatibibility and not break existing flows. This means ERC-67 URLs should still be valid and readable. But if the prefix feature is used - ERC-67 parsers might break. +The need for this ERC emerged when refining ERC-681. We need a container that does not carry the weight of the use-cases. ERC-67 was the first attempt on defining Ethereum-URLs - this ERC tries to keep backward compatibility and not break existing things. This means ERC-67 URLs should still be valid and readable. Only if the prefix feature is used - ERC-67 parsers might break. No way was seen to avoid this and innovate on the same time. This is also the reason this open prefix approach was chosen to being able to adopt to future use-cases and not block the whole "ethereum:" scheme for a limited set of use-cases that existed at the time of writing this. ## Copyright From ea3a20014293ae27a5faad44afac1dde9c16e409 Mon Sep 17 00:00:00 2001 From: Konstantin Date: Tue, 23 Jan 2018 23:48:16 +0000 Subject: [PATCH 0371/1085] Update eip-20-token-standard.md --- EIPS/eip-20-token-standard.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-20-token-standard.md b/EIPS/eip-20-token-standard.md index 0faf6cf424cf6..01cd434d8100d 100644 --- a/EIPS/eip-20-token-standard.md +++ b/EIPS/eip-20-token-standard.md @@ -174,7 +174,7 @@ There are already plenty of ERC20-compliant tokens deployed on the Ethereum netw Different implementations have been written by various teams that have different trade-offs: from gas saving to improved security. #### Example implementations are available at -- https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/StandardToken.sol +- https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/StandardToken.sol - https://github.com/ConsenSys/Tokens/blob/master/contracts/eip20/EIP20.sol #### Implementation of adding the force to 0 before calling "approve" again: From 31ed49ea42bca57407395dd6ddaadbaaf38ac461 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 24 Jan 2018 01:06:45 -0500 Subject: [PATCH 0372/1085] EIP-721 Deed Standard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # TO DO: - [ ] Get to status accepted - [ ] Write test cases - [ ] Write implementation (on OpenZeppelin?) - [ ] Get to ​status final --- EIPS/eip-721.md | 312 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 312 insertions(+) create mode 100644 EIPS/eip-721.md diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md new file mode 100644 index 0000000000000..c1e2ada6d04f1 --- /dev/null +++ b/EIPS/eip-721.md @@ -0,0 +1,312 @@ +## Preamble + +``` +EIP: +Title: ERC-721 Deed Standard +Author: William Entriken , Dieter Shirley +Type: Standard +Category ERC +Status: Draft +Created: 2018-01-31 +``` + +## Simple Summary + +A standard interface for deeds, also known as non-fungible tokens. + +## Abstract + +**This a standard interface for smart contracts to handle deed ownership.** Deeds can represent ownership of physical property, like houses, or digital property, like unique pictures of kittens. In general, all houses are distinct and no two kittens are alike. Therefore you must track each deed separately; it is insufficient to simply count the deeds you own. + +The scope of this interface includes **interrogating the smart contract about deed ownership**. It also **allows deed owners to transfer assets**. The authors considered uses cases of individual deed ownership as well as custody by third party brokers/wallets/auctioneers. + +## Motivation + +A standard interface allows wallet/broker/auctioneer applications to work with any deed on Ethereum. This contract considers simple deed contracts as well as contract that track large number of deeds. Additional applications are discussed below. + +This standard is inspired by [the ERC-20 token standard](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) and builds on two years of experience since EIP-20 was created. EIP-20 is insufficient for tracking deed ownership because each deed is distinct (non-fungible) whereas each token is identical (fungible). + +Differences between this standard and EIP-20 are examined below. + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt). + +The **baseline specification** is REQUIRED for all ERC-721 implementations (subject to "caveats", below). + +```solidity +pragma solidity ^0.4.19; + +/// @title Interface for contracts conforming to ERC-721: Deed Standard +/// @author William Entriken (https://phor.net), et. al. +/// @dev Specification at https://github.com/ethereum/eips/XXXFinalUrlXXX +interface ERC721 { + + // COMPLIANCE WITH ERC-165 (DRAFT) ///////////////////////////////////////// + + /// @dev ERC-165 (draft) interface signature for itself + // bytes4 internal constant INTERFACE_SIGNATURE_ERC165 = // 0x01ffc9a7 + // bytes4(keccak256('supportsInterface(bytes4)')); + + /// @dev ERC-165 (draft) interface signature for ERC721 + // bytes4 internal constant INTERFACE_SIGNATURE_ERC721 = // 0xe55729f5 + // bytes4(keccak256('ownerOf(uint256)')) ^ + // bytes4(keccak256('countOfDeeds()')) ^ + // bytes4(keccak256('countOfDeedsByOwner(address)')) ^ + // bytes4(keccak256('deedOfOwnerByIndex(uint256)')) ^ + // bytes4(keccak256('approve(address,uint256)')) ^ + // bytes4(keccak256('takeOwnership(uint256)')); + + /// @notice Query a contract to see if it supports a certain interface + /// @dev Returns `true` the interface is supported and `false` otherwise, + /// returns `true` for INTERFACE_SIGNATURE_ERC165 and + /// INTERFACE_SIGNATURE_ERC721, see ERC-165 for other interface signatures. + function supportsInterface(bytes4 _interfaceID) external pure returns (bool); + + // PUBLIC QUERY FUNCTIONS ////////////////////////////////////////////////// + + /// @notice Find the owner of a deed + /// @param _deedId The identifier for a deed we are inspecting + /// @dev Deeds assigned to zero address are considered destroyed, and + /// queries about them do throw. + /// @return The non-zero address of the owner of deed `_deedId`, or `throw` + /// if deed `_deedId` is not tracked by this contract + function ownerOf(uint256 _deedId) external view returns (address _owner); + + /// @notice Count deeds tracked by this contract + /// @return A count of the deeds tracked by this contract, where each one of + /// them has an assigned and queryable owner + function countOfDeeds() external view returns (uint256 _count); + + /// @notice Count all deeds assigned to an owner + /// @dev Throws if `_owner` is the zero address, representing destroyed deeds. + /// @param _owner An address where we are interested in deeds owned by them + /// @return The number of deeds owned by `_owner`, possibly zero + function countOfDeedsByOwner(address _owner) external view returns (uint256 _count); + + /// @notice Enumerate deeds assigned to an owner + /// @dev Throws if `_index` >= `countOfDeedsByOwner(_owner)` or if + /// `_owner` is the zero address, representing destroyed deeds. + /// @param _owner An address where we are interested in deeds owned by them + /// @param _index A counter between zero and `countOfDeedsByOwner(_owner)`, + /// inclusive + /// @return The identifier for the `_index`th deed assigned to `_owner`, + /// (sort order not specified) + function deedOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256 _deedId); + + // TRANSFER MECHANISM ////////////////////////////////////////////////////// + + /// @dev This event emits when ownership of any deed changes by any + /// mechanism. This event emits when deeds are created (`from` == 0) and + /// destroyed (`to` == 0). Exception: during contract creation, any + /// transfers may occur without emitting `Transfer`. + event Transfer(address indexed from, address indexed to, uint256 indexed deedId); + + /// @dev This event emits on any successful call to + /// `approve(address _spender, uint256 _deedId)`. Exception: does not emit + /// if an owner revokes approval (`_to` == 0x0) on a deed with no existing + /// approval. + event Approval(address indexed owner, address indexed approved, uint256 indexed deedId); + + /// @notice Approve a new owner to take your deed, or revoke approval by + /// setting the zero address. You may `approve` any number of times while + /// the deed is assigned to you, only the most recent approval matters. + /// @dev Throws if `msg.sender` does not own deed `_deedId` or if `_to` == + /// `msg.sender`. + /// @param _deedId The deed you are granting ownership of + function approve(address _to, uint256 _deedId) external payable; + + /// @notice Become owner of a deed for which you are currently approved + /// @dev Throws if `msg.sender` is not approved to become the owner of + /// `deedId` or if `msg.sender` currently owns `_deedId`. + /// @param _deedId The deed that is being transferred + function takeOwnership(uint256 _deedId) external payable; +} +``` + +Implementations MAY also choose to implement the **ERC-721 Metadata extension**. This is RECOMMENDED and will allow third party wallets to show your deeds in the best way. It will be a lot more flattering than + +> You just received deed ID `0xb9d6a94f1ab16f461b2af06aebab7e1cfe10ada985da001f274f370fbb848a40` from contract `0x0dcd2f752394c41875e259e00bb44fd505297caf`! + +``` +/// @title Metadata extension to ERC-721 interface +/// @author William Entriken (https://phor.net) +/// @dev Specification at https://github.com/ethereum/eips/issues/XXXX +interface ERC721Metadata is ERC721 { + + /// @dev ERC-165 (draft) interface signature for ERC721 + // bytes4 internal constant INTERFACE_SIGNATURE_ERC721Metadata = // 0x2a786f11 + // bytes4(keccak256('name()')) ^ + // bytes4(keccak256('symbol()')) ^ + // bytes4(keccak256('deedUri(uint256)')); + + /// @notice A descriptive name for a collection of deeds managed by this + /// contract + /// @dev Wallets and exchanges MAY display this to the end user. + function name() public pure returns (string _deedName); + + /// @notice An abbreviated name for deeds managed by this contract + /// @dev Wallets and exchanges MAY display this to the end user. + function symbol() public pure returns (string _deedSymbol); + + /// @notice A distinct URI (RFC 3986) for a given token. + /// @dev If: + /// * The URI is a URL + /// * The URL is accessible + /// * The URL points to a valid JSON file format (ECMA-404 2nd ed.) + /// * The JSON base element is an object + /// then these names of the base element SHALL have special meaning: + /// * "name": A string identifying the item to which `_deedId` grants + /// ownership + /// * "description": A string detailing the item to which `_deedId` grants + /// ownership + /// * "image": A URI pointing to a file of image/* mime type representing + /// the item to which `_deedId` grants ownership + /// Wallets and exchanges MAY display this to the end user. + /// Consider making any images at a width between 320 and 1080 pixels and + /// aspect ratio between 1.91:1 and 4:5 inclusive. + function deedUri(uint256 _deedId) external view returns (string _uri); +} +``` + +A second extension, the **ERC-721 Accountability Extension**, is OPTIONAL and allows your contract to make all deeds discoverable. + +```solidity +/// @title Enumeration extension to ERC-721 interface +/// @author William Entriken (https://phor.net) +/// @dev Specification at https://github.com/ethereum/eips/issues/XXXX +contract ERC721Enumerable is ERC721 { + + /// @dev ERC-165 (draft) interface signature for ERC721 + // bytes4 internal constant INTERFACE_SIGNATURE_ERC721Metadata = // 0xa5e86824 + // bytes4(keccak256('deedByIndex()')) ^ + // bytes4(keccak256('countOfOwners()')) ^ + // bytes4(keccak256('ownerByIndex(uint256)')); + + /// @notice Enumerate active deeds + /// @dev Throws if `_index` >= `countOfDeeds()` + /// @param _index A counter between zero and `countOfDeeds()`, inclusive + /// @return The identifier for the `_index`th deed, (sort order not + /// specified) + function deedByIndex(uint256 _index) external view returns (uint256 _deedId); + + /// @notice Count of owners which own at least one deed + /// @return A count of the number of owners which own deeds + function countOfOwners() external view returns (uint256 _count); + + /// @notice Enumerate owners + /// @dev Throws if `_index` >= `countOfOwners()` + /// @param _index A counter between zero and `countOfOwners()`, inclusive + /// @return The address of the `_index`th owner (sort order not specified) + function ownerByIndex(uint256 _index) external view returns (address _owner); +} +``` + +### Caveats + +The 0.4.19 Solidity interface grammar is not expressive enough to document the ERC-721 specification. A contract which complies with ERC-721 must also abide by the following: + +- [Solidity issue #3412](https://github.com/ethereum/solidity/issues/3412): This interface includes explicit mutability guarantees for each function. Mutability guarantees are, in order weak to strong: `payable`, implicit nonpayable, `view`, and `pure`. Your implementation must meet the mutability guarantee in this interface or you may meet a stronger guarantee. For example, a `payable` function in this interface may be implemented as nonpayble (no state mutability specified) in your contract. We expect a later Solidity release will allow your stricter contract to inherit from this interface, but a workaround for version 0.4.19 is that you can edit this interface to add stricter mutibility before inheriting from your contract. +- [Solidity issue #3419](https://github.com/ethereum/solidity/issues/3419): If a contract is not compliant with `ERC721` then it is not compliant with `ERC721Metadata` or `ERC721Enumerable`. +- [Solidity issue #2330](https://github.com/ethereum/solidity/issues/2330): If a function is shown in this specification as `external` then a contract will be compliant if it uses `public` visibility. + +*If a newer version of Solidity allows the caveats to be expressed in code, then this EIP MAY be updated and the caveats removed, such will be equivalent to the original specification.* + +## Rationale + +There are many proposed uses of Ethereum smart contracts that depend on tracking individual deeds (non-fungible tokens). Examples of existing or planned NFTs are LAND in [Decentraland](https://decentraland.org/), the eponymous punks in [CryptoPunks](https://www.larvalabs.com/cryptopunks), and in-game items using systems like [Dmarket](https://www.dmarket.io/) or [EnjinCoin](https://enjincoin.io/). Future uses include tracking real-world non-fungible assets, like real-estate (as envisioned by companies like [Ubitquity](https://www.ubitquity.io/) or [Propy](https://tokensale.propy.com/)). It is critical in each of these cases that these items are not "lumped together" as numbers in a ledger, but instead, each token must have its ownership individually and atomically tracked. Regardless of the nature of these items, the ecosystem will be stronger if we have a standardized interface that allows for cross-functional deed management and sales platforms. + +**"Deed" word choice** + +The noun deed is defined in the Oxford Dictionary as: + +> A legal document that is signed and delivered, especially one regarding the ownership of property or legal rights. + +This definition is consistent with the fact that ERC-721 contracts track ownership of other things, such as houses, pictures of kittens or collectable cards. If you gain ownership of a house via ERC-721 (first, that would be awesome) then the thing that the ERC-721 contract tracks is the *deed*, the place where you live (and invite Will for dinner) is the *asset*. + +*Alternatives considered: non-fungible token, token, asset, equity, ticket* + +**Deed identifiers** + +The basis of this standard is that every deed is identified by a unique 256-bit unsigned integer within its tracking contract. This ID number MUST NOT change for the life of the contract. The pair `(contract address, asset ID)` will then be a globally unique and fully-qualified identifier for a specific deed within the Ethereum ecosystem. While some contracts may find it convenient to start with ID 0 and simply increment by one for each new NFT, callers MUST NOT assume that ID numbers have any specific pattern to them, and should treat the ID as a "black box". Also note that a deeds MAY be destroyed and as such you cannot simply count from from `0` to `countOfDeeds()`. Please see the enumerations functions for a supported enumeration interface. + +**Transfer mechanism** + +ERC-721 standardizes a two-step process for transferring deeds inspired from [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md). This requires the sender to approve sending and the receiver to accept approval. In the original ERC-20, this caused a problem when `allowance` was called and then later modified to a different amount, as [disucssed on OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/issues/438). In this deed standard, there is no allowance because every deed is unique, the quantity is none or one. Therefore we receive the benefits of ERC-20's original design without problems that have been later discovered. + +With two years experience, we have found that the one-step `transfer(address _to, uint256 _value)` is underirible. This is because it is very simple to accidently send property to an address that cannot use it, as dicussed in [ERC-233](https://github.com/ethereum/EIPs/issues/223) and [ERC-677](https://github.com/ethereum/EIPs/issues/677). + +A careful reading of this standars `approve` and `takeOwnership` functions also shows that *any* business reason may be used to deny transactions. Failed transactions will throw, a best practice identified in [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827) and [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol). + +Creating of new deeds and destruction of deeds is not included in the specification. Your implementing contract may implement these by other means. Please see the `event` documentation for your responsibilities when creating or destroying deeds. + +**Function mutability** + +The transfer functions `approve` and `takeOwnership` are payable. Yes, really. The standard contemplates a real estate ownership application where transfer of property will require paying tax from the old and/or new owner. Such an application would be compliant under this specification. Note that your contract may be nonpayable (syntactical sugar for `require(msg.value == 0)`) and be compliant, see caveats. + +**Supports interface** + +This specification includes a function `supportsInterface` so that any contract MAY query your contract to see if it complies with ERC-721 and the extensions. In the interest of GETTING THINGS DONE, we have inlined ERC-165. This EIP does NOT require the passage of ERC-165. To be clear: if you ask a contract if it supports ERC-721 and get a positive response, then it is still possible that the contract has lied to you and that its implementation does not meet the specification in this document. + +This inlined `supportsInterface` function uses `pure` mutability. The significance is that a contract which is deployed and not compliant with ERC-721 cannot make changes to become ERC-721 compliant. The benefit is that results of `supportsInterface` can be cached. This decision [has not achieved full consensus in the ERC-165 discussion](https://github.com/ethereum/EIPs/issues/165). + +**Gas and compleixty** + +This specification contemplates contracts managing few and *many* deeds. Specifically, we note that a large contract, initially with `N` deeds owned by the contract owner, can be deployed with `O(1)` gas. All fuctnios in the baseline and extension specifications can be implemented with `O(1)` gas and `O(Deed Count)` storage. + +**Accountability** + +Minimally, only the fuctions `ownerOf`, `approve`, `takeOwnership` are necessary for a usable deed standard. But wallets/brokers/auctioneers identified in the motivation section have a strong need to identify which deeds an owner owns. + +It may be interesting to consider a use case where deeds are not enumerable or deeds are not enumerable by owner, such as a private registry of property ownership, or a partially-private registry. However, privacy cannot be attained because an attacker can simply (!) call `ownerOf` for every possible `deedId`. This is why we include just the most usefull accounting in the baseline standard and the full accounting in the extension. + +**Metadata** + +We have chosen to make `name` and `symbol` both optional. These are interesting properties but are of limited utility. We remind wallet application authors that `name` and `symbol` cannot be trusted, a contract can easily return a value which overlaps with an existing well-known contract — or they may return an empty string / unable value. + +A mechanism is provided to associate deeds with URIs. We expect that many implementations will take advantage of this to provide metadata for each deed. The image size recommendation is taken from Instagram, they probably know much about image usability. The URI MAY be mutable (i.e. it changes from time to time). We considered a deed representing ownership of a real-world asset, in this case metadata about such an asset may naturally change. + +Metadata is returned as a string value. Currently this is only usable as calling from `web3`, not from other contracts. This is acceptable because we have not considered a use case where an on-blockchain application would query such information. + +**Operators** + +[ERC-777 discusses "operators"](https://github.com/ethereum/EIPs/issues/777), entities that you may assign to control property for you. We have considered adding such a feature to this specification. We have considered against this beacuse it should not be required — many contracts will not need this feature and such contracts have merit enough to be considered compliant with ERC-721. At this time, the operator model does not have much real-world experience. We expect that a future extension to this deed standard may introduce such functionality if warranted. + +**Discussions** + +A significant amount of discussion occured on [the original ERC-721](ERC-721 issue), additionally we held a live meeting [on Gitter](https://gitter.im/ethereum/ERCs?at=5a62259b5ade18be3998eec4) that had good representation and [was](https://www.reddit.com/r/ethereum/comments/7r2ena/friday_119_live_discussion_on_erc_nonfungible/) [well](https://gitter.im/ethereum/EIPs?at=5a5f823fb48e8c3566f0a5e7) [advertised](https://github.com/ethereum/eips/issues/721#issuecomment-358369377) in relevant communities. Thank you to the participants: + +- [@ImAllInNow](https://github.com/imallinnow) Rob from DEC Gaming / Presenting Michigan Ethereum Meetup Feb 7 +- [@Arachnid](https://github.com/arachnid) Nick Johnson +- [@jadhavajay](https://github.com/jadhavajay) Ajay Jadhav from AyanWorks +- [@superphly](https://github.com/superphly) Cody Marx Bailey - XRAM Capital / Sharing at hackathon Jan 20 + +Cody, is presenting ERC-721 at the UN Future of Finance Hackathon. + +## Backwards Compatibility + +This standard is inspired by the semantics of ERC-20, but can't be compatible with it due to the fundamental differences between tokens and deeds. + +Example deeds implementations as of January 2018: + +- [CryptoKitties](https://www.cryptokitties.co/) — Compatible with an earlier version of this standard. +- [CryptoPunks](https://www.larvalabs.com/cryptopunks) — Partially ERC-20 compatible, but not easily generalizable because it includes auction functionality directly in the contract and uses function names that explicitly refer to the deeds as "punks". +- [Auctionhouse Asset Interface](https://github.com/dob/auctionhouse/blob/master/contracts/Asset.sol) — [@dob](https://github.com/dob) needed a generic interface for his Auctionhouse dapp (currently ice-boxed). His "Asset" contract is very simple, but is missing ERC-20 compatibility, `approve()` functionality, and metadata. This effort is referenced in the discussion for [EIP-173](https://github.com/ethereum/EIPs/issues/173). + +Note: "Limited edition, collectable tokens" like [Curio Cards](https://mycuriocards.com/) and [Rare Pepe](https://rarepepewallet.com/) are *not* deeds. They're actually a collection of individual fungible tokens, each of which is tracked by its own smart contract with its own total supply (which may be `1` in extreme cases). + +## Test Cases + +**TO DO** + +Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable. + +## Implementation + +**TO DO** + +The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details. + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 4f71a029b80b42c74421b3988442b6cf8b095a32 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 24 Jan 2018 10:42:02 -0500 Subject: [PATCH 0373/1085] Correct spelling errors and interface name, thanks @Beskhue --- EIPS/eip-721.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index c1e2ada6d04f1..c8dbb22f27e50 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -178,7 +178,7 @@ A second extension, the **ERC-721 Accountability Extension**, is OPTIONAL and al contract ERC721Enumerable is ERC721 { /// @dev ERC-165 (draft) interface signature for ERC721 - // bytes4 internal constant INTERFACE_SIGNATURE_ERC721Metadata = // 0xa5e86824 + // bytes4 internal constant INTERFACE_SIGNATURE_ERC721Enumerable = // 0xa5e86824 // bytes4(keccak256('deedByIndex()')) ^ // bytes4(keccak256('countOfOwners()')) ^ // bytes4(keccak256('ownerByIndex(uint256)')); @@ -206,7 +206,7 @@ contract ERC721Enumerable is ERC721 { The 0.4.19 Solidity interface grammar is not expressive enough to document the ERC-721 specification. A contract which complies with ERC-721 must also abide by the following: -- [Solidity issue #3412](https://github.com/ethereum/solidity/issues/3412): This interface includes explicit mutability guarantees for each function. Mutability guarantees are, in order weak to strong: `payable`, implicit nonpayable, `view`, and `pure`. Your implementation must meet the mutability guarantee in this interface or you may meet a stronger guarantee. For example, a `payable` function in this interface may be implemented as nonpayble (no state mutability specified) in your contract. We expect a later Solidity release will allow your stricter contract to inherit from this interface, but a workaround for version 0.4.19 is that you can edit this interface to add stricter mutibility before inheriting from your contract. +- [Solidity issue #3412](https://github.com/ethereum/solidity/issues/3412): This interface includes explicit mutability guarantees for each function. Mutability guarantees are, in order weak to strong: `payable`, implicit nonpayable, `view`, and `pure`. Your implementation must meet the mutability guarantee in this interface or you may meet a stronger guarantee. For example, a `payable` function in this interface may be implemented as nonpayble (no state mutability specified) in your contract. We expect a later Solidity release will allow your stricter contract to inherit from this interface, but a workaround for version 0.4.19 is that you can edit this interface to add stricter mutability before inheriting from your contract. - [Solidity issue #3419](https://github.com/ethereum/solidity/issues/3419): If a contract is not compliant with `ERC721` then it is not compliant with `ERC721Metadata` or `ERC721Enumerable`. - [Solidity issue #2330](https://github.com/ethereum/solidity/issues/2330): If a function is shown in this specification as `external` then a contract will be compliant if it uses `public` visibility. @@ -234,31 +234,31 @@ The basis of this standard is that every deed is identified by a unique 256-bit ERC-721 standardizes a two-step process for transferring deeds inspired from [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md). This requires the sender to approve sending and the receiver to accept approval. In the original ERC-20, this caused a problem when `allowance` was called and then later modified to a different amount, as [disucssed on OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/issues/438). In this deed standard, there is no allowance because every deed is unique, the quantity is none or one. Therefore we receive the benefits of ERC-20's original design without problems that have been later discovered. -With two years experience, we have found that the one-step `transfer(address _to, uint256 _value)` is underirible. This is because it is very simple to accidently send property to an address that cannot use it, as dicussed in [ERC-233](https://github.com/ethereum/EIPs/issues/223) and [ERC-677](https://github.com/ethereum/EIPs/issues/677). +With two years experience, we have found that the one-step `transfer(address _to, uint256 _value)` is undesirable. This is because it is very simple to accidentally send property to an address that cannot use it, as discussed in [ERC-233](https://github.com/ethereum/EIPs/issues/223) and [ERC-677](https://github.com/ethereum/EIPs/issues/677). -A careful reading of this standars `approve` and `takeOwnership` functions also shows that *any* business reason may be used to deny transactions. Failed transactions will throw, a best practice identified in [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827) and [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol). +A careful reading of this standard's `approve` and `takeOwnership` functions also shows that *any* business reason may be used to deny transactions. Failed transactions will throw, a best practice identified in [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827) and [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol). Creating of new deeds and destruction of deeds is not included in the specification. Your implementing contract may implement these by other means. Please see the `event` documentation for your responsibilities when creating or destroying deeds. **Function mutability** -The transfer functions `approve` and `takeOwnership` are payable. Yes, really. The standard contemplates a real estate ownership application where transfer of property will require paying tax from the old and/or new owner. Such an application would be compliant under this specification. Note that your contract may be nonpayable (syntactical sugar for `require(msg.value == 0)`) and be compliant, see caveats. +The transfer functions `approve` and `takeOwnership` are payable. Yes, really. The standard contemplates a real estate ownership application where transfer of property will require paying tax from the old and/or new owner. Such an application would be compliant under this specification. Note that your contract may be nonpayable (syntactic sugar for `require(msg.value == 0)`) and be compliant, see caveats. **Supports interface** This specification includes a function `supportsInterface` so that any contract MAY query your contract to see if it complies with ERC-721 and the extensions. In the interest of GETTING THINGS DONE, we have inlined ERC-165. This EIP does NOT require the passage of ERC-165. To be clear: if you ask a contract if it supports ERC-721 and get a positive response, then it is still possible that the contract has lied to you and that its implementation does not meet the specification in this document. -This inlined `supportsInterface` function uses `pure` mutability. The significance is that a contract which is deployed and not compliant with ERC-721 cannot make changes to become ERC-721 compliant. The benefit is that results of `supportsInterface` can be cached. This decision [has not achieved full consensus in the ERC-165 discussion](https://github.com/ethereum/EIPs/issues/165). +This inline `supportsInterface` function uses `pure` mutability. The significance is that a contract which is deployed and not compliant with ERC-721 cannot make changes to become ERC-721 compliant. The benefit is that results of `supportsInterface` can be cached. This decision [has not achieved full consensus in the ERC-165 discussion](https://github.com/ethereum/EIPs/issues/165). -**Gas and compleixty** +**Gas and complexity** -This specification contemplates contracts managing few and *many* deeds. Specifically, we note that a large contract, initially with `N` deeds owned by the contract owner, can be deployed with `O(1)` gas. All fuctnios in the baseline and extension specifications can be implemented with `O(1)` gas and `O(Deed Count)` storage. +This specification contemplates contracts managing few and *many* deeds. Specifically, we note that a large contract, initially with `N` deeds owned by the contract owner, can be deployed with `O(1)` gas. All functions in the baseline and extension specifications can be implemented with `O(1)` gas and `O(Deed Count)` storage. **Accountability** -Minimally, only the fuctions `ownerOf`, `approve`, `takeOwnership` are necessary for a usable deed standard. But wallets/brokers/auctioneers identified in the motivation section have a strong need to identify which deeds an owner owns. +Minimally, only the functions `ownerOf`, `approve`, `takeOwnership` are necessary for a usable deed standard. But wallets/brokers/auctioneers identified in the motivation section have a strong need to identify which deeds an owner owns. -It may be interesting to consider a use case where deeds are not enumerable or deeds are not enumerable by owner, such as a private registry of property ownership, or a partially-private registry. However, privacy cannot be attained because an attacker can simply (!) call `ownerOf` for every possible `deedId`. This is why we include just the most usefull accounting in the baseline standard and the full accounting in the extension. +It may be interesting to consider a use case where deeds are not enumerable or deeds are not enumerable by owner, such as a private registry of property ownership, or a partially-private registry. However, privacy cannot be attained because an attacker can simply (!) call `ownerOf` for every possible `deedId`. This is why we include just the most useful accounting in the baseline standard and the full accounting in the extension. **Metadata** @@ -270,7 +270,7 @@ Metadata is returned as a string value. Currently this is only usable as calling **Operators** -[ERC-777 discusses "operators"](https://github.com/ethereum/EIPs/issues/777), entities that you may assign to control property for you. We have considered adding such a feature to this specification. We have considered against this beacuse it should not be required — many contracts will not need this feature and such contracts have merit enough to be considered compliant with ERC-721. At this time, the operator model does not have much real-world experience. We expect that a future extension to this deed standard may introduce such functionality if warranted. +[ERC-777 discusses "operators"](https://github.com/ethereum/EIPs/issues/777), entities that you may assign to control property for you. We have considered adding such a feature to this specification. We have considered against this because it should not be required — many contracts will not need this feature and such contracts have merit enough to be considered compliant with ERC-721. At this time, the operator model does not have much real-world experience. We expect that a future extension to this deed standard may introduce such functionality if warranted. **Discussions** @@ -293,7 +293,7 @@ Example deeds implementations as of January 2018: - [CryptoPunks](https://www.larvalabs.com/cryptopunks) — Partially ERC-20 compatible, but not easily generalizable because it includes auction functionality directly in the contract and uses function names that explicitly refer to the deeds as "punks". - [Auctionhouse Asset Interface](https://github.com/dob/auctionhouse/blob/master/contracts/Asset.sol) — [@dob](https://github.com/dob) needed a generic interface for his Auctionhouse dapp (currently ice-boxed). His "Asset" contract is very simple, but is missing ERC-20 compatibility, `approve()` functionality, and metadata. This effort is referenced in the discussion for [EIP-173](https://github.com/ethereum/EIPs/issues/173). -Note: "Limited edition, collectable tokens" like [Curio Cards](https://mycuriocards.com/) and [Rare Pepe](https://rarepepewallet.com/) are *not* deeds. They're actually a collection of individual fungible tokens, each of which is tracked by its own smart contract with its own total supply (which may be `1` in extreme cases). +Note: "Limited edition, collectible tokens" like [Curio Cards](https://mycuriocards.com/) and [Rare Pepe](https://rarepepewallet.com/) are *not* deeds. They're actually a collection of individual fungible tokens, each of which is tracked by its own smart contract with its own total supply (which may be `1` in extreme cases). ## Test Cases From 29f88ccbc4a45673956c54081c71f1ffc8286ec7 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 24 Jan 2018 10:45:17 -0500 Subject: [PATCH 0374/1085] Add "title" as considered alternative, thanks @TCOA --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index c8dbb22f27e50..b1cec0b9034f0 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -224,7 +224,7 @@ The noun deed is defined in the Oxford Dictionary as: This definition is consistent with the fact that ERC-721 contracts track ownership of other things, such as houses, pictures of kittens or collectable cards. If you gain ownership of a house via ERC-721 (first, that would be awesome) then the thing that the ERC-721 contract tracks is the *deed*, the place where you live (and invite Will for dinner) is the *asset*. -*Alternatives considered: non-fungible token, token, asset, equity, ticket* +*Alternatives considered: non-fungible token, title, token, asset, equity, ticket* **Deed identifiers** From e28b0ee623746884fe2f314b81185a59af4ca3b9 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 24 Jan 2018 10:47:37 -0500 Subject: [PATCH 0375/1085] Undo time travel, thanks @pirapira --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index b1cec0b9034f0..444f33c307d9f 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -7,7 +7,7 @@ Author: William Entriken , Dieter Shirley Date: Wed, 24 Jan 2018 10:48:19 -0500 Subject: [PATCH 0376/1085] "This is a" language, thanks @pirapira --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 444f33c307d9f..323965fa9180a 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -16,7 +16,7 @@ A standard interface for deeds, also known as non-fungible tokens. ## Abstract -**This a standard interface for smart contracts to handle deed ownership.** Deeds can represent ownership of physical property, like houses, or digital property, like unique pictures of kittens. In general, all houses are distinct and no two kittens are alike. Therefore you must track each deed separately; it is insufficient to simply count the deeds you own. +**This is a standard interface for smart contracts to handle deed ownership.** Deeds can represent ownership of physical property, like houses, or digital property, like unique pictures of kittens. In general, all houses are distinct and no two kittens are alike. Therefore you must track each deed separately; it is insufficient to simply count the deeds you own. The scope of this interface includes **interrogating the smart contract about deed ownership**. It also **allows deed owners to transfer assets**. The authors considered uses cases of individual deed ownership as well as custody by third party brokers/wallets/auctioneers. From f3765be9536399f4c9355ea942e40a6460df214c Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 24 Jan 2018 11:22:01 -0500 Subject: [PATCH 0377/1085] At risk of making this more boring to read, remove flavor text, thanks @TCOA --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 323965fa9180a..713461b760746 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -222,7 +222,7 @@ The noun deed is defined in the Oxford Dictionary as: > A legal document that is signed and delivered, especially one regarding the ownership of property or legal rights. -This definition is consistent with the fact that ERC-721 contracts track ownership of other things, such as houses, pictures of kittens or collectable cards. If you gain ownership of a house via ERC-721 (first, that would be awesome) then the thing that the ERC-721 contract tracks is the *deed*, the place where you live (and invite Will for dinner) is the *asset*. +This definition is consistent with the fact that ERC-721 contracts track ownership of other things, such as houses, pictures of kittens or collectable cards. If you gain ownership of a house via ERC-721 then the thing that the ERC-721 contract tracks is the *deed*, the place where you live is the *asset*. *Alternatives considered: non-fungible token, title, token, asset, equity, ticket* From 001b67bda3246e0662571f36984903c0d1391646 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 24 Jan 2018 11:26:29 -0500 Subject: [PATCH 0378/1085] Clarify real estate transferrence fees, thank you @TCOA --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 713461b760746..5b23c4072acce 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -242,7 +242,7 @@ Creating of new deeds and destruction of deeds is not included in the specificat **Function mutability** -The transfer functions `approve` and `takeOwnership` are payable. Yes, really. The standard contemplates a real estate ownership application where transfer of property will require paying tax from the old and/or new owner. Such an application would be compliant under this specification. Note that your contract may be nonpayable (syntactic sugar for `require(msg.value == 0)`) and be compliant, see caveats. +The transfer functions `approve` and `takeOwnership` are payable. Yes, really. The standard contemplates a real estate ownership application where transfer of property will require paying tax and/or various fees (including, but not limited to mining fees and pre-set transference fees), which may be paid by the old and/or new owner in any pre-arranged amount. Such an application would be compliant under this specification. Note that your contract may be nonpayable (syntactic sugar for `require(msg.value == 0)`) and be compliant, see caveats. **Supports interface** From c39a9f56c7dc00f32ec5cc0b2302d22d737d8472 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 24 Jan 2018 11:27:19 -0500 Subject: [PATCH 0379/1085] Use "unusable", thanks @TCOA --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 5b23c4072acce..b1235298c5fe3 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -262,7 +262,7 @@ It may be interesting to consider a use case where deeds are not enumerable or d **Metadata** -We have chosen to make `name` and `symbol` both optional. These are interesting properties but are of limited utility. We remind wallet application authors that `name` and `symbol` cannot be trusted, a contract can easily return a value which overlaps with an existing well-known contract — or they may return an empty string / unable value. +We have chosen to make `name` and `symbol` both optional. These are interesting properties but are of limited utility. We remind wallet application authors that `name` and `symbol` cannot be trusted, a contract can easily return a value which overlaps with an existing well-known contract — or they may return an empty string / unusable value. A mechanism is provided to associate deeds with URIs. We expect that many implementations will take advantage of this to provide metadata for each deed. The image size recommendation is taken from Instagram, they probably know much about image usability. The URI MAY be mutable (i.e. it changes from time to time). We considered a deed representing ownership of a real-world asset, in this case metadata about such an asset may naturally change. From 8636d7b8d6e798da66db4849c668c99cf5eff1f1 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 24 Jan 2018 11:37:06 -0500 Subject: [PATCH 0380/1085] occurred --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index b1235298c5fe3..d98ac059fdb0e 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -274,7 +274,7 @@ Metadata is returned as a string value. Currently this is only usable as calling **Discussions** -A significant amount of discussion occured on [the original ERC-721](ERC-721 issue), additionally we held a live meeting [on Gitter](https://gitter.im/ethereum/ERCs?at=5a62259b5ade18be3998eec4) that had good representation and [was](https://www.reddit.com/r/ethereum/comments/7r2ena/friday_119_live_discussion_on_erc_nonfungible/) [well](https://gitter.im/ethereum/EIPs?at=5a5f823fb48e8c3566f0a5e7) [advertised](https://github.com/ethereum/eips/issues/721#issuecomment-358369377) in relevant communities. Thank you to the participants: +A significant amount of discussion occurred on [the original ERC-721](ERC-721 issue), additionally we held a live meeting [on Gitter](https://gitter.im/ethereum/ERCs?at=5a62259b5ade18be3998eec4) that had good representation and [was](https://www.reddit.com/r/ethereum/comments/7r2ena/friday_119_live_discussion_on_erc_nonfungible/) [well](https://gitter.im/ethereum/EIPs?at=5a5f823fb48e8c3566f0a5e7) [advertised](https://github.com/ethereum/eips/issues/721#issuecomment-358369377) in relevant communities. Thank you to the participants: - [@ImAllInNow](https://github.com/imallinnow) Rob from DEC Gaming / Presenting Michigan Ethereum Meetup Feb 7 - [@Arachnid](https://github.com/arachnid) Nick Johnson From 82ad31575466dba198b0085c91d44a324f1102dc Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 24 Jan 2018 11:41:10 -0500 Subject: [PATCH 0381/1085] Limit title length --- eip-X.md | 1 + 1 file changed, 1 insertion(+) diff --git a/eip-X.md b/eip-X.md index 3ab783216dd8c..99de918876cd8 100644 --- a/eip-X.md +++ b/eip-X.md @@ -14,6 +14,7 @@ Note that an EIP number will be assigned by an editor. When opening a pull reque Requires (*optional): Replaces (*optional): +The title should be 44 characters or less. ## Simple Summary "If you can't explain it simply, you don't understand it well enough." Provide a simplified and layman-accessible explanation of the EIP. From e790f96e38acf428becfb4e760966f4a54b6372a Mon Sep 17 00:00:00 2001 From: ligi Date: Wed, 24 Jan 2018 22:56:07 +0100 Subject: [PATCH 0382/1085] Fix punctuation - clean dashy text --- EIPS/eip-831.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-831.md b/EIPS/eip-831.md index 0cf8d332b76db..cd6b147bda31d 100644 --- a/EIPS/eip-831.md +++ b/EIPS/eip-831.md @@ -28,14 +28,14 @@ Ethereum URLs contain "ethereum" in their schema (protocol) part and are constru ### Semantics -`prefix` is optional and defines the use-case for this URL. If no prefix is given: "pay-" is assumed to be concise and ensure backward compatibility to ERC-67. When the prefix is omitted - the payload must start with `0x`. Also prefixes must not start with `0x`. So starting with `0x` can be used as a clear signal that there is no prefix. +`prefix` is optional and defines the use-case for this URL. If no prefix is given: "pay-" is assumed to be concise and ensure backward compatibility to ERC-67. When the prefix is omitted, the payload must start with `0x`. Also prefixes must not start with `0x`. So starting with `0x` can be used as a clear signal that there is no prefix. `payload` is mandatory and the content depends on the prefix. Structuring of the content is defined in the ERC for the specific use-case and not in the scope of this document. One example is ERC-681 for the pay- prefix. ## Rationale -The need for this ERC emerged when refining ERC-681. We need a container that does not carry the weight of the use-cases. ERC-67 was the first attempt on defining Ethereum-URLs - this ERC tries to keep backward compatibility and not break existing things. This means ERC-67 URLs should still be valid and readable. Only if the prefix feature is used - ERC-67 parsers might break. No way was seen to avoid this and innovate on the same time. This is also the reason this open prefix approach was chosen to being able to adopt to future use-cases and not block the whole "ethereum:" scheme for a limited set of use-cases that existed at the time of writing this. +The need for this ERC emerged when refining ERC-681. We need a container that does not carry the weight of the use-cases. ERC-67 was the first attempt on defining Ethereum-URLs. This ERC tries to keep backward compatibility and not break existing things. This means ERC-67 URLs should still be valid and readable. Only if the prefix feature is used, ERC-67 parsers might break. No way was seen to avoid this and innovate on the same time. This is also the reason this open prefix approach was chosen to being able to adopt to future use-cases and not block the whole "ethereum:" scheme for a limited set of use-cases that existed at the time of writing this. ## Copyright From afabcb5f4630292094159aa628226e2b39e4b328 Mon Sep 17 00:00:00 2001 From: ligi Date: Thu, 25 Jan 2018 14:21:27 +0100 Subject: [PATCH 0383/1085] Add references --- EIPS/eip-831.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/EIPS/eip-831.md b/EIPS/eip-831.md index cd6b147bda31d..4196a550eafc9 100644 --- a/EIPS/eip-831.md +++ b/EIPS/eip-831.md @@ -37,6 +37,10 @@ Ethereum URLs contain "ethereum" in their schema (protocol) part and are constru The need for this ERC emerged when refining ERC-681. We need a container that does not carry the weight of the use-cases. ERC-67 was the first attempt on defining Ethereum-URLs. This ERC tries to keep backward compatibility and not break existing things. This means ERC-67 URLs should still be valid and readable. Only if the prefix feature is used, ERC-67 parsers might break. No way was seen to avoid this and innovate on the same time. This is also the reason this open prefix approach was chosen to being able to adopt to future use-cases and not block the whole "ethereum:" scheme for a limited set of use-cases that existed at the time of writing this. +## References + +1. ERC-67, https://github.com/ethereum/EIPs/issues/67 +2. ERC-681, https://github.com/ethereum/EIPs/pull/681 ## Copyright From cea1db05a3444870132ec3cb7dd78a244cba1805 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Thu, 25 Jan 2018 14:23:26 +0100 Subject: [PATCH 0384/1085] Move eip-20-token-standard.md to eip-20.md To prevent dangling links, I left a notice in eip-20-token-standard.md --- EIPS/eip-20-token-standard.md | 197 +--------------------------------- EIPS/eip-20.md | 196 +++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+), 196 deletions(-) create mode 100644 EIPS/eip-20.md diff --git a/EIPS/eip-20-token-standard.md b/EIPS/eip-20-token-standard.md index 01cd434d8100d..bbbf76174ddda 100644 --- a/EIPS/eip-20-token-standard.md +++ b/EIPS/eip-20-token-standard.md @@ -1,196 +1 @@ -## Preamble - - EIP: 20 - Title: ERC-20 Token Standard - Author: Fabian Vogelsteller , Vitalik Buterin - Type: Standard - Category: ERC - Status: Accepted - Created: 2015-11-19 - - -## Simple Summary - -A standard interface for tokens. - - -## Abstract - -The following standard allows for the implementation of a standard API for tokens within smart contracts. -This standard provides basic functionality to transfer tokens, as well as allow tokens to be approved so they can be spent by another on-chain third party. - - -## Motivation - -A standard interface allows any tokens on Ethereum to be re-used by other applications: from wallets to decentralized exchanges. - - -## Specification - -## Token -### Methods - -**NOTE**: Callers MUST handle `false` from `returns (bool success)`. Callers MUST NOT assume that `false` is never returned! - - -#### name - -Returns the name of the token - e.g. `"MyToken"`. - -OPTIONAL - This method can be used to improve usability, -but interfaces and other contracts MUST NOT expect these values to be present. - - -``` js -function name() constant returns (string name) -``` - - -#### symbol - -Returns the symbol of the token. E.g. "HIX". - -OPTIONAL - This method can be used to improve usability, -but interfaces and other contracts MUST NOT expect these values to be present. - -``` js -function symbol() constant returns (string symbol) -``` - - - -#### decimals - -Returns the number of decimals the token uses - e.g. `8`, means to divide the token amount by `100000000` to get its user representation. - -OPTIONAL - This method can be used to improve usability, -but interfaces and other contracts MUST NOT expect these values to be present. - -``` js -function decimals() constant returns (uint8 decimals) -``` - - -#### totalSupply - -Returns the total token supply. - -``` js -function totalSupply() constant returns (uint256 totalSupply) -``` - - - -#### balanceOf - -Returns the account balance of another account with address `_owner`. - -``` js -function balanceOf(address _owner) constant returns (uint256 balance) -``` - - - -#### transfer - -Transfers `_value` amount of tokens to address `_to`, and MUST fire the `Transfer` event. -The function SHOULD `throw` if the `_from` account balance does not have enough tokens to spend. - -*Note* Transfers of 0 values MUST be treated as normal transfers and fire the `Transfer` event. - -``` js -function transfer(address _to, uint256 _value) returns (bool success) -``` - - - -#### transferFrom - -Transfers `_value` amount of tokens from address `_from` to address `_to`, and MUST fire the `Transfer` event. - -The `transferFrom` method is used for a withdraw workflow, allowing contracts to transfer tokens on your behalf. -This can be used for example to allow a contract to transfer tokens on your behalf and/or to charge fees in sub-currencies. -The function SHOULD `throw` unless the `_from` account has deliberately authorized the sender of the message via some mechanism. - -*Note* Transfers of 0 values MUST be treated as normal transfers and fire the `Transfer` event. - -``` js -function transferFrom(address _from, address _to, uint256 _value) returns (bool success) -``` - - - -#### approve - -Allows `_spender` to withdraw from your account multiple times, up to the `_value` amount. If this function is called again it overwrites the current allowance with `_value`. - -**NOTE**: To prevent attack vectors like the one [described here](https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/) and discussed [here](https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729), -clients SHOULD make sure to create user interfaces in such a way that they set the allowance first to `0` before setting it to another value for the same spender. -THOUGH The contract itself shouldn't enforce it, to allow backwards compatibility with contracts deployed before - -``` js -function approve(address _spender, uint256 _value) returns (bool success) -``` - - -#### allowance - -Returns the amount which `_spender` is still allowed to withdraw from `_owner`. - -``` js -function allowance(address _owner, address _spender) constant returns (uint256 remaining) -``` - - - -### Events - - -#### Transfer - -MUST trigger when tokens are transferred, including zero value transfers. - -A token contract which creates new tokens SHOULD trigger a Transfer event with the `_from` address set to `0x0` when tokens are created. - -``` js -event Transfer(address indexed _from, address indexed _to, uint256 _value) -``` - - - -#### Approval - -MUST trigger on any successful call to `approve(address _spender, uint256 _value)`. - -``` js -event Approval(address indexed _owner, address indexed _spender, uint256 _value) -``` - - - -## Implementation - -There are already plenty of ERC20-compliant tokens deployed on the Ethereum network. -Different implementations have been written by various teams that have different trade-offs: from gas saving to improved security. - -#### Example implementations are available at -- https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/StandardToken.sol -- https://github.com/ConsenSys/Tokens/blob/master/contracts/eip20/EIP20.sol - -#### Implementation of adding the force to 0 before calling "approve" again: -- https://github.com/Giveth/minime/blob/master/contracts/MiniMeToken.sol - - - -## History - -Historical links releated to this standard: - -- Orginial proposal from Vitalik Buterin: https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs/499c882f3ec123537fc2fccd57eaa29e6032fe4a -- Reddit discussion: https://www.reddit.com/r/ethereum/comments/3n8fkn/lets_talk_about_the_coin_standard/ -- Original Issue #20: https://github.com/ethereum/EIPs/issues/20 - - - -## Copyright -Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). +Moved to [eip-20.md](./eip-20.md). diff --git a/EIPS/eip-20.md b/EIPS/eip-20.md new file mode 100644 index 0000000000000..01cd434d8100d --- /dev/null +++ b/EIPS/eip-20.md @@ -0,0 +1,196 @@ +## Preamble + + EIP: 20 + Title: ERC-20 Token Standard + Author: Fabian Vogelsteller , Vitalik Buterin + Type: Standard + Category: ERC + Status: Accepted + Created: 2015-11-19 + + +## Simple Summary + +A standard interface for tokens. + + +## Abstract + +The following standard allows for the implementation of a standard API for tokens within smart contracts. +This standard provides basic functionality to transfer tokens, as well as allow tokens to be approved so they can be spent by another on-chain third party. + + +## Motivation + +A standard interface allows any tokens on Ethereum to be re-used by other applications: from wallets to decentralized exchanges. + + +## Specification + +## Token +### Methods + +**NOTE**: Callers MUST handle `false` from `returns (bool success)`. Callers MUST NOT assume that `false` is never returned! + + +#### name + +Returns the name of the token - e.g. `"MyToken"`. + +OPTIONAL - This method can be used to improve usability, +but interfaces and other contracts MUST NOT expect these values to be present. + + +``` js +function name() constant returns (string name) +``` + + +#### symbol + +Returns the symbol of the token. E.g. "HIX". + +OPTIONAL - This method can be used to improve usability, +but interfaces and other contracts MUST NOT expect these values to be present. + +``` js +function symbol() constant returns (string symbol) +``` + + + +#### decimals + +Returns the number of decimals the token uses - e.g. `8`, means to divide the token amount by `100000000` to get its user representation. + +OPTIONAL - This method can be used to improve usability, +but interfaces and other contracts MUST NOT expect these values to be present. + +``` js +function decimals() constant returns (uint8 decimals) +``` + + +#### totalSupply + +Returns the total token supply. + +``` js +function totalSupply() constant returns (uint256 totalSupply) +``` + + + +#### balanceOf + +Returns the account balance of another account with address `_owner`. + +``` js +function balanceOf(address _owner) constant returns (uint256 balance) +``` + + + +#### transfer + +Transfers `_value` amount of tokens to address `_to`, and MUST fire the `Transfer` event. +The function SHOULD `throw` if the `_from` account balance does not have enough tokens to spend. + +*Note* Transfers of 0 values MUST be treated as normal transfers and fire the `Transfer` event. + +``` js +function transfer(address _to, uint256 _value) returns (bool success) +``` + + + +#### transferFrom + +Transfers `_value` amount of tokens from address `_from` to address `_to`, and MUST fire the `Transfer` event. + +The `transferFrom` method is used for a withdraw workflow, allowing contracts to transfer tokens on your behalf. +This can be used for example to allow a contract to transfer tokens on your behalf and/or to charge fees in sub-currencies. +The function SHOULD `throw` unless the `_from` account has deliberately authorized the sender of the message via some mechanism. + +*Note* Transfers of 0 values MUST be treated as normal transfers and fire the `Transfer` event. + +``` js +function transferFrom(address _from, address _to, uint256 _value) returns (bool success) +``` + + + +#### approve + +Allows `_spender` to withdraw from your account multiple times, up to the `_value` amount. If this function is called again it overwrites the current allowance with `_value`. + +**NOTE**: To prevent attack vectors like the one [described here](https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/) and discussed [here](https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729), +clients SHOULD make sure to create user interfaces in such a way that they set the allowance first to `0` before setting it to another value for the same spender. +THOUGH The contract itself shouldn't enforce it, to allow backwards compatibility with contracts deployed before + +``` js +function approve(address _spender, uint256 _value) returns (bool success) +``` + + +#### allowance + +Returns the amount which `_spender` is still allowed to withdraw from `_owner`. + +``` js +function allowance(address _owner, address _spender) constant returns (uint256 remaining) +``` + + + +### Events + + +#### Transfer + +MUST trigger when tokens are transferred, including zero value transfers. + +A token contract which creates new tokens SHOULD trigger a Transfer event with the `_from` address set to `0x0` when tokens are created. + +``` js +event Transfer(address indexed _from, address indexed _to, uint256 _value) +``` + + + +#### Approval + +MUST trigger on any successful call to `approve(address _spender, uint256 _value)`. + +``` js +event Approval(address indexed _owner, address indexed _spender, uint256 _value) +``` + + + +## Implementation + +There are already plenty of ERC20-compliant tokens deployed on the Ethereum network. +Different implementations have been written by various teams that have different trade-offs: from gas saving to improved security. + +#### Example implementations are available at +- https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/StandardToken.sol +- https://github.com/ConsenSys/Tokens/blob/master/contracts/eip20/EIP20.sol + +#### Implementation of adding the force to 0 before calling "approve" again: +- https://github.com/Giveth/minime/blob/master/contracts/MiniMeToken.sol + + + +## History + +Historical links releated to this standard: + +- Orginial proposal from Vitalik Buterin: https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs/499c882f3ec123537fc2fccd57eaa29e6032fe4a +- Reddit discussion: https://www.reddit.com/r/ethereum/comments/3n8fkn/lets_talk_about_the_coin_standard/ +- Original Issue #20: https://github.com/ethereum/EIPs/issues/20 + + + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From ea5b79014936bfb332166490d76de7ae2d58dd89 Mon Sep 17 00:00:00 2001 From: ia Date: Fri, 26 Jan 2018 00:35:55 +0900 Subject: [PATCH 0385/1085] Assigned lucky number 695 --- EIPS/{eip-rpc_eth_chain_id.md => eip-695.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename EIPS/{eip-rpc_eth_chain_id.md => eip-695.md} (98%) diff --git a/EIPS/eip-rpc_eth_chain_id.md b/EIPS/eip-695.md similarity index 98% rename from EIPS/eip-rpc_eth_chain_id.md rename to EIPS/eip-695.md index ab11affe8c207..6a26656303c3e 100644 --- a/EIPS/eip-rpc_eth_chain_id.md +++ b/EIPS/eip-695.md @@ -1,6 +1,6 @@ ## Preamble - EIP: + EIP: 695 Title: Create `eth_chainId` method for JSON-RPC Author: Isaac Ardis: isaac.ardis@gmail.com, Wei Tang: hi@that.world, [@tcz001](https://github.com/tcz001) Type: Standard Track From 68cde9b43ae9149a2bdd819e50fdc73f4c30f13b Mon Sep 17 00:00:00 2001 From: ia Date: Fri, 26 Jan 2018 11:40:17 +0900 Subject: [PATCH 0386/1085] Relative link to eip-155 --- EIPS/eip-695.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-695.md b/EIPS/eip-695.md index 6a26656303c3e..5e974a4a7c20e 100644 --- a/EIPS/eip-695.md +++ b/EIPS/eip-695.md @@ -16,7 +16,7 @@ Include `eth_chainId` method in `eth_`-namespaced JSON-RPC methods. The `eth_chainId` method should return a single STRING result for an integer value in hexadecimal format, describing the currently configured "Chain Id" value used for signing replay-protected transactions, -introduced via EIP-155. +introduced via [EIP-155](./eip-155.md). ## Motivation Currently although we can use net_version RPC call to get the From 45f6e8e48fbcd7ebda64083688728c522fc7190a Mon Sep 17 00:00:00 2001 From: ia Date: Fri, 26 Jan 2018 11:47:28 +0900 Subject: [PATCH 0387/1085] RPC spec: 'big integer' -> 'integer' --- EIPS/eip-695.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-695.md b/EIPS/eip-695.md index 5e974a4a7c20e..6366bd4d9d512 100644 --- a/EIPS/eip-695.md +++ b/EIPS/eip-695.md @@ -38,7 +38,7 @@ none ##### Returns -`QUANTITY` - big integer of the current chain id. Defaults are mainnet=61, morden=62. +`QUANTITY` - integer of the current chain id. Defaults are mainnet=61, morden=62. ##### Example ```js From 4269d195cbdfe9da3394edfcffa90ed61f847f17 Mon Sep 17 00:00:00 2001 From: ia Date: Fri, 26 Jan 2018 11:50:32 +0900 Subject: [PATCH 0388/1085] Rel link eip-155 for other occurrance --- EIPS/eip-695.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-695.md b/EIPS/eip-695.md index 6366bd4d9d512..70e8e9b8eff9b 100644 --- a/EIPS/eip-695.md +++ b/EIPS/eip-695.md @@ -31,7 +31,7 @@ the RPC. ### eth_chainId Returns the currently configured chain id, a value used in replay-protected transaction -signing as introduced by EIP-155. +signing as introduced by [EIP-155](./eip-155.md). ##### Parameters none From 18e49fe48b3f44dc2063f89ad561edf9bbb3416b Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 15:05:46 +1100 Subject: [PATCH 0389/1085] Grammar fixes --- EIPS/eip-2.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/EIPS/eip-2.md b/EIPS/eip-2.md index d31f61d29c1fa..dfc35cbeb7e5f 100644 --- a/EIPS/eip-2.md +++ b/EIPS/eip-2.md @@ -10,16 +10,16 @@ Created: 2015-11-15 # Specification -If `block.number >= HOMESTEAD_FORK_BLKNUM` (e.g., 1.150.000 on livenet, 494.000 on Morden and 0 on future testnets), do the following: +If `block.number >= HOMESTEAD_FORK_BLKNUM` (e.g., 1,150,000 on livenet, 494,000 on Morden and 0 on future testnets), do the following: -1. The gas cost *for creating contracts via a transaction* is increased from 21000 to 53000, ie. if you send a transaction and the to address is the empty string, the initial gas subtracted is 53000 plus the gas cost of the tx data, rather than 21000 as is currently the case. Contract creation from a contract using the `CREATE` opcode is unaffected. -2. All transaction signatures whose s-value is greater than `secp256k1n/2` are now considered invalid. The ECDSA recover precompiled contract remains unchanged and will keep accepting high s-values - this is useful if e.g. a contract recovers old Bitcoin signatures. -3. If contract creation does not have enough gas to pay for the final gas fee for adding the contract code to the state, the contract creation fails (ie. goes out-of-gas) rather than leaving an empty contract. +1. The gas cost *for creating contracts via a transaction* is increased from 21,000 to 53,000, i.e. if you send a transaction and the to address is the empty string, the initial gas subtracted is 53,000 plus the gas cost of the tx data, rather than 2,1000 as is currently the case. Contract creation from a contract using the `CREATE` opcode is unaffected. +2. All transaction signatures whose s-value is greater than `secp256k1n/2` are now considered invalid. The ECDSA recover precompiled contract remains unchanged and will keep accepting high s-values—this is useful e.g. if a contract recovers old Bitcoin signatures. +3. If contract creation does not have enough gas to pay for the final gas fee for adding the contract code to the state, the contract creation fails (i.e. goes out-of-gas) rather than leaving an empty contract. 4. Change the difficulty adjustment algorithm from the current formula: `block_diff = parent_diff + parent_diff // 2048 * (1 if block_timestamp - parent_timestamp < 13 else -1) + int(2**((block.number // 100000) - 2))` (where the ` + int(2**((block.number // 100000) - 2))` represents the exponential difficulty adjustment component) to `block_diff = parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99) + int(2**((block.number // 100000) - 2))`, where `//` is the integer division operator, eg. `6 // 2 = 3`, `7 // 2 = 3`, `8 // 2 = 4`. The `minDifficulty` still defines the minimum difficulty allowed and no adjustment may take it below this. # Rationale -Currently, there is an excess incentive to create contracts via transactions, where the cost is 21000, rather than contracts, where the cost is 32000. Additionally, with the help of suicide refunds, it is currently possible to make a simple ether value transfer using only 11664 gas; the code for doing this is as follows: +Currently, there is an excess incentive to create contracts via transactions, where the cost is 21,000, rather than contracts, where the cost is 32,000. Additionally, with the help of suicide refunds, it is currently possible to make a simple ether value transfer using only 11,664 gas; the code for doing this is as follows: ```python from ethereum import tester as t @@ -31,13 +31,16 @@ from ethereum import tester as t > s.block.get_balance(utils.normalize_address(0x47e25df8822538a8596b28c637896b4d143c351e)) 1000000000000000 ``` -This is not a particularly serious problem, but is nevertheless arguably a bug. +This is not a particularly serious problem, but it is nevertheless arguably a bug. Allowing transactions with any s value with `0 < s < secp256k1n`, as is currently the case, opens a transaction malleability concern, as one can take any transaction, flip the s value from `s` to `secp256k1n - s`, flip the v value (`27 -> 28`, `28 -> 27`), and the resulting signature would still be valid. This is not a serious security flaw, especially since Ethereum uses addresses and not transaction hashes as the input to an ether value transfer or other transaction, but it nevertheless creates a UI inconvenience as an attacker can cause the transaction that gets confirmed in a block to have a different hash from the transaction that any user sends, interfering with user interfaces that use transaction hashes as tracking IDs. Preventing high s values removes this problem. -Making contract creation go out-of-gas if there is not enough gas to pay for the final gas fee has the benefits that (i) it creates a more intuitive "success or fail" distinction in the result of a contract creation process, rather than the current "success, fail, or empty contract" trichotomy, (ii) makes failures more easily detectable, as unless contract creation fully succeeds then no contract account will be created at all, and (iii) makes contract creation safer in the case where there is an endowment, as there is a guarantee that either the entire initiation process happens or the transaction fails and the endowment is refunded. +Making contract creation go out-of-gas if there is not enough gas to pay for the final gas fee has the benefits that: +- (i) it creates a more intuitive "success or fail" distinction in the result of a contract creation process, rather than the current "success, fail, or empty contract" trichotomy; +- (ii) makes failures more easily detectable, as unless contract creation fully succeeds then no contract account will be created at all; and +- (iii) makes contract creation safer in the case where there is an endowment, as there is a guarantee that either the entire initiation process happens or the transaction fails and the endowment is refunded. -The difficulty adjustment change conclusively solves a problem that the Ethereum protocol saw two months ago where an excessive number of miners were mining blocks that contain a timestamp equal to `parent_timestamp + 1`; this skewed the block time distribution, and so the current block time algorithm, which targets a *median* of 13 seconds, continued to target the same median but the mean started increasing. If 51% of miners had started mining blocks in this way, the mean would have increased to infinity. The proposed new formula is roughly based on targeting the mean; one can prove that with the formula in use an average block time longer than 24 seconds is mathematically impossible in the long term. +The difficulty adjustment change conclusively solves a problem that the Ethereum protocol saw two months ago where an excessive number of miners were mining blocks that contain a timestamp equal to `parent_timestamp + 1`; this skewed the block time distribution, and so the current block time algorithm, which targets a *median* of 13 seconds, continued to target the same median but the mean started increasing. If 51% of miners had started mining blocks in this way, the mean would have increased to infinity. The proposed new formula is roughly based on targeting the mean; one can prove that with the formula in use, an average block time longer than 24 seconds is mathematically impossible in the long term. The use of `(block_timestamp - parent_timestamp) // 10` as the main input variable rather than the time difference directly serves to maintain the coarse-grained nature of the algorithm, preventing an excessive incentive to set the timestamp difference to exactly 1 in order to create a block that has slightly higher difficulty and that will thus be guaranteed to beat out any possible forks. The cap of -99 simply serves to ensure that the difficulty does not fall extremely far if two blocks happen to be very far apart in time due to a client security bug or other black-swan issue. From fefbbea5f4d8bc7a01791e94101197eb6a4a0907 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 15:11:40 +1100 Subject: [PATCH 0390/1085] Grammar fixes --- EIPS/eip-7.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/EIPS/eip-7.md b/EIPS/eip-7.md index f9f5059f29bf2..78d73a36956c0 100644 --- a/EIPS/eip-7.md +++ b/EIPS/eip-7.md @@ -8,7 +8,7 @@ ### Overview -Add a new opcode, `DELEGATECALL` at `0xf4`, which is similar in idea to `CALLCODE`, except that it propagates the sender and value from the parent scope to the child scope, ie. the call created has the same sender and value as the original call. +Add a new opcode, `DELEGATECALL` at `0xf4`, which is similar in idea to `CALLCODE`, except that it propagates the sender and value from the parent scope to the child scope, i.e. the call created has the same sender and value as the original call. ### Specification @@ -20,15 +20,15 @@ Add a new opcode, `DELEGATECALL` at `0xf4`, which is similar in idea to `CALLCOD - `out_offset`: the offset into memory of the output; - `out_size`: the size of the scratch pad for the output. -#### Notes on Gas +#### Notes on gas - The basic stipend is not given; `gas` is the total amount the callee receives. - Like `CALLCODE`, account creation never happens, so the upfront gas cost is always `schedule.callGas` + `gas`. - Unused gas is refunded as normal. -#### Notes on Sender +#### Notes on sender - `CALLER` and `VALUE` behave exactly in the callee's environment as they do in the caller's environment. -#### Other Notes +#### Other notes - The depth limit of 1024 is still preserved as normal. ### Rationale From d0b542e499f0159321458675a1f427c8c5b1ffb4 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 16:08:33 +1100 Subject: [PATCH 0391/1085] Grammar fixes --- EIPS/eip-155.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-155.md b/EIPS/eip-155.md index 9e18730b0a95f..b33005e5a03c3 100644 --- a/EIPS/eip-155.md +++ b/EIPS/eip-155.md @@ -14,7 +14,7 @@ Created: 2016-10-14 - `CHAIN_ID`: 1 ### Specification -If `block.number >= FORK_BLKNUM` and `v = CHAIN_ID * 2 + 35` or `v = CHAIN_ID * 2 + 36`, then when computing the hash of a transaction for purposes of signing or recovering, instead of hashing only the first six elements (ie. nonce, gasprice, startgas, to, value, data), hash nine elements, with `v` replaced by `CHAIN_ID`, `r = 0` and `s = 0`. The currently existing signature scheme using `v = 27` and `v = 28` remains valid and continues to operate under the same rules as it does now. +If `block.number >= FORK_BLKNUM` and `v = CHAIN_ID * 2 + 35` or `v = CHAIN_ID * 2 + 36`, then when computing the hash of a transaction for purposes of signing or recovering, instead of hashing only the first six elements (i.e. nonce, gasprice, startgas, to, value, data), hash nine elements, with `v` replaced by `CHAIN_ID`, `r = 0` and `s = 0`. The currently existing signature scheme using `v = 27` and `v = 28` remains valid and continues to operate under the same rules as it does now. ### Example Consider a transaction with `nonce = 9`, `gasprice = 20 * 10**9`, `startgas = 21000`, `to = 0x3535353535353535353535353535353535353535`, `value = 10**18`, `data=''` (empty). @@ -44,7 +44,7 @@ Notice the use of 37 instead of 27. The signed tx would become: ``` ### Rationale -This would provide a way to send transactions that work on ethereum without working on ETC or the Morden testnet. ETC is encouraged to adopt this EIP but replacing `CHAIN_ID` with a different value, and all future testnets, consortium chains and alt-etherea are encouraged to adopt this EIP replacing `CHAIN_ID` with a unique value. +This would provide a way to send transactions that work on Ethereum without working on ETC or the Morden testnet. ETC is encouraged to adopt this EIP but replacing `CHAIN_ID` with a different value, and all future testnets, consortium chains and alt-etherea are encouraged to adopt this EIP replacing `CHAIN_ID` with a unique value. ### List of Chain ID's: From c8cb7ca168c18d08b02ff35758d4358704971ee2 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 16:14:52 +1100 Subject: [PATCH 0392/1085] Add FORK_BLKNUM: 2,675,000 (Spurious Dragon) plus an en dash --- EIPS/eip-160.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-160.md b/EIPS/eip-160.md index c80d384155e02..d788aeda6708c 100644 --- a/EIPS/eip-160.md +++ b/EIPS/eip-160.md @@ -7,6 +7,9 @@ Category: Core Status: Final Created: 2016-10-20 ``` +### Parameters + +FORK_BLKNUM: 2,675,000 (Spurious Dragon) ### Specification @@ -14,7 +17,7 @@ If `block.number >= FORK_BLKNUM`, increase the gas cost of EXP from 10 + 10 per ### Rationale -Benchmarks suggest that EXP is currently underpriced by a factor of about 4-8. +Benchmarks suggest that EXP is currently underpriced by a factor of about 4–8. ### References From 20d8f9434642531d93183e7b035b6170b4c57faa Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 16:31:59 +1100 Subject: [PATCH 0393/1085] Grammar fixes and block number Newly-creation: this is wrong. You use adverbs before verbs. Creation implies that it is new, so it is a tautology to say new creation or newly created; rather like "I killed him dead". --- EIPS/eip-161.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-161.md b/EIPS/eip-161.md index bd73c60a05106..cb15cb88a6d60 100644 --- a/EIPS/eip-161.md +++ b/EIPS/eip-161.md @@ -7,7 +7,9 @@ Category: Core Status: Final Created: 2016-10-24 ``` - +### Parameters +- `FORK_BLKNUM`: 2,675,000 +- `CHAIN_ID`: 1 # Specification a. Account creation transactions and the `CREATE` operation SHALL, prior to the execution of the initialisation code, **increment** the **nonce** over and above its normal starting value by **one** (for normal networks, this will be simply 1, however test-nets with non-zero default starting nonces will be different). @@ -31,8 +33,8 @@ _At the end of the transaction_ is immediately following the execution of the su An account _changes state_ when: - it is the target or refund of a `SUICIDE` operation for **zero or more** value; - it is the source or destination of a `CALL` operation or message-call transaction transferring **zero or more** value; -- it is the source or newly-creation of a `CREATE` operation or contract-creation transaction endowing **zero or more** value; -- as the block author ("miner") it is recipient of block-rewards or transaction-fees of **zero or more**. +- it is the source or creation of a `CREATE` operation or contract-creation transaction endowing **zero or more** value; +- as the block author ("miner") it is the recipient of block-rewards or transaction-fees of **zero or more** value. ## Notes From 065d4189f2b7f61515e7a320e4a75d28de0b7507 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 16:35:40 +1100 Subject: [PATCH 0394/1085] Update eip-170.md --- EIPS/eip-170.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-170.md b/EIPS/eip-170.md index 2dcd7a5899754..5b63567d157ac 100644 --- a/EIPS/eip-170.md +++ b/EIPS/eip-170.md @@ -7,6 +7,10 @@ Category: Core Status: Final Created: 2016-11-04 ``` +### Parameters + +- `FORK_BLKNUM`: 2,675,000 +- `CHAIN_ID`: 1 ### Specification @@ -14,7 +18,7 @@ If `block.number >= FORK_BLKNUM`, then if contract creation initialization retur ### Rationale -Currently, there remains one slight quadratic vulnerability in ethereum: when a contract is called, even though the call takes a constant amount of gas, the call can trigger O(n) cost in terms of reading the code from disk, preprocessing the code for VM execution, and also adding O(n) data to the Merkle proof for the block's proof-of-validity. At current gas levels, this is acceptable even if suboptimal. At the higher gas levels that could be triggered in the future, possibly very soon due to dynamic gas limit rules, this would become a greater concern - not nearly as serious as recent denial of service attacks, but still inconvenient especially for future light clients verifying proofs of validity or invalidity. The solution is to put a hard cap on the size of an object that can be saved to the blockchain, and do so non-disruptively by setting the cap at a value slightly higher than what is feasible with current gas limits. +Currently, there remains one slight quadratic vulnerability in Ethereum: when a contract is called, even though the call takes a constant amount of gas, the call can trigger O(n) cost in terms of reading the code from disk, preprocessing the code for VM execution, and also adding O(n) data to the Merkle proof for the block's proof-of-validity. At current gas levels, this is acceptable even if suboptimal. At the higher gas levels that could be triggered in the future, possibly very soon due to dynamic gas limit rules, this would become a greater concern—not nearly as serious as recent denial of service attacks, but still inconvenient especially for future light clients verifying proofs of validity or invalidity. The solution is to put a hard cap on the size of an object that can be saved to the blockchain, and do so non-disruptively by setting the cap at a value slightly higher than what is feasible with current gas limits. ### References From 2c5c077d16ba75f9523445b0eb65e505424ce38e Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 17:02:05 +1100 Subject: [PATCH 0395/1085] (Tangerine Whistle) --- EIPS/eip-170.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-170.md b/EIPS/eip-170.md index 5b63567d157ac..6ca2c505115af 100644 --- a/EIPS/eip-170.md +++ b/EIPS/eip-170.md @@ -9,7 +9,7 @@ Created: 2016-11-04 ``` ### Parameters -- `FORK_BLKNUM`: 2,675,000 +- `FORK_BLKNUM`: 2,675,000 ([Tangerine Whistle](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-608.md)) - `CHAIN_ID`: 1 ### Specification From 400438cebd4f55f509ec7fdb8742def9db7a404a Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 17:03:07 +1100 Subject: [PATCH 0396/1085] [Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md) --- EIPS/eip-160.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-160.md b/EIPS/eip-160.md index d788aeda6708c..2837775e7cbf6 100644 --- a/EIPS/eip-160.md +++ b/EIPS/eip-160.md @@ -9,7 +9,7 @@ Created: 2016-10-20 ``` ### Parameters -FORK_BLKNUM: 2,675,000 (Spurious Dragon) +FORK_BLKNUM: 2,675,000 ([Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md)) ### Specification From c862735e827ccc53e470e6980e178280f85b03a2 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 17:05:16 +1100 Subject: [PATCH 0397/1085] ([Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md)) --- EIPS/eip-155.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-155.md b/EIPS/eip-155.md index b33005e5a03c3..af9b94095e6c7 100644 --- a/EIPS/eip-155.md +++ b/EIPS/eip-155.md @@ -10,7 +10,7 @@ Created: 2016-10-14 ``` ### Parameters -- `FORK_BLKNUM`: 2,675,000 +- `FORK_BLKNUM`: 2,675,000 ([Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md)) - `CHAIN_ID`: 1 ### Specification From 2b6c2039fa23626a615eca0cadc8941cca26dc3e Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 17:07:39 +1100 Subject: [PATCH 0398/1085] Add parameters --- EIPS/eip-7.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/EIPS/eip-7.md b/EIPS/eip-7.md index 78d73a36956c0..2f100778a6d90 100644 --- a/EIPS/eip-7.md +++ b/EIPS/eip-7.md @@ -6,6 +6,10 @@ Type: Homestead feature Created: 2015-11-15 +### Parameters +- FORK_BLKNUM: 2,675,000 ([Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md)) +- CHAIN_ID: 1 + ### Overview Add a new opcode, `DELEGATECALL` at `0xf4`, which is similar in idea to `CALLCODE`, except that it propagates the sender and value from the parent scope to the child scope, i.e. the call created has the same sender and value as the original call. From 2b02ca4548a76d57451bf5b37bcc9df497e62a99 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 17:09:00 +1100 Subject: [PATCH 0399/1085] Chain_ID --- EIPS/eip-160.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-160.md b/EIPS/eip-160.md index 2837775e7cbf6..101beb9054511 100644 --- a/EIPS/eip-160.md +++ b/EIPS/eip-160.md @@ -9,7 +9,8 @@ Created: 2016-10-20 ``` ### Parameters -FORK_BLKNUM: 2,675,000 ([Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md)) +- FORK_BLKNUM: 2,675,000 ([Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md)) +- CHAIN_ID: 1 ### Specification From 31be04a215125a9bb90e2780b4b5543669641331 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 17:11:25 +1100 Subject: [PATCH 0400/1085] Add parameters --- EIPS/eip-150.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/EIPS/eip-150.md b/EIPS/eip-150.md index 8231cf81e9859..8ed0c111f89bf 100644 --- a/EIPS/eip-150.md +++ b/EIPS/eip-150.md @@ -8,20 +8,24 @@ Category: Core Status: Final Created: 2016-09-24 ``` +### Parameters + +- `FORK_BLKNUM`: 1 ([Homestead](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-606.md)) +- `CHAIN_ID`: 1 ### Specification If `block.number >= FORK_BLKNUM`, then: -- Increase the gas cost of EXTCODESIZE to 700 -- Increase the base gas cost of EXTCODECOPY to 700 -- Increase the gas cost of BALANCE to 400 -- Increase the gas cost of SLOAD to 200 -- Increase the gas cost of CALL, DELEGATECALL, CALLCODE to 700 -- Increase the gas cost of SELFDESTRUCT to 5000 -- If SELFDESTRUCT hits a newly created account, it triggers an additional gas cost of 25000 (similar to CALLs) -- Increase the recommended gas limit target to 5.5 million -- Define "all but one 64th" of `N` as `N - floor(N / 64)` -- If a call asks for more gas than the maximum allowed amount (ie. total amount of gas remaining in the parent after subtracting the gas cost of the call and memory expansion), do not return an OOG error; instead, if a call asks for more gas than all but one 64th of the maximum allowed amount, call with all but one 64th of the maximum allowed amount of gas (this is equivalent to a version of EIP-90[1](https://github.com/ethereum/EIPs/issues/90) plus EIP-114[2](https://github.com/ethereum/EIPs/issues/114)). CREATE only provides all but one 64th of the parent gas to the child call. +- Increase the gas cost of EXTCODESIZE to 700. +- Increase the base gas cost of EXTCODECOPY to 700. +- Increase the gas cost of BALANCE to 400. +- Increase the gas cost of SLOAD to 200. +- Increase the gas cost of CALL, DELEGATECALL, CALLCODE to 700. +- Increase the gas cost of SELFDESTRUCT to 5000. +- If SELFDESTRUCT hits a newly created account, it triggers an additional gas cost of 25000 (similar to CALLs). +- Increase the recommended gas limit target to 5.5 million. +- Define "all but one 64th" of `N` as `N - floor(N / 64)`. +- If a call asks for more gas than the maximum allowed amount (i.e. the total amount of gas remaining in the parent after subtracting the gas cost of the call and memory expansion), do not return an OOG error; instead, if a call asks for more gas than all but one 64th of the maximum allowed amount, call with all but one 64th of the maximum allowed amount of gas (this is equivalent to a version of EIP-90[1](https://github.com/ethereum/EIPs/issues/90) plus EIP-114[2](https://github.com/ethereum/EIPs/issues/114)). CREATE only provides all but one 64th of the parent gas to the child call. That is, substitute: From e362ba314de1a2d053a1b6841dbbf958639d4c1d Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 17:21:00 +1100 Subject: [PATCH 0401/1085] Include EIP 8 --- EIPS/eip-606.md | 1 + 1 file changed, 1 insertion(+) diff --git a/EIPS/eip-606.md b/EIPS/eip-606.md index b2ecb84792aa6..c8dad7f004ab8 100644 --- a/EIPS/eip-606.md +++ b/EIPS/eip-606.md @@ -22,6 +22,7 @@ This specifies the changes included in the hard fork named Homestead. - Included EIPs: - [EIP 2](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md) (Homestead Hard-fork Changes) - [EIP 7](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7.md) (DELEGATECALL) + - [EIP 8](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-8.md) (Networking layer: devp2p Forward Compatibility Requirements for Homestead) ## References From 58df2e402f96ccfb336ccccabed9cc6ed91d8423 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 18:04:36 +1100 Subject: [PATCH 0402/1085] Meta reference and table of parameters --- EIPS/eip-150.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-150.md b/EIPS/eip-150.md index 8ed0c111f89bf..353b497108331 100644 --- a/EIPS/eip-150.md +++ b/EIPS/eip-150.md @@ -8,10 +8,15 @@ Category: Core Status: Final Created: 2016-09-24 ``` +### Meta reference + +([Tangerine Whistle](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-608.md)). + ### Parameters -- `FORK_BLKNUM`: 1 ([Homestead](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-606.md)) -- `CHAIN_ID`: 1 +| FORK_BLKNUM | CHAIN_ID | CHAIN_NAME | +|-----------------|------------|-------------| +| 2,463,000 | 1 | Main net | ### Specification From f7512125ac31f1e39244f396bcf70390c4be372a Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 18:05:06 +1100 Subject: [PATCH 0403/1085] Remove parentheses --- EIPS/eip-150.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-150.md b/EIPS/eip-150.md index 353b497108331..f2c7fd1265ec2 100644 --- a/EIPS/eip-150.md +++ b/EIPS/eip-150.md @@ -10,7 +10,7 @@ Created: 2016-09-24 ``` ### Meta reference -([Tangerine Whistle](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-608.md)). +[Tangerine Whistle](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-608.md). ### Parameters From 34663200323e65d161d6fd79583f76a95d4212ac Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 18:44:00 +1100 Subject: [PATCH 0404/1085] Grammar fixes: en dash, delete a space --- EIPS/eip-150.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-150.md b/EIPS/eip-150.md index f2c7fd1265ec2..9070389e78fe2 100644 --- a/EIPS/eip-150.md +++ b/EIPS/eip-150.md @@ -59,9 +59,9 @@ With: ### Rationale -Recent denial-of-service attacks have shown that opcodes that read the state tree are under-priced relative to other opcodes. There are software changes that have been made, are being made and can be made in order to mitigate the situation; however, the fact will remain that such opcodes will be by a substantial margin the easiest known mechanism to degrade network performance via transaction spam. The concern arises because it takes a long time to read from disk, and is additionally a risk to future sharding proposals as the "attack transactions" that have so far been most successful in degrading network performance would also require tens of megabytes to provide Merkle proofs for. This EIP increases the cost of storage reading opcodes to address this concern. The costs have been derived from an updated version of the calculation table used to generate the 1.0 gas costs: https://docs.google.com/spreadsheets/d/15wghZr-Z6sRSMdmRmhls9dVXTOpxKy8Y64oy9MvDZEQ/edit#gid=0 ; the rules attempt to target a limit of 8 MB of data that needs to be read in order to process a block, and include an estimate of 500 bytes for a Merkle proof for SLOAD and 1000 for an account. +Recent denial-of-service attacks have shown that opcodes that read the state tree are under-priced relative to other opcodes. There are software changes that have been made, are being made and can be made in order to mitigate the situation; however, the fact will remain that such opcodes will be by a substantial margin the easiest known mechanism to degrade network performance via transaction spam. The concern arises because it takes a long time to read from disk, and is additionally a risk to future sharding proposals as the "attack transactions" that have so far been most successful in degrading network performance would also require tens of megabytes to provide Merkle proofs for. This EIP increases the cost of storage reading opcodes to address this concern. The costs have been derived from an updated version of the calculation table used to generate the 1.0 gas costs: https://docs.google.com/spreadsheets/d/15wghZr-Z6sRSMdmRmhls9dVXTOpxKy8Y64oy9MvDZEQ/edit#gid=0; the rules attempt to target a limit of 8 MB of data that needs to be read in order to process a block, and include an estimate of 500 bytes for a Merkle proof for SLOAD and 1000 for an account. -This EIP aims to be simple, and adds a flat penalty of 300 gas on top of the costs calculated in this table to account for the cost of loading the code (~17-21 kb in the worst case). +This EIP aims to be simple, and adds a flat penalty of 300 gas on top of the costs calculated in this table to account for the cost of loading the code (~17–21 kb in the worst case). The EIP 90 gas mechanic is introduced because without it, all current contracts that make calls would stop working as they use an expression like `msg.gas - 40` to determine how much gas to make a call with, relying on the gas cost of calls being 40. Additionally, EIP 114 is introduced because, given that we are making the cost of a call higher and less predictable, we have an opportunity to do it at no extra cost to currently available guarantees, and so we also achieve the benefit of replacing the call stack depth limit with a "softer" gas-based restriction, thereby eliminating call stack depth attacks as a class of attack that contract developers have to worry about and hence increasing contract programming safety. Note that with the given parameters, the de-facto maximum call stack depth is limited to ~340 (down from ~1024), mitigating the harm caused by any further potential quadratic-complexity DoS attacks that rely on calls. From 1fcba3f4600f32165dad0141330c9576ca4a2375 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 19:02:44 +1100 Subject: [PATCH 0405/1085] EIP-2: Meta ref and parameters --- EIPS/eip-2.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-2.md b/EIPS/eip-2.md index dfc35cbeb7e5f..afc13e553b765 100644 --- a/EIPS/eip-2.md +++ b/EIPS/eip-2.md @@ -7,10 +7,21 @@ Type: Standard Track Category: Core Created: 2015-11-15 ``` +### Meta reference + +[Homestead](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-606.md). + +### Parameters + +| FORK_BLKNUM | CHAIN_ID | CHAIN_NAME | +|-----------------|------------|-------------| +| 1,150,000 | 1 | Main net | +| 494,000 | 2 | Morden | +| 0 | 1 | Future testnets | # Specification -If `block.number >= HOMESTEAD_FORK_BLKNUM` (e.g., 1,150,000 on livenet, 494,000 on Morden and 0 on future testnets), do the following: +If `block.number >= HOMESTEAD_FORK_BLKNUM`, do the following: 1. The gas cost *for creating contracts via a transaction* is increased from 21,000 to 53,000, i.e. if you send a transaction and the to address is the empty string, the initial gas subtracted is 53,000 plus the gas cost of the tx data, rather than 2,1000 as is currently the case. Contract creation from a contract using the `CREATE` opcode is unaffected. 2. All transaction signatures whose s-value is greater than `secp256k1n/2` are now considered invalid. The ECDSA recover precompiled contract remains unchanged and will keep accepting high s-values—this is useful e.g. if a contract recovers old Bitcoin signatures. From 5b3555763d34c3262f0fd2335f23a21bda856d89 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 19:05:32 +1100 Subject: [PATCH 0406/1085] EIP-155: Hard fork meta reference --- EIPS/eip-155.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/EIPS/eip-155.md b/EIPS/eip-155.md index 9e18730b0a95f..e65b806df72e7 100644 --- a/EIPS/eip-155.md +++ b/EIPS/eip-155.md @@ -9,6 +9,9 @@ Status: Final Created: 2016-10-14 ``` +### Hard fork meta reference +[Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md) + ### Parameters - `FORK_BLKNUM`: 2,675,000 - `CHAIN_ID`: 1 From d851740f6c1f3883d6feac8669f45c06675c5475 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 19:09:22 +1100 Subject: [PATCH 0407/1085] EIP-7: [Homestead](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-606.md) --- EIPS/eip-7.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-7.md b/EIPS/eip-7.md index 2f100778a6d90..a218f570f05b5 100644 --- a/EIPS/eip-7.md +++ b/EIPS/eip-7.md @@ -6,8 +6,11 @@ Type: Homestead feature Created: 2015-11-15 +### Hard Fork +[Homestead](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-606.md) + ### Parameters -- FORK_BLKNUM: 2,675,000 ([Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md)) +- FORK_BLKNUM: 2,675,000 - CHAIN_ID: 1 ### Overview From 85a4d3063dcdc46ffa59224581eb4c288c3d4ea8 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 19:12:00 +1100 Subject: [PATCH 0408/1085] Update parameters --- EIPS/eip-7.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-7.md b/EIPS/eip-7.md index a218f570f05b5..cc432bf186df4 100644 --- a/EIPS/eip-7.md +++ b/EIPS/eip-7.md @@ -10,8 +10,10 @@ [Homestead](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-606.md) ### Parameters -- FORK_BLKNUM: 2,675,000 -- CHAIN_ID: 1 +- Activation: + - Block >= 1,150,000 on Mainnet (CHAIN_ID = 1) + - Block >= 494,000 on Morden (CHAIN_ID = 2) + - Block >= 0 on future testnets ### Overview From bcf8f50e4c34647978b679405b16b637503e054b Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 19:56:37 +1100 Subject: [PATCH 0409/1085] EIP-155: [Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md) --- EIPS/eip-155.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-155.md b/EIPS/eip-155.md index af9b94095e6c7..1e18adbecc1be 100644 --- a/EIPS/eip-155.md +++ b/EIPS/eip-155.md @@ -9,8 +9,11 @@ Status: Final Created: 2016-10-14 ``` +### Hard fork +[Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md) + ### Parameters -- `FORK_BLKNUM`: 2,675,000 ([Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md)) +- `FORK_BLKNUM`: 2,675,000 - `CHAIN_ID`: 1 ### Specification From 24497b7074dd41f0603b702c07e3e20c2ef30d38 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 19:58:07 +1100 Subject: [PATCH 0410/1085] Hard fork ref and parameters --- EIPS/eip-160.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-160.md b/EIPS/eip-160.md index 101beb9054511..5c88e5f04c452 100644 --- a/EIPS/eip-160.md +++ b/EIPS/eip-160.md @@ -7,10 +7,12 @@ Category: Core Status: Final Created: 2016-10-20 ``` -### Parameters +### Hard fork +[Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md) -- FORK_BLKNUM: 2,675,000 ([Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md)) -- CHAIN_ID: 1 +### Parameters +- `FORK_BLKNUM`: 2,675,000 +- `CHAIN_ID`: 1 ### Specification From 1b59d8972bfb3e3ebd573407ff273596cdfa3afb Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 20:00:56 +1100 Subject: [PATCH 0411/1085] EIP-161: Hard fork ref, parameters and headings --- EIPS/eip-161.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/EIPS/eip-161.md b/EIPS/eip-161.md index cb15cb88a6d60..991e360097778 100644 --- a/EIPS/eip-161.md +++ b/EIPS/eip-161.md @@ -7,10 +7,14 @@ Category: Core Status: Final Created: 2016-10-24 ``` +### Hard fork +[Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md) + ### Parameters - `FORK_BLKNUM`: 2,675,000 - `CHAIN_ID`: 1 -# Specification + +### Specification a. Account creation transactions and the `CREATE` operation SHALL, prior to the execution of the initialisation code, **increment** the **nonce** over and above its normal starting value by **one** (for normal networks, this will be simply 1, however test-nets with non-zero default starting nonces will be different). @@ -36,7 +40,7 @@ An account _changes state_ when: - it is the source or creation of a `CREATE` operation or contract-creation transaction endowing **zero or more** value; - as the block author ("miner") it is the recipient of block-rewards or transaction-fees of **zero or more** value. -## Notes +#### Notes In the present Ethereum protocol, it should be noted that very few state changes can ultimately result in accounts that are empty following the execution of the transaction. In fact there are only four contexts that current implementations need track: - an empty account has zero value transferred to it through `CALL`; @@ -44,7 +48,7 @@ In the present Ethereum protocol, it should be noted that very few state changes - an empty account has zero value transferred to it through a message-call transaction; - an empty account has zero value transferred to it through a zero-gas-price fees transfer. -# Rationale +### Rationale Same as #158 except that several edge cases are avoided since we do not break invariants: - ~~that an account can go from having code and storage to not having code or storage mid-way through the execution of a transaction;~~ [corrected] @@ -52,11 +56,11 @@ Same as #158 except that several edge cases are avoided since we do not break in `CREATE` avoids zero in the nonce to avoid any suggestion of the oddity of `CREATE`d accounts being reaped half-way through their creation. -# Addendum (2017-08-15) +### Addendum (2017-08-15) On 2016-11-24, a consensus bug occurred due to two implementations having different behavior in the case of state reverts.[3] The specification was amended to clarify that empty account deletions are reverted when the state is reverted. -# References +### References 1. EIP-158 issue and discussion: https://github.com/ethereum/EIPs/issues/158 2. EIP-161 issue and discussion: https://github.com/ethereum/EIPs/issues/161 From d371e4ed7c817c3f5324e624d39c4b3bdb3238fb Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 20:03:00 +1100 Subject: [PATCH 0412/1085] EIP-170: Spurious Dragon ref. --- EIPS/eip-170.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-170.md b/EIPS/eip-170.md index 6ca2c505115af..ff98340458fbb 100644 --- a/EIPS/eip-170.md +++ b/EIPS/eip-170.md @@ -7,9 +7,11 @@ Category: Core Status: Final Created: 2016-11-04 ``` -### Parameters +### Hard fork +[Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md) -- `FORK_BLKNUM`: 2,675,000 ([Tangerine Whistle](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-608.md)) +### Parameters +- `FORK_BLKNUM`: 2,675,000 - `CHAIN_ID`: 1 ### Specification From 3a64ec9faaa3cbc10dfac65a97929ce28443c0b0 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 20:03:48 +1100 Subject: [PATCH 0413/1085] (main net) --- EIPS/eip-170.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-170.md b/EIPS/eip-170.md index ff98340458fbb..4dfa169e7117b 100644 --- a/EIPS/eip-170.md +++ b/EIPS/eip-170.md @@ -12,7 +12,7 @@ Created: 2016-11-04 ### Parameters - `FORK_BLKNUM`: 2,675,000 -- `CHAIN_ID`: 1 +- `CHAIN_ID`: 1 (main net) ### Specification From 7a943d25f04dcc4eda589aa3381928a8593cc977 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 20:05:58 +1100 Subject: [PATCH 0414/1085] EIP-161: (main net) --- EIPS/eip-161.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-161.md b/EIPS/eip-161.md index 991e360097778..09d6a4c29e509 100644 --- a/EIPS/eip-161.md +++ b/EIPS/eip-161.md @@ -12,7 +12,7 @@ Created: 2016-10-24 ### Parameters - `FORK_BLKNUM`: 2,675,000 -- `CHAIN_ID`: 1 +- `CHAIN_ID`: 1 (main net) ### Specification From 540fd28c782b76fee35dfcaf6c30ff6da376049f Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 20:08:27 +1100 Subject: [PATCH 0415/1085] EIP-155: (main net) --- EIPS/eip-155.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-155.md b/EIPS/eip-155.md index e65b806df72e7..d332632337bf7 100644 --- a/EIPS/eip-155.md +++ b/EIPS/eip-155.md @@ -14,7 +14,7 @@ Created: 2016-10-14 ### Parameters - `FORK_BLKNUM`: 2,675,000 -- `CHAIN_ID`: 1 +- `CHAIN_ID`: 1 (main net) ### Specification If `block.number >= FORK_BLKNUM` and `v = CHAIN_ID * 2 + 35` or `v = CHAIN_ID * 2 + 36`, then when computing the hash of a transaction for purposes of signing or recovering, instead of hashing only the first six elements (ie. nonce, gasprice, startgas, to, value, data), hash nine elements, with `v` replaced by `CHAIN_ID`, `r = 0` and `s = 0`. The currently existing signature scheme using `v = 27` and `v = 28` remains valid and continues to operate under the same rules as it does now. From ce3c5d82698bb97ba03ecf54d80e17fcdedc2913 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 21:21:08 +1100 Subject: [PATCH 0416/1085] Remove chain_IDs --- EIPS/eip-2.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/EIPS/eip-2.md b/EIPS/eip-2.md index afc13e553b765..a79d98a2b0211 100644 --- a/EIPS/eip-2.md +++ b/EIPS/eip-2.md @@ -13,11 +13,11 @@ Created: 2015-11-15 ### Parameters -| FORK_BLKNUM | CHAIN_ID | CHAIN_NAME | -|-----------------|------------|-------------| -| 1,150,000 | 1 | Main net | -| 494,000 | 2 | Morden | -| 0 | 1 | Future testnets | +| FORK_BLKNUM | CHAIN_NAME | +|-----------------|-------------| +| 1,150,000 | Main net | +| 494,000 | Morden | +| 0 | Future testnets | # Specification From f3e7dfc3bd52f6ccdee58a2f57d4bc71da1f5be3 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Fri, 26 Jan 2018 21:21:37 +1100 Subject: [PATCH 0417/1085] Remove chain_ids --- EIPS/eip-7.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-7.md b/EIPS/eip-7.md index cc432bf186df4..f33ca94350f16 100644 --- a/EIPS/eip-7.md +++ b/EIPS/eip-7.md @@ -11,8 +11,8 @@ ### Parameters - Activation: - - Block >= 1,150,000 on Mainnet (CHAIN_ID = 1) - - Block >= 494,000 on Morden (CHAIN_ID = 2) + - Block >= 1,150,000 on Mainnet + - Block >= 494,000 on Morden - Block >= 0 on future testnets ### Overview From 1d1799bd2e1c022dd3d746e2f5f28497bb6b2810 Mon Sep 17 00:00:00 2001 From: ia Date: Fri, 26 Jan 2018 19:28:59 +0900 Subject: [PATCH 0418/1085] Reference hex encoding standard --- EIPS/eip-695.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/EIPS/eip-695.md b/EIPS/eip-695.md index 70e8e9b8eff9b..c917d29ced092 100644 --- a/EIPS/eip-695.md +++ b/EIPS/eip-695.md @@ -76,5 +76,9 @@ Not currently implemented. ## Implementation Would be good to have a test to confirm that expected==got. +## Reference + +Return value `QUANTITY` adheres to standard JSON RPC hex value encoding, as documented here: https://github.com/ethereum/wiki/wiki/JSON-RPC#hex-value-encoding. + ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 99b60b5d6a686c5fd220853bbfab5dd63a2b3773 Mon Sep 17 00:00:00 2001 From: cdetrio Date: Fri, 26 Jan 2018 13:55:04 +0100 Subject: [PATCH 0419/1085] reformat from mediawiki to md --- EIPS/eip-4.mediawiki => EIPs/eip-4.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) rename EIPS/eip-4.mediawiki => EIPs/eip-4.md (92%) diff --git a/EIPS/eip-4.mediawiki b/EIPs/eip-4.md similarity index 92% rename from EIPS/eip-4.mediawiki rename to EIPs/eip-4.md index c10a1b8fe8166..fc8d1a4460bde 100644 --- a/EIPS/eip-4.mediawiki +++ b/EIPs/eip-4.md @@ -8,7 +8,7 @@ Created: 2015-11-17
-==Abstract== +# Abstract This document describes a classification scheme for EIPs, adapted from BIP123. @@ -16,22 +16,22 @@ EIPs are classified by system layers with lower numbered layers involving more i The specification defines the layers and sets forth specific criteria for deciding to which layer a particular standards EIP belongs. -==Motivation== +# Motivation Ethereum is a system involving a number of different standards. Some standards are absolute requirements for interoperability while others can be considered optional, giving implementors a choice of whether to support them. In order to have a EIP process which more closely reflects the interoperability requirements, it is necessary to categorize EIPs accordingly. Lower layers present considerably greater challenges in getting standards accepted and deployed. -==Specification== +# Specification Standards EIPs are placed in one of four layers: -# Consensus -# Networking -# API/RPC -# Applications +1. Consensus +2. Networking +3. API/RPC +4. Applications -===1. Consensus Layer=== +# 1. Consensus Layer The consensus layer defines cryptographic commitment structures. Its purpose is ensuring that anyone can locally evaluate whether a particular state and history is valid, providing settlement guarantees, and assuring eventual convergence. @@ -39,15 +39,15 @@ The consensus layer is not concerned with how messages are propagated on a netwo Disagreements over the consensus layer can result in network partitioning, or forks, where different nodes might end up accepting different incompatible histories. We further subdivide consensus layer changes into soft forks and hard forks. -====Soft Forks==== +## Soft Forks In a soft fork, some structures that were valid under the old rules are no longer valid under the new rules. Structures that were invalid under the old rules continue to be invalid under the new rules. -====Hard Forks==== +## Hard Forks In a hard fork, structures that were invalid under the old rules become valid under the new rules. -===2. Networking Layer=== +# 2. Networking Layer The networking layer specifies the Ethereum wire protocol (eth) and the Light Ethereum Subprotocol (les). RLPx is excluded and tracked in the [https://github.com/ethereum/devp2p devp2p repository]. @@ -56,12 +56,12 @@ Only a subset of subprotocols are required for basic node interoperability. Node It is always possible to add new subprotocols without breaking compatibility with existing protocols, then gradually deprecate older protocols. In this manner, the entire network can be upgraded without serious risks of service disruption. -===3. API/RPC Layer=== +# 3. API/RPC Layer The API/RPC layer specifies higher level calls accessible to applications. Support for these EIPs is not required for basic network interoperability but might be expected by some client applications. There's room at this layer to allow for competing standards without breaking basic network interoperability. -===4. Applications Layer=== +# 4. Applications Layer The applications layer specifies high level structures, abstractions, and conventions that allow different applications to support similar features and share data. From 622ce70741d1b536d26a9145ede7d0835dc24c4f Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Sat, 27 Jan 2018 00:22:53 +1100 Subject: [PATCH 0420/1085] Fix a typo, change an em dash to a semi-comma --- EIPS/eip-2.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-2.md b/EIPS/eip-2.md index a79d98a2b0211..18c4949c21b7f 100644 --- a/EIPS/eip-2.md +++ b/EIPS/eip-2.md @@ -23,8 +23,8 @@ Created: 2015-11-15 If `block.number >= HOMESTEAD_FORK_BLKNUM`, do the following: -1. The gas cost *for creating contracts via a transaction* is increased from 21,000 to 53,000, i.e. if you send a transaction and the to address is the empty string, the initial gas subtracted is 53,000 plus the gas cost of the tx data, rather than 2,1000 as is currently the case. Contract creation from a contract using the `CREATE` opcode is unaffected. -2. All transaction signatures whose s-value is greater than `secp256k1n/2` are now considered invalid. The ECDSA recover precompiled contract remains unchanged and will keep accepting high s-values—this is useful e.g. if a contract recovers old Bitcoin signatures. +1. The gas cost *for creating contracts via a transaction* is increased from 21,000 to 53,000, i.e. if you send a transaction and the to address is the empty string, the initial gas subtracted is 53,000 plus the gas cost of the tx data, rather than 21,000 as is currently the case. Contract creation from a contract using the `CREATE` opcode is unaffected. +2. All transaction signatures whose s-value is greater than `secp256k1n/2` are now considered invalid. The ECDSA recover precompiled contract remains unchanged and will keep accepting high s-values; this is useful e.g. if a contract recovers old Bitcoin signatures. 3. If contract creation does not have enough gas to pay for the final gas fee for adding the contract code to the state, the contract creation fails (i.e. goes out-of-gas) rather than leaving an empty contract. 4. Change the difficulty adjustment algorithm from the current formula: `block_diff = parent_diff + parent_diff // 2048 * (1 if block_timestamp - parent_timestamp < 13 else -1) + int(2**((block.number // 100000) - 2))` (where the ` + int(2**((block.number // 100000) - 2))` represents the exponential difficulty adjustment component) to `block_diff = parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99) + int(2**((block.number // 100000) - 2))`, where `//` is the integer division operator, eg. `6 // 2 = 3`, `7 // 2 = 3`, `8 // 2 = 4`. The `minDifficulty` still defines the minimum difficulty allowed and no adjustment may take it below this. From d666d8eed37562449ad13481973d095e09af32e1 Mon Sep 17 00:00:00 2001 From: James Ray <16969914+jamesray1@users.noreply.github.com> Date: Sat, 27 Jan 2018 00:32:10 +1100 Subject: [PATCH 0421/1085] Change hard fork heading --- EIPS/eip-155.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-155.md b/EIPS/eip-155.md index d332632337bf7..314624b0ac9e9 100644 --- a/EIPS/eip-155.md +++ b/EIPS/eip-155.md @@ -9,7 +9,7 @@ Status: Final Created: 2016-10-14 ``` -### Hard fork meta reference +### Hard fork [Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md) ### Parameters From 34e374bb288bba95e2889d5b9a27299c481a15fb Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 26 Jan 2018 18:10:11 +0100 Subject: [PATCH 0422/1085] Note that EIP-86 is going to be replaced --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a7f1fdc773996..b2b00a3fed5d6 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP # Deferred EIPs | Number | Title | Author | Layer | Status | | -------------------------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------ | ---------- | -------- | -| [86](https://github.com/ethereum/EIPs/pull/208) | Abstraction of transaction origin and signature | Vitalik Buterin | Core | Deferred | +| [86](https://github.com/ethereum/EIPs/pull/208) | Abstraction of transaction origin and signature | Vitalik Buterin | Core | Deferred (to be replaced) | | [96](https://github.com/ethereum/EIPs/pull/210) | Blockhash refactoring | Vitalik Buterin | Core | Deferred | | [145](EIPS/eip-145.md) | Bitwise shifting instructions in EVM | Alex Beregszaszi, Paweł Bylica | Core | Deferred | From fb25707cc81b451f6ea6ffcd29c5b22c5c0c609c Mon Sep 17 00:00:00 2001 From: cdetrio Date: Sat, 27 Jan 2018 13:56:29 +0100 Subject: [PATCH 0423/1085] clarify author --- EIPs/eip-4.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EIPs/eip-4.md b/EIPs/eip-4.md index fc8d1a4460bde..260d842426145 100644 --- a/EIPs/eip-4.md +++ b/EIPs/eip-4.md @@ -2,7 +2,7 @@ EIP: 4 Layer: Process Title: EIP Classification - Author: Eric Lombrozo + Author: Joseph Chow Status: Draft Type: Process Created: 2015-11-17 @@ -10,7 +10,7 @@ # Abstract -This document describes a classification scheme for EIPs, adapted from BIP123. +This document describes a classification scheme for EIPs, adapted from [BIP 123](https://github.com/bitcoin/bips/blob/master/bip-0123.mediawiki). EIPs are classified by system layers with lower numbered layers involving more intricate interoperability requirements. @@ -64,4 +64,4 @@ There's room at this layer to allow for competing standards without breaking bas # 4. Applications Layer -The applications layer specifies high level structures, abstractions, and conventions that allow different applications to support similar features and share data. +The applications layer specifies high level structures, abstractions, and conventions that allow different applications to support similar features and share data. From b8a59c959f4407b6470d4d9350de74e52e6f0c4c Mon Sep 17 00:00:00 2001 From: cdetrio Date: Sat, 27 Jan 2018 13:56:44 +0100 Subject: [PATCH 0424/1085] correct EIP 4 author on readme table --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a7f1fdc773996..264ad64a89e10 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | Number | Title | Author | Layer | Status | | ------------------------- | ------------------------------------------------------- | ----------------------------- | --------- | ---------- | | [3](EIPS/eip-3.mediawiki) | Addition of CALLDEPTH opcode | Martin Holst Swende | Core | Draft | -| [4](EIPS/eip-4.mediawiki) | EIP Classification | Eric Lombrozo | Meta | Draft | +| [4](EIPS/eip-4.mediawiki) | EIP Classification | Joseph Chow | Meta | Draft | | [5](EIPS/eip-5.md) | Gas Usage for `RETURN` and `CALL*` | Christian Reitwiessner | Core | Draft | | [101](EIPS/eip-101.md) | Serenity Currency and Crypto Abstraction | Vitalik Buterin | | Active | | [158](EIPS/eip-158.md) | State clearing | Vitalik Buterin | Core | Superseded | From f53cc2ddba0ca6ff45f36a22c5d2d44368d9c7de Mon Sep 17 00:00:00 2001 From: William Entriken Date: Sat, 27 Jan 2018 16:51:32 -0500 Subject: [PATCH 0425/1085] Clean up Accept wording --- EIPS/eip-721.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index d98ac059fdb0e..459bcb9110891 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -99,21 +99,27 @@ interface ERC721 { /// @dev This event emits when ownership of any deed changes by any /// mechanism. This event emits when deeds are created (`from` == 0) and /// destroyed (`to` == 0). Exception: during contract creation, any - /// transfers may occur without emitting `Transfer`. + /// transfers may occur without emitting `Transfer`. At the time of any transfer, + /// the "approved taker" is implicitly reset to the zero address. event Transfer(address indexed from, address indexed to, uint256 indexed deedId); - /// @dev This event emits on any successful call to - /// `approve(address _spender, uint256 _deedId)`. Exception: does not emit - /// if an owner revokes approval (`_to` == 0x0) on a deed with no existing - /// approval. + /// @dev The Approve event emits to log the "approved taker" for a deed -- whether + /// set for the first time, reaffirmed by setting the same value, or by setting to + /// to a new value. The "approved taker" is the zero address if nobody can take the + /// deed now or it is an address if that address can call `takeOwnership` to attempt + /// taking the deed. Any change to the "approved taker" for a deed SHALL cause cause + /// Approve to emit. However, an exception, the Approve event will not emit when + /// Transfer emits, this is because Transfer implicitly denotes the "approved taker" + /// is reset to the zero address. event Approval(address indexed owner, address indexed approved, uint256 indexed deedId); - /// @notice Approve a new owner to take your deed, or revoke approval by + /// @notice Set the "approved taker" for your deed, or revoke approval by /// setting the zero address. You may `approve` any number of times while - /// the deed is assigned to you, only the most recent approval matters. + /// the deed is assigned to you, only the most recent approval matters. Emits + /// an Approval event. /// @dev Throws if `msg.sender` does not own deed `_deedId` or if `_to` == /// `msg.sender`. - /// @param _deedId The deed you are granting ownership of + /// @param _deedId The deed for which you are granting approval function approve(address _to, uint256 _deedId) external payable; /// @notice Become owner of a deed for which you are currently approved From 6754461619eb5e29fa5c8750d5767b4e4cbb4f98 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Sun, 28 Jan 2018 13:34:23 -0500 Subject: [PATCH 0426/1085] Clarify invalid deeds and counting --- EIPS/eip-721.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 459bcb9110891..f9695566e5449 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -67,29 +67,28 @@ interface ERC721 { /// @notice Find the owner of a deed /// @param _deedId The identifier for a deed we are inspecting - /// @dev Deeds assigned to zero address are considered destroyed, and + /// @dev Deeds assigned to zero address are considered invalid, and /// queries about them do throw. /// @return The non-zero address of the owner of deed `_deedId`, or `throw` /// if deed `_deedId` is not tracked by this contract function ownerOf(uint256 _deedId) external view returns (address _owner); /// @notice Count deeds tracked by this contract - /// @return A count of the deeds tracked by this contract, where each one of - /// them has an assigned and queryable owner + /// @return A count of valid deeds tracked by this contract, where each one of + /// them has an assigned and queryable owner not equal to the zero address function countOfDeeds() external view returns (uint256 _count); /// @notice Count all deeds assigned to an owner - /// @dev Throws if `_owner` is the zero address, representing destroyed deeds. + /// @dev Throws if `_owner` is the zero address, representing invalid deeds. /// @param _owner An address where we are interested in deeds owned by them /// @return The number of deeds owned by `_owner`, possibly zero function countOfDeedsByOwner(address _owner) external view returns (uint256 _count); /// @notice Enumerate deeds assigned to an owner /// @dev Throws if `_index` >= `countOfDeedsByOwner(_owner)` or if - /// `_owner` is the zero address, representing destroyed deeds. + /// `_owner` is the zero address, representing invalid deeds. /// @param _owner An address where we are interested in deeds owned by them - /// @param _index A counter between zero and `countOfDeedsByOwner(_owner)`, - /// inclusive + /// @param _index A counter less than `countOfDeedsByOwner(_owner)` /// @return The identifier for the `_index`th deed assigned to `_owner`, /// (sort order not specified) function deedOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256 _deedId); @@ -104,10 +103,10 @@ interface ERC721 { event Transfer(address indexed from, address indexed to, uint256 indexed deedId); /// @dev The Approve event emits to log the "approved taker" for a deed -- whether - /// set for the first time, reaffirmed by setting the same value, or by setting to - /// to a new value. The "approved taker" is the zero address if nobody can take the + /// set for the first time, reaffirmed by setting the same value, or setting to + /// a new value. The "approved taker" is the zero address if nobody can take the /// deed now or it is an address if that address can call `takeOwnership` to attempt - /// taking the deed. Any change to the "approved taker" for a deed SHALL cause cause + /// taking the deed. Any change to the "approved taker" for a deed SHALL cause /// Approve to emit. However, an exception, the Approve event will not emit when /// Transfer emits, this is because Transfer implicitly denotes the "approved taker" /// is reset to the zero address. @@ -118,13 +117,14 @@ interface ERC721 { /// the deed is assigned to you, only the most recent approval matters. Emits /// an Approval event. /// @dev Throws if `msg.sender` does not own deed `_deedId` or if `_to` == - /// `msg.sender`. + /// `msg.sender` or if `_deedId` is not a valid deed. /// @param _deedId The deed for which you are granting approval function approve(address _to, uint256 _deedId) external payable; /// @notice Become owner of a deed for which you are currently approved /// @dev Throws if `msg.sender` is not approved to become the owner of - /// `deedId` or if `msg.sender` currently owns `_deedId`. + /// `deedId` or if `msg.sender` currently owns `_deedId` or if `_deedId is not a + /// valid deed. /// @param _deedId The deed that is being transferred function takeOwnership(uint256 _deedId) external payable; } @@ -191,7 +191,7 @@ contract ERC721Enumerable is ERC721 { /// @notice Enumerate active deeds /// @dev Throws if `_index` >= `countOfDeeds()` - /// @param _index A counter between zero and `countOfDeeds()`, inclusive + /// @param _index A counter less than `countOfDeeds()` /// @return The identifier for the `_index`th deed, (sort order not /// specified) function deedByIndex(uint256 _index) external view returns (uint256 _deedId); @@ -202,7 +202,7 @@ contract ERC721Enumerable is ERC721 { /// @notice Enumerate owners /// @dev Throws if `_index` >= `countOfOwners()` - /// @param _index A counter between zero and `countOfOwners()`, inclusive + /// @param _index A counter less than `countOfOwners()` /// @return The address of the `_index`th owner (sort order not specified) function ownerByIndex(uint256 _index) external view returns (address _owner); } @@ -234,7 +234,7 @@ This definition is consistent with the fact that ERC-721 contracts track ownersh **Deed identifiers** -The basis of this standard is that every deed is identified by a unique 256-bit unsigned integer within its tracking contract. This ID number MUST NOT change for the life of the contract. The pair `(contract address, asset ID)` will then be a globally unique and fully-qualified identifier for a specific deed within the Ethereum ecosystem. While some contracts may find it convenient to start with ID 0 and simply increment by one for each new NFT, callers MUST NOT assume that ID numbers have any specific pattern to them, and should treat the ID as a "black box". Also note that a deeds MAY be destroyed and as such you cannot simply count from from `0` to `countOfDeeds()`. Please see the enumerations functions for a supported enumeration interface. +The basis of this standard is that every deed is identified by a unique 256-bit unsigned integer within its tracking contract. This ID number MUST NOT change for the life of the contract. The pair `(contract address, asset ID)` will then be a globally unique and fully-qualified identifier for a specific deed within the Ethereum ecosystem. While some contracts may find it convenient to start with ID 0 and simply increment by one for each new NFT, callers MUST NOT assume that ID numbers have any specific pattern to them, and should treat the ID as a "black box". Also note that a deeds MAY become invalid (be destroyed). Please see the enumerations functions for a supported enumeration interface. **Transfer mechanism** From 1ca7dfb9eb6c4dd6685b4fca88b3e8e7a55fa15a Mon Sep 17 00:00:00 2001 From: William Entriken Date: Sun, 28 Jan 2018 14:06:57 -0500 Subject: [PATCH 0427/1085] Fix signature, thanks @Beskhue --- EIPS/eip-721.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index f9695566e5449..80be7bb253e94 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -49,11 +49,11 @@ interface ERC721 { // bytes4(keccak256('supportsInterface(bytes4)')); /// @dev ERC-165 (draft) interface signature for ERC721 - // bytes4 internal constant INTERFACE_SIGNATURE_ERC721 = // 0xe55729f5 + // bytes4 internal constant INTERFACE_SIGNATURE_ERC721 = // 0xda671b9b // bytes4(keccak256('ownerOf(uint256)')) ^ // bytes4(keccak256('countOfDeeds()')) ^ // bytes4(keccak256('countOfDeedsByOwner(address)')) ^ - // bytes4(keccak256('deedOfOwnerByIndex(uint256)')) ^ + // bytes4(keccak256('deedOfOwnerByIndex(address,uint256)')) ^ // bytes4(keccak256('approve(address,uint256)')) ^ // bytes4(keccak256('takeOwnership(uint256)')); From c0e6345a4d487a94c3c627df58c915c75169fd2e Mon Sep 17 00:00:00 2001 From: William Entriken Date: Sun, 28 Jan 2018 17:22:35 -0500 Subject: [PATCH 0428/1085] Use interface keyword --- EIPS/eip-721.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 80be7bb253e94..9818b989d905f 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -138,7 +138,7 @@ Implementations MAY also choose to implement the **ERC-721 Metadata extension**. /// @title Metadata extension to ERC-721 interface /// @author William Entriken (https://phor.net) /// @dev Specification at https://github.com/ethereum/eips/issues/XXXX -interface ERC721Metadata is ERC721 { +interface ERC721Metadata { /// @dev ERC-165 (draft) interface signature for ERC721 // bytes4 internal constant INTERFACE_SIGNATURE_ERC721Metadata = // 0x2a786f11 @@ -181,7 +181,7 @@ A second extension, the **ERC-721 Accountability Extension**, is OPTIONAL and al /// @title Enumeration extension to ERC-721 interface /// @author William Entriken (https://phor.net) /// @dev Specification at https://github.com/ethereum/eips/issues/XXXX -contract ERC721Enumerable is ERC721 { +interface ERC721Enumerable { /// @dev ERC-165 (draft) interface signature for ERC721 // bytes4 internal constant INTERFACE_SIGNATURE_ERC721Enumerable = // 0xa5e86824 From 0ad1810fd6cf3090bf9d87f6635906a6ad70fb9d Mon Sep 17 00:00:00 2001 From: Carl Larson Date: Mon, 29 Jan 2018 13:19:13 +0000 Subject: [PATCH 0429/1085] added eip-reduce_block_reward draft 1 --- EIPS/eip-reduce_block_reward.md | 38 +++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 EIPS/eip-reduce_block_reward.md diff --git a/EIPS/eip-reduce_block_reward.md b/EIPS/eip-reduce_block_reward.md new file mode 100644 index 0000000000000..77f0449bb1bf7 --- /dev/null +++ b/EIPS/eip-reduce_block_reward.md @@ -0,0 +1,38 @@ +## Preamble + + EIP: + Title: Reduce block reward + Author: Carl Larson + Type: Standard Track + Category: Core + Status: Draft + Created: 2018-01-29 + +## Simple Summary +Reduce the block reward to 1 ETH. + +## Abstract +The current public Ethereum network has a hashrate that corresponds to a tremendous level of energy consumption. As this energy consumption has a correlated environmental cost the network participants have an ethical obligation to ensure this cost is not higher than necessary. At this time, the most direct way to reduce this cost is to lower the block reward in order to limit the appeal of ETH mining. Unchecked growth in hashrate is also counterproductive from a security standpoint. + +## Motivation +The current public Ethereum network has a hashrate of 205 TH/s). This hashrate corresponds to a **lower bound** for power usage of roughly 710MW, which would correspond to a yearly energy consumption of 6.2TWh (roughly 0.03% of [total](https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption) global electricity consumption). [Assuming](http://www.carbonindependent.org/sources_home_energy.html) a rate of carbon emmisions of 0.527 kg/kWh this means at it's present hashrate the network contributes more than 1 million tons of CO2 per month. These numbers assume the [best GPU, perfectly overclocked](http://www.legitreviews.com/geforce-gtx-1070-ethereum-mining-small-tweaks-great-hashrate-low-power_195451), and running on a PC without it's own power draw, so again the true numbers are likely much higher. A future switch to full Proof of Stake will solve this issue entirely. Yet that switch remains enough in the future that action should be taken in the interim to limit excess harmful side affects of the present network. + +## Specification +Block reward to be changed to 1 ETH / block. +If any resulting hard forks need a name for that name to maybe be Perinthos. + +## Rationale +partly TBD +The network hashrate provides security by reducing the likelihood that an adversary could mount a 51% attack. A static block reward means that factors (price) may be such that participation in mining grows unchecked. This growth may be counterproductive and work to also grow and potential pool of adversaries. The means we have to arrest this growth is to reduce the appeal of mining and the most direct way to do that is to reduce the block reward. + +## Backwards Compatibility +This EIP is consensus incompatible with the current public Ethereum chain and would cause a hard fork when enacted. The resulting fork would allow users to chose between two chains: a chain with a block reward of 1 ETH/block and another with a block reward of 3 ETH/block. This is a good choice to allow users to make. + +## Test Cases +Tests have, as yet, not been completed. + +## Implementation +A [fork of the go repo](https://github.com/cslarson/go-ethereum/tree/reduce-block-reward) with changes to reflect a block reward reduced to 1 ETH, activated at a fork to be called Perinthos. + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 0748f5976667c890b00013442da2371cd7c741a4 Mon Sep 17 00:00:00 2001 From: Carl Larson Date: Mon, 29 Jan 2018 14:06:56 +0000 Subject: [PATCH 0430/1085] assign 858 to reduce_block_reward eip --- EIPS/{eip-reduce_block_reward.md => eip-858.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename EIPS/{eip-reduce_block_reward.md => eip-858.md} (99%) diff --git a/EIPS/eip-reduce_block_reward.md b/EIPS/eip-858.md similarity index 99% rename from EIPS/eip-reduce_block_reward.md rename to EIPS/eip-858.md index 77f0449bb1bf7..4229162601a73 100644 --- a/EIPS/eip-reduce_block_reward.md +++ b/EIPS/eip-858.md @@ -1,6 +1,6 @@ ## Preamble - EIP: + EIP: 858 Title: Reduce block reward Author: Carl Larson Type: Standard Track From ea084caabdf3b37c2afe9f24eb66a9979232266f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 30 Jan 2018 22:28:24 +0100 Subject: [PATCH 0431/1085] EIP-145: Add test cases --- EIPS/eip-145.md | 249 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 248 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-145.md b/EIPS/eip-145.md index 6cd270c33eda1..15fb26aecd81d 100644 --- a/EIPS/eip-145.md +++ b/EIPS/eip-145.md @@ -79,7 +79,254 @@ The newly introduced instructions have no effect on bytecode created in the past ## Test Cases -TBA +### `SHL` (shift left) + +1. ``` + PUSH 0x0000000000000000000000000000000000000000000000000000000000000001 + PUSH 0x00 + SHL + --- + 0x0000000000000000000000000000000000000000000000000000000000000001 + ``` +2. ``` + PUSH 0x0000000000000000000000000000000000000000000000000000000000000001 + PUSH 0x01 + SHL + --- + 0x0000000000000000000000000000000000000000000000000000000000000002 + ``` +3. ``` + PUSH 0x0000000000000000000000000000000000000000000000000000000000000001 + PUSH 0xff + SHL + --- + 0x8000000000000000000000000000000000000000000000000000000000000000 + ``` +4. ``` + PUSH 0x0000000000000000000000000000000000000000000000000000000000000001 + PUSH 0x0100 + SHL + --- + 0x0000000000000000000000000000000000000000000000000000000000000000 + ``` +5. ``` + PUSH 0x0000000000000000000000000000000000000000000000000000000000000001 + PUSH 0x0101 + SHL + --- + 0x0000000000000000000000000000000000000000000000000000000000000000 + ``` +6. ``` + PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + PUSH 0x00 + SHL + --- + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ``` +7. ``` + PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + PUSH 0x01 + SHL + --- + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe + ``` +8. ``` + PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + PUSH 0xff + SHL + --- + 0x8000000000000000000000000000000000000000000000000000000000000000 + ``` +9. ``` + PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + PUSH 0x0100 + SHL + --- + 0x0000000000000000000000000000000000000000000000000000000000000000 + ``` +10. ``` + PUSH 0x0000000000000000000000000000000000000000000000000000000000000000 + PUSH 0x01 + SHL + --- + 0x0000000000000000000000000000000000000000000000000000000000000000 + ``` + + +### `SHR` (logical shift right) + +1. ``` + PUSH 0x0000000000000000000000000000000000000000000000000000000000000001 + PUSH 0x00 + SHR + --- + 0x0000000000000000000000000000000000000000000000000000000000000001 + ``` +2. ``` + PUSH 0x0000000000000000000000000000000000000000000000000000000000000001 + PUSH 0x01 + SHR + --- + 0x0000000000000000000000000000000000000000000000000000000000000000 + ``` +3. ``` + PUSH 0x8000000000000000000000000000000000000000000000000000000000000000 + PUSH 0x01 + SHR + --- + 0x4000000000000000000000000000000000000000000000000000000000000000 + ``` +4. ``` + PUSH 0x8000000000000000000000000000000000000000000000000000000000000000 + PUSH 0xff + SHR + --- + 0x0000000000000000000000000000000000000000000000000000000000000001 + ``` +5. ``` + PUSH 0x8000000000000000000000000000000000000000000000000000000000000000 + PUSH 0x0100 + SHR + --- + 0x0000000000000000000000000000000000000000000000000000000000000000 + ``` +6. ``` + PUSH 0x8000000000000000000000000000000000000000000000000000000000000000 + PUSH 0x0101 + SHR + --- + 0x0000000000000000000000000000000000000000000000000000000000000000 + ``` +7. ``` + PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + PUSH 0x00 + SHR + --- + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ``` +8. ``` + PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + PUSH 0x01 + SHR + --- + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ``` +9. ``` + PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + PUSH 0xff + SHR + --- + 0x0000000000000000000000000000000000000000000000000000000000000001 + ``` +10. ``` + PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + PUSH 0x0100 + SHR + --- + 0x0000000000000000000000000000000000000000000000000000000000000000 + ``` +11. ``` + PUSH 0x0000000000000000000000000000000000000000000000000000000000000000 + PUSH 0x01 + SHR + --- + 0x0000000000000000000000000000000000000000000000000000000000000000 + ``` + +### `SAR` (arithmetic shift right) + +1. ``` + PUSH 0x0000000000000000000000000000000000000000000000000000000000000001 + PUSH 0x00 + SAR + --- + 0x0000000000000000000000000000000000000000000000000000000000000001 + ``` +2. ``` + PUSH 0x0000000000000000000000000000000000000000000000000000000000000001 + PUSH 0x01 + SAR + --- + 0x0000000000000000000000000000000000000000000000000000000000000000 + ``` +3. ``` + PUSH 0x8000000000000000000000000000000000000000000000000000000000000000 + PUSH 0x01 + SAR + --- + 0x12000000000000000000000000000000000000000000000000000000000000000 + ``` +4. ``` + PUSH 0x8000000000000000000000000000000000000000000000000000000000000000 + PUSH 0xff + SAR + --- + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ``` +5. ``` + PUSH 0x8000000000000000000000000000000000000000000000000000000000000000 + PUSH 0x0100 + SAR + --- + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ``` +6. ``` + PUSH 0x8000000000000000000000000000000000000000000000000000000000000000 + PUSH 0x0101 + SAR + --- + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ``` +7. ``` + PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + PUSH 0x00 + SAR + --- + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ``` +8. ``` + PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + PUSH 0x01 + SAR + --- + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ``` +9. ``` + PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + PUSH 0xff + SAR + --- + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ``` +10. ``` + PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + PUSH 0x0100 + SAR + --- + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ``` +11. ``` + PUSH 0x0000000000000000000000000000000000000000000000000000000000000000 + PUSH 0x01 + SAR + --- + 0x0000000000000000000000000000000000000000000000000000000000000000 + ``` +12. ``` + PUSH 0x4000000000000000000000000000000000000000000000000000000000000000 + PUSH 0xfe + SAR + --- + 0x0000000000000000000000000000000000000000000000000000000000000001 + ``` +13. ``` + PUSH 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + PUSH 0xf8 + SAR + --- + 0x000000000000000000000000000000000000000000000000000000000000007f + ``` + ## Implementation From 49e86ff026c258675945d4f6db4580b2e827acc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Wed, 31 Jan 2018 17:51:59 +0100 Subject: [PATCH 0432/1085] EIP-145: Add more test cases --- EIPS/eip-145.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/EIPS/eip-145.md b/EIPS/eip-145.md index 15fb26aecd81d..094f52820442f 100644 --- a/EIPS/eip-145.md +++ b/EIPS/eip-145.md @@ -151,6 +151,13 @@ The newly introduced instructions have no effect on bytecode created in the past --- 0x0000000000000000000000000000000000000000000000000000000000000000 ``` +11. ``` + PUSH 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + PUSH 0x01 + SHL + --- + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe + ``` ### `SHR` (logical shift right) @@ -326,6 +333,27 @@ The newly introduced instructions have no effect on bytecode created in the past --- 0x000000000000000000000000000000000000000000000000000000000000007f ``` +14. ``` + PUSH 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + PUSH 0xfe + SAR + --- + 0x0000000000000000000000000000000000000000000000000000000000000001 + ``` +15. ``` + PUSH 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + PUSH 0xff + SAR + --- + 0x0000000000000000000000000000000000000000000000000000000000000000 + ``` +16. ``` + PUSH 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + PUSH 0x100 + SAR + --- + 0x0000000000000000000000000000000000000000000000000000000000000000 + ``` ## Implementation From ea4ed40d451fa54f4d05739dba86cf0714454ea4 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Thu, 1 Feb 2018 21:42:43 -0500 Subject: [PATCH 0433/1085] Add deed name, rename return variables --- EIPS/eip-721.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 9818b989d905f..92f9400892284 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -149,11 +149,15 @@ interface ERC721Metadata { /// @notice A descriptive name for a collection of deeds managed by this /// contract /// @dev Wallets and exchanges MAY display this to the end user. - function name() public pure returns (string _deedName); + function name() public pure returns (string _name); /// @notice An abbreviated name for deeds managed by this contract /// @dev Wallets and exchanges MAY display this to the end user. - function symbol() public pure returns (string _deedSymbol); + function symbol() public pure returns (string _symbol); + + /// @notice A distinct name for a deed managed by this contract + /// @dev Wallets and exchanges MAY display this to the end user. + function deedName(uint256 _deedId) public pure returns (string _deedName); /// @notice A distinct URI (RFC 3986) for a given token. /// @dev If: @@ -171,7 +175,7 @@ interface ERC721Metadata { /// Wallets and exchanges MAY display this to the end user. /// Consider making any images at a width between 320 and 1080 pixels and /// aspect ratio between 1.91:1 and 4:5 inclusive. - function deedUri(uint256 _deedId) external view returns (string _uri); + function deedUri(uint256 _deedId) external view returns (string _deedUri); } ``` From 6149eccfcafc08ea8911be98543bb3435dcb53bd Mon Sep 17 00:00:00 2001 From: William Entriken Date: Thu, 1 Feb 2018 21:54:01 -0500 Subject: [PATCH 0434/1085] Update deed word choice explanation --- EIPS/eip-721.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 92f9400892284..d6039b417fe36 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -232,13 +232,13 @@ The noun deed is defined in the Oxford Dictionary as: > A legal document that is signed and delivered, especially one regarding the ownership of property or legal rights. -This definition is consistent with the fact that ERC-721 contracts track ownership of other things, such as houses, pictures of kittens or collectable cards. If you gain ownership of a house via ERC-721 then the thing that the ERC-721 contract tracks is the *deed*, the place where you live is the *asset*. +This definition is consistent with the fact that ERC-721 contracts track ownership of other things, such as houses, pictures of kittens or collectable cards. If you gain ownership of a house via ERC-721 then the thing that the ERC-721 contract tracks is the *deed*, the place where you live is the *asset*. This standard is not concerned with the *collectable*, *item*, *thing*, or *asset* that you own -- we use these words interchangeably. *Alternatives considered: non-fungible token, title, token, asset, equity, ticket* **Deed identifiers** -The basis of this standard is that every deed is identified by a unique 256-bit unsigned integer within its tracking contract. This ID number MUST NOT change for the life of the contract. The pair `(contract address, asset ID)` will then be a globally unique and fully-qualified identifier for a specific deed within the Ethereum ecosystem. While some contracts may find it convenient to start with ID 0 and simply increment by one for each new NFT, callers MUST NOT assume that ID numbers have any specific pattern to them, and should treat the ID as a "black box". Also note that a deeds MAY become invalid (be destroyed). Please see the enumerations functions for a supported enumeration interface. +The basis of this standard is that every deed is identified by a unique 256-bit unsigned integer within its tracking contract. This ID number MUST NOT change for the life of the contract. The pair `(contract address, deed ID)` will then be a globally unique and fully-qualified identifier for a specific deed within the Ethereum ecosystem. While some contracts may find it convenient to start with ID 0 and simply increment by one for each new NFT, callers MUST NOT assume that ID numbers have any specific pattern to them, and should treat the ID as a "black box". Also note that a deeds MAY become invalid (be destroyed). Please see the enumerations functions for a supported enumeration interface. **Transfer mechanism** From 846f01bf0c2e60ce6b04cd05bcbddfdc76a86105 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 2 Feb 2018 14:16:59 +0100 Subject: [PATCH 0435/1085] EIP-868: Node Discovery v4 ENR Extension --- EIPS/eip-868.md | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 EIPS/eip-868.md diff --git a/EIPS/eip-868.md b/EIPS/eip-868.md new file mode 100644 index 0000000000000..33fc329a3d616 --- /dev/null +++ b/EIPS/eip-868.md @@ -0,0 +1,54 @@ +# Preamble + + EIP: 868 + Title: Node Discovery v4 ENR Extension + Author: Felix Lange + Type: Standard Track + Category: Networking + Status: Draft + Created: 2018-02-02 + Requires: EIP-8, EIP-778 + +# Abstract + +This EIP defines an extension to Node Discovery Protocol v4 to enable authoritative +resolution of Ethereum Node Records (ENR). + +# Motivation + +To bridge current and future discovery networks and to aid the implementation of other +relay mechanisms for ENR such as DNS, we need a way to request the most up-to-date version +of a node record. + +# Specification + +Implementations of Node Discovery Protocol v4 should support two new packet types, a request +and reply of the node record. The new packets are: + +### enrRequest (0x05) + +RLP: `[ expiration ]` + +When a packet of this type is received, the node should reply with an enrResponse packet +containing the current version of its record. + +To guard against amplification attacks, the sender of enrRequest should have replied to a +ping packet recently. The expiration field, a UNIX timestamp, should be handled as for all +other existing packets, i.e. no reply should be sent if it refers to a time in the past. + +### enrResponse (0x06) + +RLP: `[ requestHash, ENR ]` + +This packet is the response to enrRequest. + +- `requestHash` is the hash of the entire enrRequest packet being replied to. +- `ENR` is the node record. + +The recipient of the packet should verify that the node record is signed by node who +sent enrResponse. + +# Copyright + +Copyright and related rights waived via CC0. + From e801dfaa61045aa7062b3671b5cc21f028f29341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 2 Feb 2018 18:20:04 +0100 Subject: [PATCH 0436/1085] EIP-145: Fix a test case --- EIPS/eip-145.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-145.md b/EIPS/eip-145.md index 094f52820442f..c993af140ab7a 100644 --- a/EIPS/eip-145.md +++ b/EIPS/eip-145.md @@ -261,7 +261,7 @@ The newly introduced instructions have no effect on bytecode created in the past PUSH 0x01 SAR --- - 0x12000000000000000000000000000000000000000000000000000000000000000 + 0xc000000000000000000000000000000000000000000000000000000000000000 ``` 4. ``` PUSH 0x8000000000000000000000000000000000000000000000000000000000000000 From 539de8e40ac6edae2bf7f8642a5256ff11471f6b Mon Sep 17 00:00:00 2001 From: Carl Larson Date: Mon, 5 Feb 2018 11:26:01 +0000 Subject: [PATCH 0437/1085] fix rate of network carbon emmisions --- EIPS/eip-858.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-858.md b/EIPS/eip-858.md index 4229162601a73..1a53b837eaaa7 100644 --- a/EIPS/eip-858.md +++ b/EIPS/eip-858.md @@ -15,7 +15,7 @@ Reduce the block reward to 1 ETH. The current public Ethereum network has a hashrate that corresponds to a tremendous level of energy consumption. As this energy consumption has a correlated environmental cost the network participants have an ethical obligation to ensure this cost is not higher than necessary. At this time, the most direct way to reduce this cost is to lower the block reward in order to limit the appeal of ETH mining. Unchecked growth in hashrate is also counterproductive from a security standpoint. ## Motivation -The current public Ethereum network has a hashrate of 205 TH/s). This hashrate corresponds to a **lower bound** for power usage of roughly 710MW, which would correspond to a yearly energy consumption of 6.2TWh (roughly 0.03% of [total](https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption) global electricity consumption). [Assuming](http://www.carbonindependent.org/sources_home_energy.html) a rate of carbon emmisions of 0.527 kg/kWh this means at it's present hashrate the network contributes more than 1 million tons of CO2 per month. These numbers assume the [best GPU, perfectly overclocked](http://www.legitreviews.com/geforce-gtx-1070-ethereum-mining-small-tweaks-great-hashrate-low-power_195451), and running on a PC without it's own power draw, so again the true numbers are likely much higher. A future switch to full Proof of Stake will solve this issue entirely. Yet that switch remains enough in the future that action should be taken in the interim to limit excess harmful side affects of the present network. +The current public Ethereum network has a hashrate of 224 TH/s). This hashrate corresponds to a **lower bound** for power usage of roughly 793MW, which would correspond to a yearly energy consumption of 6.95TWh (roughly 0.032% of [total](https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption) global electricity consumption). [Assuming](http://www.carbonindependent.org/sources_home_energy.html) a rate of carbon emmisions of 0.527 kg/kWh this means at it's present hashrate the network contributes more than **10,000 tons of CO2 per day** ([math](https://docs.google.com/spreadsheets/d/1Q2DvnsUzgy7nQXVAkbNgvxqPfU56cGx4ubx6H8Dg6pw/edit#gid=1934769196)). These numbers assume the [best GPU, perfectly overclocked](http://www.legitreviews.com/geforce-gtx-1070-ethereum-mining-small-tweaks-great-hashrate-low-power_195451), and running on a PC without it's own power draw, so again the true numbers are higher. A future switch to full Proof of Stake will solve this issue entirely. Yet that switch remains enough in the future that action should be taken in the interim to limit excess harmful side affects of the present network. ## Specification Block reward to be changed to 1 ETH / block. From 36c592976de3cae0131b4388e9d80c1799eccf4b Mon Sep 17 00:00:00 2001 From: Carl Larson Date: Thu, 8 Feb 2018 14:03:14 +0000 Subject: [PATCH 0438/1085] it's -> its --- EIPS/eip-858.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-858.md b/EIPS/eip-858.md index 1a53b837eaaa7..94133d74824cd 100644 --- a/EIPS/eip-858.md +++ b/EIPS/eip-858.md @@ -15,7 +15,7 @@ Reduce the block reward to 1 ETH. The current public Ethereum network has a hashrate that corresponds to a tremendous level of energy consumption. As this energy consumption has a correlated environmental cost the network participants have an ethical obligation to ensure this cost is not higher than necessary. At this time, the most direct way to reduce this cost is to lower the block reward in order to limit the appeal of ETH mining. Unchecked growth in hashrate is also counterproductive from a security standpoint. ## Motivation -The current public Ethereum network has a hashrate of 224 TH/s). This hashrate corresponds to a **lower bound** for power usage of roughly 793MW, which would correspond to a yearly energy consumption of 6.95TWh (roughly 0.032% of [total](https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption) global electricity consumption). [Assuming](http://www.carbonindependent.org/sources_home_energy.html) a rate of carbon emmisions of 0.527 kg/kWh this means at it's present hashrate the network contributes more than **10,000 tons of CO2 per day** ([math](https://docs.google.com/spreadsheets/d/1Q2DvnsUzgy7nQXVAkbNgvxqPfU56cGx4ubx6H8Dg6pw/edit#gid=1934769196)). These numbers assume the [best GPU, perfectly overclocked](http://www.legitreviews.com/geforce-gtx-1070-ethereum-mining-small-tweaks-great-hashrate-low-power_195451), and running on a PC without it's own power draw, so again the true numbers are higher. A future switch to full Proof of Stake will solve this issue entirely. Yet that switch remains enough in the future that action should be taken in the interim to limit excess harmful side affects of the present network. +The current public Ethereum network has a hashrate of 224 TH/s). This hashrate corresponds to a **lower bound** for power usage of roughly 793MW, which would correspond to a yearly energy consumption of 6.95TWh (roughly 0.032% of [total](https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption) global electricity consumption). [Assuming](http://www.carbonindependent.org/sources_home_energy.html) a rate of carbon emmisions of 0.527 kg/kWh this means at it's present hashrate the network contributes more than **10,000 tons of CO2 per day** ([math](https://docs.google.com/spreadsheets/d/1Q2DvnsUzgy7nQXVAkbNgvxqPfU56cGx4ubx6H8Dg6pw/edit#gid=1934769196)). These numbers assume the [best GPU, perfectly overclocked](http://www.legitreviews.com/geforce-gtx-1070-ethereum-mining-small-tweaks-great-hashrate-low-power_195451), and running on a PC without its own power draw, so again the true numbers are higher. A future switch to full Proof of Stake will solve this issue entirely. Yet that switch remains enough in the future that action should be taken in the interim to limit excess harmful side affects of the present network. ## Specification Block reward to be changed to 1 ETH / block. From 4fcc646270e4197edd10dc16e3a10d73f41d5c6f Mon Sep 17 00:00:00 2001 From: Carl Larson Date: Thu, 8 Feb 2018 15:19:32 +0000 Subject: [PATCH 0439/1085] removed CO2 contribution numbers until they can be calculated more accurately, added power calculations --- EIPS/eip-858.md | 2 +- EIPS/eip-858/calculations.md | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 EIPS/eip-858/calculations.md diff --git a/EIPS/eip-858.md b/EIPS/eip-858.md index 94133d74824cd..e111e4acb8bb6 100644 --- a/EIPS/eip-858.md +++ b/EIPS/eip-858.md @@ -15,7 +15,7 @@ Reduce the block reward to 1 ETH. The current public Ethereum network has a hashrate that corresponds to a tremendous level of energy consumption. As this energy consumption has a correlated environmental cost the network participants have an ethical obligation to ensure this cost is not higher than necessary. At this time, the most direct way to reduce this cost is to lower the block reward in order to limit the appeal of ETH mining. Unchecked growth in hashrate is also counterproductive from a security standpoint. ## Motivation -The current public Ethereum network has a hashrate of 224 TH/s). This hashrate corresponds to a **lower bound** for power usage of roughly 793MW, which would correspond to a yearly energy consumption of 6.95TWh (roughly 0.032% of [total](https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption) global electricity consumption). [Assuming](http://www.carbonindependent.org/sources_home_energy.html) a rate of carbon emmisions of 0.527 kg/kWh this means at it's present hashrate the network contributes more than **10,000 tons of CO2 per day** ([math](https://docs.google.com/spreadsheets/d/1Q2DvnsUzgy7nQXVAkbNgvxqPfU56cGx4ubx6H8Dg6pw/edit#gid=1934769196)). These numbers assume the [best GPU, perfectly overclocked](http://www.legitreviews.com/geforce-gtx-1070-ethereum-mining-small-tweaks-great-hashrate-low-power_195451), and running on a PC without its own power draw, so again the true numbers are higher. A future switch to full Proof of Stake will solve this issue entirely. Yet that switch remains enough in the future that action should be taken in the interim to limit excess harmful side affects of the present network. +The current public Ethereum network has a hashrate of 232 TH/s). This hashrate corresponds to a **lower bound** for power usage of roughly [821 MW](eip-858/calculations.md) and yearly energy consumption of 7.2 TWh (roughly 0.033% of [total](https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption) global electricity consumption). A future switch to full Proof of Stake will solve this issue entirely. Yet that switch remains enough in the future that action should be taken in the interim to limit excess harmful side affects of the present network. ## Specification Block reward to be changed to 1 ETH / block. diff --git a/EIPS/eip-858/calculations.md b/EIPS/eip-858/calculations.md new file mode 100644 index 0000000000000..893ad99331c35 --- /dev/null +++ b/EIPS/eip-858/calculations.md @@ -0,0 +1,24 @@ +| Variable | Symbol | Value | Unit | Source | +| -------------------|--------------|---------------|---------------|--------| +| Network Hashrate |HN | 232001 | GH/s | https://etherscan.io/chart/hashrate | +| Power/Hashrate |PH | 3.54 | W*s/MH | http://www.legitreviews.com/geforce-gtx-1070-ethereum-mining-small-tweaks-great-hashrate-low-power_195451, https://www.reddit.com/r/ethereum/comments/7vewys/10000_tons_co2_per_day_and_climbing_eip_858/dtrswyz/ | + + +## Network Power Consumption (PNetwork) + +A baseline value for network power consumption can be found by multiplying the total network hashrate with a "best case" value for the power/hashrate ratio that a miner can achieve. + +PN = HN x PH +PN = 232001 (GH/s) x 3.54 (W*s/MH) x 1000 (GH/MH) / 10^6 (W/MW) +PN = 821 MW + +As a side note, people often confuse power (W) and energy (power x time, eg. Wh). For instance, assuming an average daily PNd of 821 MW we can calculate that days Energy consumption by multiplying by the number of hours in a day. + +ENd = PNd x Td +ENd = 821 (MW) x 24 (h/d) / 1000 (GW/MW) +ENd = 19.7 GWh + + +## Network CO2 contribution + +Work in progress From 7cbc47edceadde23b877c78acee98169451e2b32 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 9 Feb 2018 17:51:39 +0100 Subject: [PATCH 0440/1085] Add finalized but active table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EIP-1 is in the wrong table and no table exists for EIPs that are both Finalized and Active. Quoting the EIP: > Some Informational and Process EIPs may also have a status of “Active” if they are never meant to be completed. E.g. EIP 1 (this EIP). This can lead to confusion just like it happened [here](https://github.com/ethereum/EIPs/pull/867#issuecomment-364483227). To avoid that I am moving the EIP in the Readme to its own special table. --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 12042ec82ee5f..f67d9017a866c 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,6 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP # Finalized EIPs (standards that have been adopted) | Number | Title | Author | Layer | Status | | -------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------| ---------- | -------- | -| [1](EIPS/eip-1.md) | EIP Purpose and Guidelines | Martin Becze, Hudson Jameson | Meta | Final | | [2](EIPS/eip-2.md) | Homestead Hard-fork Changes | Vitalik Buterin | Core | Final | | [6](EIPS/eip-6.md) | Renaming Suicide Opcode | Hudson Jameson | Interface | Final | | [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Core | Final | @@ -62,6 +61,12 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [658](https://github.com/ethereum/EIPs/pull/658) | Embedding transaction status code in receipts | Nick Johnson | Core | Final | | [706](EIPS/eip-706.md) | DEVp2p snappy compression | Péter Szilágyi | Networking | Final | +# Active EIPs (standards that have been adopted but never meant to be completed) + +| Number | Title | Author | Layer | Status | +| -------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------| ---------- | -------- | +| [1](EIPS/eip-1.md) | EIP Purpose and Guidelines | Martin Becze, Hudson Jameson | Meta | Active | + # Past Hard Forks | Codename | Aliases | Block number | Date (UTC) | |-------------------------------------- |---------------------------- |----------------|------------| From 2cde480ba727a80d264e14d8e3507b46a1c4c3cc Mon Sep 17 00:00:00 2001 From: Carl Larson Date: Fri, 9 Feb 2018 18:29:26 +0000 Subject: [PATCH 0441/1085] fix units --- EIPS/eip-858/calculations.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/EIPS/eip-858/calculations.md b/EIPS/eip-858/calculations.md index 893ad99331c35..8abeff773cf4d 100644 --- a/EIPS/eip-858/calculations.md +++ b/EIPS/eip-858/calculations.md @@ -4,19 +4,24 @@ | Power/Hashrate |PH | 3.54 | W*s/MH | http://www.legitreviews.com/geforce-gtx-1070-ethereum-mining-small-tweaks-great-hashrate-low-power_195451, https://www.reddit.com/r/ethereum/comments/7vewys/10000_tons_co2_per_day_and_climbing_eip_858/dtrswyz/ | -## Network Power Consumption (PNetwork) +## Network Power Consumption (PN) A baseline value for network power consumption can be found by multiplying the total network hashrate with a "best case" value for the power/hashrate ratio that a miner can achieve. -PN = HN x PH -PN = 232001 (GH/s) x 3.54 (W*s/MH) x 1000 (GH/MH) / 10^6 (W/MW) -PN = 821 MW +> PN = HN x PH +> +> PN = 232001 (GH/s) x 3.54 (W*s/MH) x 1000 (MH/GH) / 10^6 (W/MW) +> +> PN = 821 MW As a side note, people often confuse power (W) and energy (power x time, eg. Wh). For instance, assuming an average daily PNd of 821 MW we can calculate that days Energy consumption by multiplying by the number of hours in a day. -ENd = PNd x Td -ENd = 821 (MW) x 24 (h/d) / 1000 (GW/MW) -ENd = 19.7 GWh +> ENd = PNd x Td +> +> ENd = 821 (MW) x 24 (h/d) / 1000 (GW/MW) +> +> ENd = 19.7 GWh + ## Network CO2 contribution From 7258f7abbf7d79cbd5f082e9fc5b4d8f08e3b941 Mon Sep 17 00:00:00 2001 From: Carl Larson Date: Fri, 9 Feb 2018 18:49:23 +0000 Subject: [PATCH 0442/1085] don't combine gpu hashrate & gpu power into weird metric --- EIPS/eip-858/calculations.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-858/calculations.md b/EIPS/eip-858/calculations.md index 8abeff773cf4d..9494cb7bb2f5b 100644 --- a/EIPS/eip-858/calculations.md +++ b/EIPS/eip-858/calculations.md @@ -1,16 +1,17 @@ | Variable | Symbol | Value | Unit | Source | | -------------------|--------------|---------------|---------------|--------| | Network Hashrate |HN | 232001 | GH/s | https://etherscan.io/chart/hashrate | -| Power/Hashrate |PH | 3.54 | W*s/MH | http://www.legitreviews.com/geforce-gtx-1070-ethereum-mining-small-tweaks-great-hashrate-low-power_195451, https://www.reddit.com/r/ethereum/comments/7vewys/10000_tons_co2_per_day_and_climbing_eip_858/dtrswyz/ | +| GPU Hashrate |HM | 31.2 | MH/s | http://www.legitreviews.com/geforce-gtx-1070-ethereum-mining-small-tweaks-great-hashrate-low-power_195451 | +| GPU Power |PM | 110.6 | W | https://www.reddit.com/r/ethereum/comments/7vewys/10000_tons_co2_per_day_and_climbing_eip_858/dtrswyz/ | ## Network Power Consumption (PN) A baseline value for network power consumption can be found by multiplying the total network hashrate with a "best case" value for the power/hashrate ratio that a miner can achieve. -> PN = HN x PH +> PN = HN x PM / HM > -> PN = 232001 (GH/s) x 3.54 (W*s/MH) x 1000 (MH/GH) / 10^6 (W/MW) +> PN = 232001 (GH/s) x 110.6 (W) x 1000 (MH/GH) / ( 31.2 (MH/s) x 10^6 (W/MW) ) > > PN = 821 MW From 615ba474a2ffdfd2456e3e0f78d3dea5fd2abf90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Ciurd=C4=83rean?= Date: Sat, 10 Feb 2018 00:58:40 +0200 Subject: [PATCH 0443/1085] Fix ERC-162 title in the Finalized EIPs table. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f67d9017a866c..dfdbd4a87665b 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [155](EIPS/eip-155.md) | Simple replay attack protection | Vitalik Buterin | Core | Final | | [160](EIPS/eip-160.md) | EXP cost increase | Vitalik Buterin | Core | Final | | [161](EIPS/eip-161.md) | State trie clearing (invariant-preserving alternative) | Gavin Wood | Core | Final | -| [162](EIPS/eip-162.md) | ERC-162 ENS support for reverse resolution of Ethereum addresses | Maurelian, Nick Johnson | ERC | Final | +| [162](EIPS/eip-162.md) | ERC-162 Initial ENS Hash Registrar | Maurelian, Nick Johnson | ERC | Final | | [170](EIPS/eip-170.md) | Contract code size limit | Vitalik Buterin | Core | Final | | [181](EIPS/eip-181.md) | ERC-181 ENS support for reverse resolution of Ethereum addresses | Nick Johnson | ERC | Final | | [190](EIPS/eip-190.md) | ERC-190 Ethereum Smart Contract Packaging Standard | Merriam, Coulter, Erfurt, Catalano, Matias | ERC | Final | From 458ecb2b1498ac38f216ae58a46cd1197bd734c2 Mon Sep 17 00:00:00 2001 From: yuzushioh Date: Sun, 11 Feb 2018 18:03:39 +0900 Subject: [PATCH 0444/1085] add swift implementation link --- EIPS/eip-55.md | 1 + 1 file changed, 1 insertion(+) diff --git a/EIPS/eip-55.md b/EIPS/eip-55.md index b428ab38be410..e9e1c82af1bb6 100644 --- a/EIPS/eip-55.md +++ b/EIPS/eip-55.md @@ -123,3 +123,4 @@ Note that the input to the Keccak256 hash is the lowercase hexadecimal string (i 2. Python example by @Recmo https://github.com/ethereum/eips/issues/55#issuecomment-261521584 3. Python implementation in [`ethereum-utils`](https://github.com/pipermerriam/ethereum-utils#to_checksum_addressvalue---text) 4. Ethereumjs-util implementation https://github.com/ethereumjs/ethereumjs-util/blob/75f529458bc7dc84f85fd0446d0fac92d991c262/index.js#L452-L466 +5. Swift implementation in [`EthereumKit`](https://github.com/yuzushioh/EthereumKit/blob/master/EthereumKit/EIP55.swift) From d9025cba50336d90ac73ac94be6a4d4ec0414744 Mon Sep 17 00:00:00 2001 From: Jack Peterson Date: Sun, 11 Feb 2018 10:00:21 -0800 Subject: [PATCH 0445/1085] Moved eip-4.md to EIPS folder --- {EIPs => EIPS}/eip-4.md | 0 README.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename {EIPs => EIPS}/eip-4.md (100%) diff --git a/EIPs/eip-4.md b/EIPS/eip-4.md similarity index 100% rename from EIPs/eip-4.md rename to EIPS/eip-4.md diff --git a/README.md b/README.md index f67d9017a866c..4f03d90ce0348 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | Number | Title | Author | Layer | Status | | ------------------------- | ------------------------------------------------------- | ----------------------------- | --------- | ---------- | | [3](EIPS/eip-3.mediawiki) | Addition of CALLDEPTH opcode | Martin Holst Swende | Core | Draft | -| [4](EIPS/eip-4.mediawiki) | EIP Classification | Joseph Chow | Meta | Draft | +| [4](EIPS/eip-4.md) | EIP Classification | Joseph Chow | Meta | Draft | | [5](EIPS/eip-5.md) | Gas Usage for `RETURN` and `CALL*` | Christian Reitwiessner | Core | Draft | | [101](EIPS/eip-101.md) | Serenity Currency and Crypto Abstraction | Vitalik Buterin | | Active | | [158](EIPS/eip-158.md) | State clearing | Vitalik Buterin | Core | Superseded | From 5e025143345dec2525ec8b777e420fd1ebf83fea Mon Sep 17 00:00:00 2001 From: William Entriken Date: Tue, 13 Feb 2018 02:35:39 -0500 Subject: [PATCH 0446/1085] A standard for interface detection, fixes #165 --- EIPS/eip-165.md | 121 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 EIPS/eip-165.md diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md new file mode 100644 index 0000000000000..250764ef6689b --- /dev/null +++ b/EIPS/eip-165.md @@ -0,0 +1,121 @@ +## Preamble + +``` +EIP: +Title: ERC-165 Standard Interface Detection +Author: Christian Reitwießner @chriseth, Nick Johnson @Arachnid, RJ Catalano @VoR0220, Fabian Vogelsteller @frozeman, Hudson Jameson @Souptacular, Jordi Baylina @jbaylina, Griff Green @griffgreen, William Entriken +Type: Standard Track +Category: ERC +Status: Draft +Created: 2018-01-23 +``` + +## Simple Summary + +Creates a standard method to publish and detect what interfaces a smart contract implements. + +## Abstract + +Herein, we standardize the following: + +1. How interfaces are identified +2. How a contract will publish the interfaces it implements +3. How to detect if a contract implements ERC-165 +4. How to detect if a contract implements any given interface + +## Motivation + +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. + +## Specification + +### How Interfaces are Identified + +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. + +We define the interface identifier as the XOR of all function selectors in the interface. This code example shows how to calculate an interface identifier: + +```solidity +pragma solidity ^0.4.19; + +interface Solidity101 { + function hello() public pure; + function world(int) public pure; +} + +contract Selector { + function calculateSelector() public pure returns (bytes4) { + Solidity101 i; + return i.hello.selector ^ i.world.selector; + } +} +``` + +Note: interfaces do not permit optional functions, therefore, the interface identity will not them. + +### How a Contract will Publish the Interfaces it Implements + +A contract that is compliant with ERC-165 shall implement the following function: + +```solidity +pragma solidity ^0.4.19; + +interface ERC165 { + /// @notice Query if a contract implements an interface + /// @param interfaceID The interface identifier, as specified in ERC-165 + /// @dev Interface identification is specified in ERC-165. This function + /// use less than 30000 gas. + /// @return `true` if the contract implements `interfaceID` and + /// `interfaceID` is not 0xffffffff, `false` otherwise + function supportsInterface(bytes4 interfaceID) external view returns (bool); +} +``` + +The interface identifier for this interface is `0x01ffc9a7`. You can calculate this by running ` bytes4(keccak256('supportsInterface(bytes4)'));` or using the `Selector` contract above. + +Therefore the implementing contract will have a `supportsInterface` function that returns: + +- `true` when `interfaceID` is `0x01ffc9a7` (EIP165 interface) +- `false` when `interfaceID` is `0xffffffff` +- `true` for any other `interfaceID` this contract implements +- `false` for any other `interfaceID` + +This function must return a bool and use at most 30000 gas. + +Implementation note, there are several logical ways to implement this function. Please see the example implementations and the discussion on gas usage. + +### How to Detect if a Contract Implements ERC-165 + +1. The source contact makes a `CALL` to the destination address with input data: `0x01ffc9a701ffc9a7` value: 0 and gas 30000. This corresponds to `contract.supportsInterface("0x01ffc9a7")`. +2. If the call fails or return false, the destination contract does not implement ERC-165. +3. If the call returns true, a second call is made with input data `0x01ffc9a7ffffffff`. +4. If the second call fails or returns true, the destination contract does not implement ERC-165. +5. Otherwise it implements EIP165. + +### How to Detect if a Contract Implements any Given Interface + +1. If you are not sure if the contract implements ERC-165 Interface, use the previous procedure to confirm. +2. If it does not implement ERC-165, then you will have to see what methods it uses the old fashioned way. +3. If it implements ERC-165 then just call `supportsInterface(interfaceID)` to determine if it implements an interface you can use. + +## Rationale + +We tried to keep this specification as simple as possible. This implementation is also compatible with the current Solidity version. + +## Backwards Compatibility + +The 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. + +Also [the ENS](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-137.md) already implements this EIP. + +## Test Cases + +XXXXXXXX HELP NEEDED XXXXXXXXX + +## Implementation + +XXXXXX IN PROGRES XXXXXX [https://github.com/jbaylina/EIP165Cache](https://github.com/jbaylina/EIP165Cache) + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 755848848742588956ef716c5d3e7a16eaa0ac24 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Tue, 13 Feb 2018 03:07:48 -0500 Subject: [PATCH 0447/1085] Discuss optional interfaces per @dete advice References: https://github.com/ethereum/EIPs/issues/165#issuecomment-345382512 --- EIPS/eip-165.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index 250764ef6689b..18b7c91854f71 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -51,7 +51,9 @@ contract Selector { } ``` -Note: interfaces do not permit optional functions, therefore, the interface identity will not them. +Note: interfaces do not permit optional functions, therefore, the interface identity will not include them. + +Note: an ERC standard may define multiple interfaces to separate core functionality from optional features. For example, [one draft standard defines](https://github.com/ethereum/EIPs/pull/841) ERC721, ERC721Metadata and ERC721Enumerable interfaces. ### How a Contract will Publish the Interfaces it Implements From 481e999d4af90122d31d5b5c133a37abb1a013f8 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Tue, 13 Feb 2018 22:54:27 -0500 Subject: [PATCH 0448/1085] remove deedName --- EIPS/eip-721.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index d6039b417fe36..7279c769d6810 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -110,7 +110,7 @@ interface ERC721 { /// Approve to emit. However, an exception, the Approve event will not emit when /// Transfer emits, this is because Transfer implicitly denotes the "approved taker" /// is reset to the zero address. - event Approval(address indexed owner, address indexed approved, uint256 indexed deedId); + event Approval(address indexed from, address indexed to, uint256 indexed deedId); /// @notice Set the "approved taker" for your deed, or revoke approval by /// setting the zero address. You may `approve` any number of times while @@ -155,11 +155,7 @@ interface ERC721Metadata { /// @dev Wallets and exchanges MAY display this to the end user. function symbol() public pure returns (string _symbol); - /// @notice A distinct name for a deed managed by this contract - /// @dev Wallets and exchanges MAY display this to the end user. - function deedName(uint256 _deedId) public pure returns (string _deedName); - - /// @notice A distinct URI (RFC 3986) for a given token. + /// @notice A distinct URI (RFC 3986) for a given deed. /// @dev If: /// * The URI is a URL /// * The URL is accessible @@ -175,6 +171,7 @@ interface ERC721Metadata { /// Wallets and exchanges MAY display this to the end user. /// Consider making any images at a width between 320 and 1080 pixels and /// aspect ratio between 1.91:1 and 4:5 inclusive. + /// Throws if `_deedId` is not a valid deed. function deedUri(uint256 _deedId) external view returns (string _deedUri); } ``` From 2b32af6ae63a768336f2dfde6b154636e633fb6d Mon Sep 17 00:00:00 2001 From: William Entriken Date: Tue, 13 Feb 2018 22:56:03 -0500 Subject: [PATCH 0449/1085] fix markdown language --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 7279c769d6810..7a18642501db0 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -134,7 +134,7 @@ Implementations MAY also choose to implement the **ERC-721 Metadata extension**. > You just received deed ID `0xb9d6a94f1ab16f461b2af06aebab7e1cfe10ada985da001f274f370fbb848a40` from contract `0x0dcd2f752394c41875e259e00bb44fd505297caf`! -``` +```solidity /// @title Metadata extension to ERC-721 interface /// @author William Entriken (https://phor.net) /// @dev Specification at https://github.com/ethereum/eips/issues/XXXX From 224822c743be51ff6b2762a1958507b4ea81637c Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 14 Feb 2018 00:05:57 -0500 Subject: [PATCH 0450/1085] Add two competing implementations --- EIPS/eip-165.md | 61 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index 18b7c91854f71..aff72d70552a5 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -51,13 +51,11 @@ contract Selector { } ``` -Note: interfaces do not permit optional functions, therefore, the interface identity will not include them. - -Note: an ERC standard may define multiple interfaces to separate core functionality from optional features. For example, [one draft standard defines](https://github.com/ethereum/EIPs/pull/841) ERC721, ERC721Metadata and ERC721Enumerable interfaces. +Note: interfaces do not permit optional functions, therefore, the interface identity will not them. ### How a Contract will Publish the Interfaces it Implements -A contract that is compliant with ERC-165 shall implement the following function: +A contract that is compliant with ERC-165 shall implement the following interface (referred as `ERC165.sol`): ```solidity pragma solidity ^0.4.19; @@ -116,6 +114,61 @@ XXXXXXXX HELP NEEDED XXXXXXXXX ## Implementation +This approach uses a `view` function implementation of `supportsInterface`. The execution cost is 478 gas for any input. But contract initialization requires storing each interface (`SSTORE` is 20,000 gas). + +```solidity +pragma solidity ^0.4.19; + +import "./ERC165.sol"; + +interface Simpson { + function is2D() external returns (bool); + function skinColor() external returns (string); +} + +contract Lisa is ERC165, Simpson { + mapping(bytes4 => bool) supportedInterfaces; + + function Lisa() public { + supportedInterfaces[this.supportsInterface.selector] = true; + supportedInterfaces[this.is2D.selector ^ this.skinColor.selector] = true; + } + + function supportsInterface(bytes4 interfaceID) external view returns (bool) { + return supportedInterfaces[interfaceID]; + } + + // ... is usually 2D + // skin color is yellow +} +``` + +Following 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. + +```solidity +pragma solidity ^0.4.19; + +import "./ERC165.sol"; + +interface Simpson { + function is2D() external returns (bool); + function skinColor() external returns (string); +} + +contract Homer is ERC165, Simpson { + function supportsInterface(bytes4 interfaceID) external view returns (bool) { + return + interfaceID == this.supportsInterface.selector || // ERC165 + interfaceID == this.is2D.selector + ^ this.skinColor.selector; // Simpson + } +} +``` + +With 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. + + + XXXXXX IN PROGRES XXXXXX [https://github.com/jbaylina/EIP165Cache](https://github.com/jbaylina/EIP165Cache) ## Copyright From 4b7b91691aa3ae4417e9b4aeaf3b96544f6119c7 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 14 Feb 2018 00:16:03 -0500 Subject: [PATCH 0451/1085] Add author email addresses per latest EIP-X Found from git log messages around the world. --- EIPS/eip-165.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index aff72d70552a5..6b14cb1b15b2a 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -3,7 +3,7 @@ ``` EIP: Title: ERC-165 Standard Interface Detection -Author: Christian Reitwießner @chriseth, Nick Johnson @Arachnid, RJ Catalano @VoR0220, Fabian Vogelsteller @frozeman, Hudson Jameson @Souptacular, Jordi Baylina @jbaylina, Griff Green @griffgreen, William Entriken +Author: Christian Reitwießner , Nick Johnson , RJ Catalano , Fabian Vogelsteller , Hudson Jameson , Jordi Baylina , Griff Green , William Entriken Type: Standard Track Category: ERC Status: Draft From 6e4394d6d127ddd447fd7991af871fb0a8800472 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 14 Feb 2018 22:29:01 -0500 Subject: [PATCH 0452/1085] Update caching contract --- EIPS/eip-165.md | 90 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 73 insertions(+), 17 deletions(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index 6b14cb1b15b2a..c843e195c83fb 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -86,7 +86,7 @@ Implementation note, there are several logical ways to implement this function. ### How to Detect if a Contract Implements ERC-165 -1. The source contact makes a `CALL` to the destination address with input data: `0x01ffc9a701ffc9a7` value: 0 and gas 30000. This corresponds to `contract.supportsInterface("0x01ffc9a7")`. +1. 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")`. 2. If the call fails or return false, the destination contract does not implement ERC-165. 3. If the call returns true, a second call is made with input data `0x01ffc9a7ffffffff`. 4. If the second call fails or returns true, the destination contract does not implement ERC-165. @@ -110,36 +110,96 @@ Also [the ENS](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-137.md) alr ## Test Cases -XXXXXXXX HELP NEEDED XXXXXXXXX +Following is a caching contract that detects which interfaces other contracts implement. From @fulldecent and @jbaylina. + +```solidity +pragma solidity ^0.4.19; + +contract ERC165Cache { + bytes4 constant InvalidID = 0xffffffff; + bytes4 constant ERC165ID = 0x01ffc9a7; + + enum ImplStatus { Unknown, No, Yes } + mapping (address => mapping (bytes4 => ImplStatus)) cache; + + // Return value from cache if available + function interfaceSupported(address _contract, bytes4 _interfaceId) external returns (bool) { + ImplStatus status = cache[_contract][_interfaceId]; + if (status == ImplStatus.Unknown) { + return checkInterfaceSupported(_contract, _interfaceId); + } + return status == ImplStatus.Yes; + } + + // Repull result into cache + function checkInterfaceSupported(address _contract, bytes4 _interfaceId) public returns (bool) { + ImplStatus status = determineInterfaceImplementationStatus(_contract, _interfaceId); + cache[_contract][_interfaceId] = status; + return status == ImplStatus.Yes; + } + + function determineInterfaceImplementationStatus(address _contract, bytes4 _interfaceId) internal view returns (ImplStatus) { + if (noThrowCall(_contract, InvalidID)) return ImplStatus.No; + if (!noThrowCall(_contract, ERC165ID)) return ImplStatus.No; + if (noThrowCall(_contract, _interfaceId)) return ImplStatus.Yes; + return ImplStatus.No; + } + + // Update this after the Metropolis hard fork to use staticcall! + function noThrowCall(address _contract, bytes4 _interfaceId) internal view returns (bool result) { + bytes4 erc165ID = ERC165ID; + assembly { + let x := mload(0x40) // Find empty storage location using "free memory pointer" + mstore(x, erc165ID) // Place signature at begining of empty storage + mstore(add(x, 0x04), _interfaceId) // Place first argument directly next to signature + call(30000, // 30k gas + _contract, // To addr + 0, // No value + x, // Inputs are stored at location x + 0x8, // Inputs are 8 byes long + x, // Store output over input (saves space) + 0x20) // Outputs are 32 bytes long + pop // Discard call return value + result := mload(x) // Load the result + } + } +} +``` ## Implementation -This approach uses a `view` function implementation of `supportsInterface`. The execution cost is 478 gas for any input. But contract initialization requires storing each interface (`SSTORE` is 20,000 gas). +This 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. ```solidity pragma solidity ^0.4.19; import "./ERC165.sol"; +contract ERC165MappingImplementation is ERC165 { + /// @dev You must not set element 0xffffffff to true + mapping(bytes4 => bool) internal supportedInterfaces; + + function ERC165MappingImplementation() internal { + supportedInterfaces[this.supportsInterface.selector] = true; + } + + function supportsInterface(bytes4 interfaceID) external view returns (bool) { + return supportedInterfaces[interfaceID]; + } +} + interface Simpson { function is2D() external returns (bool); function skinColor() external returns (string); } -contract Lisa is ERC165, Simpson { - mapping(bytes4 => bool) supportedInterfaces; - +contract Lisa is ERC165MappingImplementation, Simpson { function Lisa() public { - supportedInterfaces[this.supportsInterface.selector] = true; supportedInterfaces[this.is2D.selector ^ this.skinColor.selector] = true; } - function supportsInterface(bytes4 interfaceID) external view returns (bool) { - return supportedInterfaces[interfaceID]; - } - - // ... is usually 2D - // skin color is yellow + function is2D() external returns (bool){} + function skinColor() external returns (string){} } ``` @@ -167,10 +227,6 @@ contract Homer is ERC165, Simpson { With 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. - - -XXXXXX IN PROGRES XXXXXX [https://github.com/jbaylina/EIP165Cache](https://github.com/jbaylina/EIP165Cache) - ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 04eb283a42d72c11207d00c9f5802e7c59bc74a1 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 14 Feb 2018 23:04:08 -0500 Subject: [PATCH 0453/1085] Add Nick Savers to EIP editors list --- EIPS/eip-1.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index 0e5569b89e128..745322e4ea060 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -188,6 +188,9 @@ The current EIP editors are ` * Vitalik Buterin (@vbuterin)` +` * Nick Savers (@nicksavers)` + + EIP Editor Responsibilities and Workflow -------------------------------------- From d26f9b36eae367c86b6abf6e628ddce687036193 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Thu, 15 Feb 2018 10:46:33 -0500 Subject: [PATCH 0454/1085] Remave Yoichi as editor --- EIPS/eip-1.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index 745322e4ea060..d34fed1b37a0c 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -184,8 +184,6 @@ The current EIP editors are ` * Nick Johnson (@arachnid)` -` * Yoichi Hirai (@pirapira)` - ` * Vitalik Buterin (@vbuterin)` ` * Nick Savers (@nicksavers)` From 7046c02cd69bf5cfc1fda63c08e4ff4dcc5bc08f Mon Sep 17 00:00:00 2001 From: William Entriken Date: Thu, 15 Feb 2018 12:06:18 -0500 Subject: [PATCH 0455/1085] Add implementation, thank you Nastassia Sachs --- EIPS/eip-721.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 7a18642501db0..8eab87166d98a 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -3,7 +3,7 @@ ``` EIP: Title: ERC-721 Deed Standard -Author: William Entriken , Dieter Shirley +Author: William Entriken , Dieter Shirley , Nastassia Sachs Type: Standard Category ERC Status: Draft @@ -308,9 +308,9 @@ Note: "Limited edition, collectible tokens" like [Curio Cards](https://mycurioca Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable. -## Implementation +## Implementations -**TO DO** +ERC721ExampleDeed, by Nastassia Sachs: https://github.com/nastassiasachs/ERC721ExampleDeed The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details. From d39b3885d405474c7db773fb9983398d44fc2529 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Thu, 15 Feb 2018 12:12:05 -0500 Subject: [PATCH 0456/1085] Add author Konrad Feldmeier Per @chriseth --- EIPS/eip-165.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index c843e195c83fb..5769a84f11e99 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -3,7 +3,7 @@ ``` EIP: Title: ERC-165 Standard Interface Detection -Author: Christian Reitwießner , Nick Johnson , RJ Catalano , Fabian Vogelsteller , Hudson Jameson , Jordi Baylina , Griff Green , William Entriken +Author: Christian Reitwießner , Nick Johnson , RJ Catalano , Fabian Vogelsteller , Hudson Jameson , Jordi Baylina , Griff Green , Konrad Feldmeier , William Entriken Type: Standard Track Category: ERC Status: Draft From ddd25257926d3480febdb259ba7f6f01a38b1681 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Thu, 15 Feb 2018 16:44:10 -0500 Subject: [PATCH 0457/1085] Provide illustration for scaling use case --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 8eab87166d98a..aef992d3666e7 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -259,7 +259,7 @@ This inline `supportsInterface` function uses `pure` mutability. The significanc **Gas and complexity** -This specification contemplates contracts managing few and *many* deeds. Specifically, we note that a large contract, initially with `N` deeds owned by the contract owner, can be deployed with `O(1)` gas. All functions in the baseline and extension specifications can be implemented with `O(1)` gas and `O(Deed Count)` storage. +This specification contemplates contracts managing few and *many* deeds. Specifically, we note that a large contract, initially with `N` deeds owned by the contract owner, can be deployed with `O(1)` gas. All functions in the baseline and extension specifications can be implemented with `O(1)` gas and `O(Deed Count)` storage. We have an implementation with 1 billion deployed deeds on testnet. **Accountability** From 8743a2286ce7ebf15faf9dd85aad23a940cfdc6a Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 16 Feb 2018 03:02:03 -0500 Subject: [PATCH 0458/1085] Eat my words, add the transfer function --- EIPS/eip-721.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index aef992d3666e7..83927a75108e2 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -22,7 +22,7 @@ The scope of this interface includes **interrogating the smart contract about de ## Motivation -A standard interface allows wallet/broker/auctioneer applications to work with any deed on Ethereum. This contract considers simple deed contracts as well as contract that track large number of deeds. Additional applications are discussed below. +A standard interface allows wallet/broker/auction applications to work with any deed on Ethereum. We provide for simple deed contracts as well as contracts that track a *large* number of deeds. Additional applications are discussed below. This standard is inspired by [the ERC-20 token standard](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) and builds on two years of experience since EIP-20 was created. EIP-20 is insufficient for tracking deed ownership because each deed is distinct (non-fungible) whereas each token is identical (fungible). @@ -127,6 +127,12 @@ interface ERC721 { /// valid deed. /// @param _deedId The deed that is being transferred function takeOwnership(uint256 _deedId) external payable; + + /// @notice Set a new owner for your deed + /// @dev Throws if `msg.sender` does not own deed `_deedId` or if `_to` == + /// `msg.sender` or if `_deedId` is not a valid deed. + /// @param _deedId The deed that is being transferred + function transfer(address _to, uint256 _deedId) external payable; } ``` @@ -241,15 +247,13 @@ The basis of this standard is that every deed is identified by a unique 256-bit ERC-721 standardizes a two-step process for transferring deeds inspired from [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md). This requires the sender to approve sending and the receiver to accept approval. In the original ERC-20, this caused a problem when `allowance` was called and then later modified to a different amount, as [disucssed on OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/issues/438). In this deed standard, there is no allowance because every deed is unique, the quantity is none or one. Therefore we receive the benefits of ERC-20's original design without problems that have been later discovered. -With two years experience, we have found that the one-step `transfer(address _to, uint256 _value)` is undesirable. This is because it is very simple to accidentally send property to an address that cannot use it, as discussed in [ERC-233](https://github.com/ethereum/EIPs/issues/223) and [ERC-677](https://github.com/ethereum/EIPs/issues/677). - -A careful reading of this standard's `approve` and `takeOwnership` functions also shows that *any* business reason may be used to deny transactions. Failed transactions will throw, a best practice identified in [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827) and [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol). +A careful reading of this standard's `approve`, `takeOwnership` and `transfer` functions also shows that *any* business reason may be used to deny transactions. Failed transactions will throw, a best practice identified in [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827) and [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol). Use of the `transfer` function is controversial and is discussed in [ERC-233](https://github.com/ethereum/EIPs/issues/223) and [ERC-677](https://github.com/ethereum/EIPs/issues/677), but we take the position that misuse of the `transfer` function is an implementation mistake not a standards mistake. Creating of new deeds and destruction of deeds is not included in the specification. Your implementing contract may implement these by other means. Please see the `event` documentation for your responsibilities when creating or destroying deeds. **Function mutability** -The transfer functions `approve` and `takeOwnership` are payable. Yes, really. The standard contemplates a real estate ownership application where transfer of property will require paying tax and/or various fees (including, but not limited to mining fees and pre-set transference fees), which may be paid by the old and/or new owner in any pre-arranged amount. Such an application would be compliant under this specification. Note that your contract may be nonpayable (syntactic sugar for `require(msg.value == 0)`) and be compliant, see caveats. +The transfer functions `approve`, `takeOwnership` and `transfer` are payable. Yes, really. The standard contemplates a real estate ownership application where transfer of property will require paying tax and/or various fees (including, but not limited to mining fees and pre-set transference fees), which may be paid by the old and/or new owner in any pre-arranged amount. Such an application would be compliant under this specification. Note that your contract may be nonpayable (syntactic sugar for `require(msg.value == 0)`) and be compliant, see caveats. **Supports interface** From 2b4971e3d307c921896accefc3e2534d9bbfbd62 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 16 Feb 2018 03:37:15 -0500 Subject: [PATCH 0459/1085] Depend on 165 --- EIPS/eip-721.md | 54 ++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 83927a75108e2..cd380eea7672c 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -8,6 +8,7 @@ Type: Standard Category ERC Status: Draft Created: 2018-01-24 +Requires: ERC-165 ``` ## Simple Summary @@ -37,31 +38,27 @@ The **baseline specification** is REQUIRED for all ERC-721 implementations (subj ```solidity pragma solidity ^0.4.19; +import "./ERC165.sol"; + /// @title Interface for contracts conforming to ERC-721: Deed Standard /// @author William Entriken (https://phor.net), et. al. /// @dev Specification at https://github.com/ethereum/eips/XXXFinalUrlXXX -interface ERC721 { +interface ERC721 /* is ERC165 */ { // COMPLIANCE WITH ERC-165 (DRAFT) ///////////////////////////////////////// - /// @dev ERC-165 (draft) interface signature for itself // bytes4 internal constant INTERFACE_SIGNATURE_ERC165 = // 0x01ffc9a7 - // bytes4(keccak256('supportsInterface(bytes4)')); + // this.supportsInterface.selector; - /// @dev ERC-165 (draft) interface signature for ERC721 - // bytes4 internal constant INTERFACE_SIGNATURE_ERC721 = // 0xda671b9b - // bytes4(keccak256('ownerOf(uint256)')) ^ - // bytes4(keccak256('countOfDeeds()')) ^ - // bytes4(keccak256('countOfDeedsByOwner(address)')) ^ - // bytes4(keccak256('deedOfOwnerByIndex(address,uint256)')) ^ - // bytes4(keccak256('approve(address,uint256)')) ^ - // bytes4(keccak256('takeOwnership(uint256)')); - - /// @notice Query a contract to see if it supports a certain interface - /// @dev Returns `true` the interface is supported and `false` otherwise, - /// returns `true` for INTERFACE_SIGNATURE_ERC165 and - /// INTERFACE_SIGNATURE_ERC721, see ERC-165 for other interface signatures. - function supportsInterface(bytes4 _interfaceID) external pure returns (bool); + /// @dev ERC-165 (draft) interface signature for itself + // bytes4 internal constant INTERFACE_SIGNATURE_ERC721 = // xxxxxx + // this.ownerOf.selector ^ + // this.countOfDeeds.selector ^ + // this.countOfDeedsByOwner.selector ^ + // this.deedOfOwnerByIndex.selector ^ + // this.approve.selector ^ + // this.takeOwnership.selector ^ + // this.transfer.selector; // PUBLIC QUERY FUNCTIONS ////////////////////////////////////////////////// @@ -127,7 +124,7 @@ interface ERC721 { /// valid deed. /// @param _deedId The deed that is being transferred function takeOwnership(uint256 _deedId) external payable; - + /// @notice Set a new owner for your deed /// @dev Throws if `msg.sender` does not own deed `_deedId` or if `_to` == /// `msg.sender` or if `_deedId` is not a valid deed. @@ -148,9 +145,9 @@ interface ERC721Metadata { /// @dev ERC-165 (draft) interface signature for ERC721 // bytes4 internal constant INTERFACE_SIGNATURE_ERC721Metadata = // 0x2a786f11 - // bytes4(keccak256('name()')) ^ - // bytes4(keccak256('symbol()')) ^ - // bytes4(keccak256('deedUri(uint256)')); + // this.name.selector ^ + // this.symbol.selector ^ + // this.deedUri.selector; /// @notice A descriptive name for a collection of deeds managed by this /// contract @@ -192,9 +189,9 @@ interface ERC721Enumerable { /// @dev ERC-165 (draft) interface signature for ERC721 // bytes4 internal constant INTERFACE_SIGNATURE_ERC721Enumerable = // 0xa5e86824 - // bytes4(keccak256('deedByIndex()')) ^ - // bytes4(keccak256('countOfOwners()')) ^ - // bytes4(keccak256('ownerByIndex(uint256)')); + // this.deedByIndex.selector ^ + // this.countOfOwners.selector ^ + // this.ownerByIndex.selector; /// @notice Enumerate active deeds /// @dev Throws if `_index` >= `countOfDeeds()` @@ -220,8 +217,9 @@ interface ERC721Enumerable { The 0.4.19 Solidity interface grammar is not expressive enough to document the ERC-721 specification. A contract which complies with ERC-721 must also abide by the following: - [Solidity issue #3412](https://github.com/ethereum/solidity/issues/3412): This interface includes explicit mutability guarantees for each function. Mutability guarantees are, in order weak to strong: `payable`, implicit nonpayable, `view`, and `pure`. Your implementation must meet the mutability guarantee in this interface or you may meet a stronger guarantee. For example, a `payable` function in this interface may be implemented as nonpayble (no state mutability specified) in your contract. We expect a later Solidity release will allow your stricter contract to inherit from this interface, but a workaround for version 0.4.19 is that you can edit this interface to add stricter mutability before inheriting from your contract. -- [Solidity issue #3419](https://github.com/ethereum/solidity/issues/3419): If a contract is not compliant with `ERC721` then it is not compliant with `ERC721Metadata` or `ERC721Enumerable`. +- [Solidity issue #3419](https://github.com/ethereum/solidity/issues/3419): If a contract is not compliant with `ERC721` then it is not compliant with `ERC721Metadata` or `ERC721Enumerable`. ERC-721 implements the requirements of interface [ERC-165](https://github.com/ethereum/EIPs/pull/881). - [Solidity issue #2330](https://github.com/ethereum/solidity/issues/2330): If a function is shown in this specification as `external` then a contract will be compliant if it uses `public` visibility. +- [Solidity issue #3494](https://github.com/ethereum/solidity/issues/3494): Use of `this.*.selector` is marked as a warning by Solidity, a future version of Solidity will not mark this as an error. *If a newer version of Solidity allows the caveats to be expressed in code, then this EIP MAY be updated and the caveats removed, such will be equivalent to the original specification.* @@ -255,11 +253,11 @@ Creating of new deeds and destruction of deeds is not included in the specificat The transfer functions `approve`, `takeOwnership` and `transfer` are payable. Yes, really. The standard contemplates a real estate ownership application where transfer of property will require paying tax and/or various fees (including, but not limited to mining fees and pre-set transference fees), which may be paid by the old and/or new owner in any pre-arranged amount. Such an application would be compliant under this specification. Note that your contract may be nonpayable (syntactic sugar for `require(msg.value == 0)`) and be compliant, see caveats. -**Supports interface** +**ERC-165 interface** -This specification includes a function `supportsInterface` so that any contract MAY query your contract to see if it complies with ERC-721 and the extensions. In the interest of GETTING THINGS DONE, we have inlined ERC-165. This EIP does NOT require the passage of ERC-165. To be clear: if you ask a contract if it supports ERC-721 and get a positive response, then it is still possible that the contract has lied to you and that its implementation does not meet the specification in this document. +This specification includes a function `supportsInterface` which is standardized in [ERC-165](https://github.com/ethereum/EIPs/pull/881) (draft pending acceptance). So any contract MAY query your contract to see if it complies with ERC-721 and the extensions. This creates a dependency, which is a risk. However, ERC-165 is an extremely simple proposal, has implementations deployed in the wild for years and the draft meets all EIP requirements for acceptance, including [the new requirements](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2031.md#10957-decision-process-for-eips) that aren't even documented yet. The lead author of this standard is also the official champion for ERC-165. -This inline `supportsInterface` function uses `pure` mutability. The significance is that a contract which is deployed and not compliant with ERC-721 cannot make changes to become ERC-721 compliant. The benefit is that results of `supportsInterface` can be cached. This decision [has not achieved full consensus in the ERC-165 discussion](https://github.com/ethereum/EIPs/issues/165). +We chose ERC-165 over competing standard ERC-820 because of maturity. We consider ERC-165 low risk. But ERC-820, as recently as two weeks ago, [discovered a complete show-stopping flaw](https://github.com/ethereum/EIPs/issues/820#issuecomment-362049573). ERC-820 may be a great option, but we deem dependency on that standard an unacceptable risk at this time. **Gas and complexity** From f8fcf194ff94ff397d1befa1e3d4d9368ccb0593 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 16 Feb 2018 04:02:10 -0500 Subject: [PATCH 0460/1085] Switch to latest Solidity compiler --- EIPS/eip-721.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index cd380eea7672c..c1c96ec4181dc 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -36,7 +36,7 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S The **baseline specification** is REQUIRED for all ERC-721 implementations (subject to "caveats", below). ```solidity -pragma solidity ^0.4.19; +pragma solidity ^0.4.20; import "./ERC165.sol"; @@ -152,11 +152,11 @@ interface ERC721Metadata { /// @notice A descriptive name for a collection of deeds managed by this /// contract /// @dev Wallets and exchanges MAY display this to the end user. - function name() public pure returns (string _name); + function name() external pure returns (string _name); /// @notice An abbreviated name for deeds managed by this contract /// @dev Wallets and exchanges MAY display this to the end user. - function symbol() public pure returns (string _symbol); + function symbol() external pure returns (string _symbol); /// @notice A distinct URI (RFC 3986) for a given deed. /// @dev If: From dd3396a3ce5b95eb0f901f1451859c290b6e2086 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 16 Feb 2018 04:44:29 -0500 Subject: [PATCH 0461/1085] Add note about id choice --- EIPS/eip-721.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index c1c96ec4181dc..adab99b950066 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -241,6 +241,8 @@ This definition is consistent with the fact that ERC-721 contracts track ownersh The basis of this standard is that every deed is identified by a unique 256-bit unsigned integer within its tracking contract. This ID number MUST NOT change for the life of the contract. The pair `(contract address, deed ID)` will then be a globally unique and fully-qualified identifier for a specific deed within the Ethereum ecosystem. While some contracts may find it convenient to start with ID 0 and simply increment by one for each new NFT, callers MUST NOT assume that ID numbers have any specific pattern to them, and should treat the ID as a "black box". Also note that a deeds MAY become invalid (be destroyed). Please see the enumerations functions for a supported enumeration interface. +The choice of uint256 allows a wide variety of applications because UUIDs and sha3 hashes are directly convertible to uint256. + **Transfer mechanism** ERC-721 standardizes a two-step process for transferring deeds inspired from [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md). This requires the sender to approve sending and the receiver to accept approval. In the original ERC-20, this caused a problem when `allowance` was called and then later modified to a different amount, as [disucssed on OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/issues/438). In this deed standard, there is no allowance because every deed is unique, the quantity is none or one. Therefore we receive the benefits of ERC-20's original design without problems that have been later discovered. From 290f31cd1bebc6803e30e1853bafe9523781a87f Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 16 Feb 2018 05:04:47 -0500 Subject: [PATCH 0462/1085] Add note as 165 progresses through standardization --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index adab99b950066..b66b0e8d9c574 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -257,7 +257,7 @@ The transfer functions `approve`, `takeOwnership` and `transfer` are payable. Ye **ERC-165 interface** -This specification includes a function `supportsInterface` which is standardized in [ERC-165](https://github.com/ethereum/EIPs/pull/881) (draft pending acceptance). So any contract MAY query your contract to see if it complies with ERC-721 and the extensions. This creates a dependency, which is a risk. However, ERC-165 is an extremely simple proposal, has implementations deployed in the wild for years and the draft meets all EIP requirements for acceptance, including [the new requirements](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2031.md#10957-decision-process-for-eips) that aren't even documented yet. The lead author of this standard is also the official champion for ERC-165. +This specification includes a function `supportsInterface` which is standardized in [ERC-165](https://github.com/ethereum/EIPs/pull/881) (draft pending acceptance). So any contract MAY query your contract to see if it complies with ERC-721 and the extensions. This creates a dependency, which is a risk. However, ERC-165 is an extremely simple proposal, has implementations deployed in the wild for years and the draft meets all EIP requirements for acceptance, including [the new requirements](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2031.md#10957-decision-process-for-eips) that aren't even documented yet. The lead author of this standard is also the official champion for ERC-165. One EIP reviewer [has "ACK"ed the draft](https://github.com/ethereum/EIPs/pull/881#pullrequestreview-97124296). We chose ERC-165 over competing standard ERC-820 because of maturity. We consider ERC-165 low risk. But ERC-820, as recently as two weeks ago, [discovered a complete show-stopping flaw](https://github.com/ethereum/EIPs/issues/820#issuecomment-362049573). ERC-820 may be a great option, but we deem dependency on that standard an unacceptable risk at this time. From d45177e6b1099256e90fc3ff13a5d7d92d8cf0b8 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 16 Feb 2018 05:36:47 -0500 Subject: [PATCH 0463/1085] Add a second implementation --- EIPS/eip-721.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index b66b0e8d9c574..4fd006ca2bba4 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -316,7 +316,11 @@ Test cases for an implementation are mandatory for EIPs that are affecting conse ERC721ExampleDeed, by Nastassia Sachs: https://github.com/nastassiasachs/ERC721ExampleDeed -The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details. +- Implements using the Open Zeppelin project format + +XXXXERC721, by William Entriken: https://github.com/fulldecent/erc721-example + +- Deployed on testnet with 1 billion deeds and supporting all lookups with the metadata extension. This demonstrates that scaling is NOT a problem. ## Copyright From 992bbff14ef26027aab8cffaecf9152cf1152814 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 16 Feb 2018 05:56:40 -0500 Subject: [PATCH 0464/1085] Add operators extension, a starting point --- EIPS/eip-721.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 4fd006ca2bba4..015e31ccfb2cf 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -212,6 +212,28 @@ interface ERC721Enumerable { } ``` +Here is a also an optional **ERC-721 Operators Extension** for delegating access to your deeds. This is copied from the ERC-777 efforts. At this time DO NOT recommend this extension because of [a security considuration](https://github.com/ethereum/EIPs/issues/777#issuecomment-366182824) but we are putting it forth as a starting point for discussion. + +```solidity +/// WARNING: THIS INTERFACE IS TO PROMOTO DISCUSSION, WE DO NOT RECOMMEND YOU +/// IMPLEMENT IT YET AS THERE ARE SECURITY CONSIDERATIONS +/// @title Delegated operator extension to ERC-721 interface +/// @author William Entriken (https://phor.net) +/// @dev Specification at https://github.com/ethereum/eips/issues/XXXX +interface ERC721Operators { + + /// @dev ERC-165 (draft) interface signature for ERC721 ... + + function authorizeOperator(address operator) external; + function revokeOperator(address operator) external; + function isOperatorFor(address operator, address tokenHolder) external view returns (bool); + function operatorSend(address from, address to, uint256 _deedId) external; + event AuthorizedOperator(address indexed operator, address indexed tokenHolder); + event RevokedOperator(address indexed operator, address indexed tokenHolder); +} +``` + + ### Caveats The 0.4.19 Solidity interface grammar is not expressive enough to document the ERC-721 specification. A contract which complies with ERC-721 must also abide by the following: From 50f59da47f40c76c433e9bd54c00a4a44aa78d18 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 16 Feb 2018 06:35:16 -0500 Subject: [PATCH 0465/1085] Updated to use staticcall --- EIPS/eip-165.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index 5769a84f11e99..75082b04bd8d8 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -145,16 +145,14 @@ contract ERC165Cache { return ImplStatus.No; } - // Update this after the Metropolis hard fork to use staticcall! function noThrowCall(address _contract, bytes4 _interfaceId) internal view returns (bool result) { bytes4 erc165ID = ERC165ID; assembly { let x := mload(0x40) // Find empty storage location using "free memory pointer" mstore(x, erc165ID) // Place signature at begining of empty storage mstore(add(x, 0x04), _interfaceId) // Place first argument directly next to signature - call(30000, // 30k gas + staticcall(30000, // 30k gas _contract, // To addr - 0, // No value x, // Inputs are stored at location x 0x8, // Inputs are 8 byes long x, // Store output over input (saves space) From 529ce1b2cae64f22df72d8de236b9b85414c18dd Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 16 Feb 2018 06:51:50 -0500 Subject: [PATCH 0466/1085] Update cache to use explicit return values of 32 byte length --- EIPS/eip-165.md | 49 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index 75082b04bd8d8..0586dd35f4528 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -36,11 +36,11 @@ For this standard, an *interface* is a set of [function selectors as calculated We define the interface identifier as the XOR of all function selectors in the interface. This code example shows how to calculate an interface identifier: ```solidity -pragma solidity ^0.4.19; +pragma solidity ^0.4.20; interface Solidity101 { - function hello() public pure; - function world(int) public pure; + function hello() external pure; + function world(int) external pure; } contract Selector { @@ -58,7 +58,7 @@ Note: interfaces do not permit optional functions, therefore, the interface iden A contract that is compliant with ERC-165 shall implement the following interface (referred as `ERC165.sol`): ```solidity -pragma solidity ^0.4.19; +pragma solidity ^0.4.20; interface ERC165 { /// @notice Query if a contract implements an interface @@ -113,7 +113,7 @@ Also [the ENS](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-137.md) alr Following is a caching contract that detects which interfaces other contracts implement. From @fulldecent and @jbaylina. ```solidity -pragma solidity ^0.4.19; +pragma solidity ^0.4.20; contract ERC165Cache { bytes4 constant InvalidID = 0xffffffff; @@ -139,25 +139,42 @@ contract ERC165Cache { } function determineInterfaceImplementationStatus(address _contract, bytes4 _interfaceId) internal view returns (ImplStatus) { - if (noThrowCall(_contract, InvalidID)) return ImplStatus.No; - if (!noThrowCall(_contract, ERC165ID)) return ImplStatus.No; - if (noThrowCall(_contract, _interfaceId)) return ImplStatus.Yes; + uint256 success; + uint256 result; + + (success, result) = noThrowCall(_contract, ERC165ID); + if ((success==0)||(result==0)) { + return ImplStatus.No; + } + + (success, result) = noThrowCall(_contract, InvalidID); + if ((success==0)||(result!=0)) { + return ImplStatus.No; + } + + (success, result) = noThrowCall(_contract, _interfaceId); + if ((success==1)&&(result==1)) { + return ImplStatus.Yes; + } return ImplStatus.No; } - function noThrowCall(address _contract, bytes4 _interfaceId) internal view returns (bool result) { + function noThrowCall(address _contract, bytes4 _interfaceId) constant internal returns (uint256 success, uint256 result) { bytes4 erc165ID = ERC165ID; + assembly { let x := mload(0x40) // Find empty storage location using "free memory pointer" mstore(x, erc165ID) // Place signature at begining of empty storage mstore(add(x, 0x04), _interfaceId) // Place first argument directly next to signature - staticcall(30000, // 30k gas - _contract, // To addr - x, // Inputs are stored at location x - 0x8, // Inputs are 8 byes long - x, // Store output over input (saves space) - 0x20) // Outputs are 32 bytes long - pop // Discard call return value + + success := staticcall( + 30000, // 5k gas + _contract, // To addr + x, // Inputs are stored at location x + 0x8, // Inputs are 8 byes long + x, // Store output over input (saves space) + 0x20) // Outputs are 32 bytes long + result := mload(x) // Load the result } } From 26c91183dc3a497cac02e3488e641217ac883d32 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 16 Feb 2018 06:56:43 -0500 Subject: [PATCH 0467/1085] "uses less than" --- EIPS/eip-165.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index 0586dd35f4528..91e05a17c3ec5 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -64,7 +64,7 @@ interface ERC165 { /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @dev Interface identification is specified in ERC-165. This function - /// use less than 30000 gas. + /// uses less than 30000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface(bytes4 interfaceID) external view returns (bool); From ad70b8d27686de2b324491b1a7f6667963f5aa2e Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 16 Feb 2018 06:58:03 -0500 Subject: [PATCH 0468/1085] Function selectors are defined by Ethereum, not Solidity --- EIPS/eip-165.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index 91e05a17c3ec5..392ff855547d4 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -31,7 +31,7 @@ For some "standard interfaces" like [the ERC-20 token interface](https://github. ### How Interfaces are Identified -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. +For this standard, an *interface* is a set of [function selectors as defined by the Ethereum ABI](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. We define the interface identifier as the XOR of all function selectors in the interface. This code example shows how to calculate an interface identifier: From 1bc54d967ac1b615b4a08973128a05a035fd8f2e Mon Sep 17 00:00:00 2001 From: "Daniel A. Nagy" Date: Fri, 16 Feb 2018 16:16:55 +0100 Subject: [PATCH 0469/1085] Added copyright notice, removed ERC 76 dependency --- EIPS/eip-681.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-681.md b/EIPS/eip-681.md index 1b1f27c3390b5..1174c3c516ddd 100644 --- a/EIPS/eip-681.md +++ b/EIPS/eip-681.md @@ -6,7 +6,6 @@ Type: Standard Track Category: ERC Status: Draft - Replaces: 67 Created: 2017-08-01 Requires: 20, 137 @@ -76,3 +75,7 @@ The proposed format is chosen to resemble `bitcoin:` URLs as closely as possible ## Compatibility and Versioning Future upgrades that are partially or fully incompatible with this proposal should introduce a version prefix to `target_address` that is separated by a dash (`-`) character from whatever follows it. Exact specifications lie outside the scope of this document. + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 1d613bab257aaa1c8013aaed54c5e608c53cad3b Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 16 Feb 2018 14:18:18 -0500 Subject: [PATCH 0470/1085] Specify functions that cannot throw --- EIPS/eip-721.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 015e31ccfb2cf..cb8882c7faba0 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -77,6 +77,7 @@ interface ERC721 /* is ERC165 */ { /// @notice Count all deeds assigned to an owner /// @dev Throws if `_owner` is the zero address, representing invalid deeds. + /// Otherwise this function must not throw. /// @param _owner An address where we are interested in deeds owned by them /// @return The number of deeds owned by `_owner`, possibly zero function countOfDeedsByOwner(address _owner) external view returns (uint256 _count); @@ -84,6 +85,7 @@ interface ERC721 /* is ERC165 */ { /// @notice Enumerate deeds assigned to an owner /// @dev Throws if `_index` >= `countOfDeedsByOwner(_owner)` or if /// `_owner` is the zero address, representing invalid deeds. + /// Otherwise this must not throw. /// @param _owner An address where we are interested in deeds owned by them /// @param _index A counter less than `countOfDeedsByOwner(_owner)` /// @return The identifier for the `_index`th deed assigned to `_owner`, @@ -194,18 +196,21 @@ interface ERC721Enumerable { // this.ownerByIndex.selector; /// @notice Enumerate active deeds - /// @dev Throws if `_index` >= `countOfDeeds()` + /// @dev Throws if `_index` >= `countOfDeeds()`. + /// Otherwise must not throw. /// @param _index A counter less than `countOfDeeds()` /// @return The identifier for the `_index`th deed, (sort order not /// specified) function deedByIndex(uint256 _index) external view returns (uint256 _deedId); /// @notice Count of owners which own at least one deed + /// Must not throw. /// @return A count of the number of owners which own deeds function countOfOwners() external view returns (uint256 _count); /// @notice Enumerate owners /// @dev Throws if `_index` >= `countOfOwners()` + /// Otherwise must not throw. /// @param _index A counter less than `countOfOwners()` /// @return The address of the `_index`th owner (sort order not specified) function ownerByIndex(uint256 _index) external view returns (address _owner); @@ -215,7 +220,7 @@ interface ERC721Enumerable { Here is a also an optional **ERC-721 Operators Extension** for delegating access to your deeds. This is copied from the ERC-777 efforts. At this time DO NOT recommend this extension because of [a security considuration](https://github.com/ethereum/EIPs/issues/777#issuecomment-366182824) but we are putting it forth as a starting point for discussion. ```solidity -/// WARNING: THIS INTERFACE IS TO PROMOTO DISCUSSION, WE DO NOT RECOMMEND YOU +/// WARNING: THIS INTERFACE IS TO PROMOTE DISCUSSION, WE DO NOT RECOMMEND YOU /// IMPLEMENT IT YET AS THERE ARE SECURITY CONSIDERATIONS /// @title Delegated operator extension to ERC-721 interface /// @author William Entriken (https://phor.net) From 792bf0520f98e05f25338b36536931cd9802e879 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 16 Feb 2018 14:24:22 -0500 Subject: [PATCH 0471/1085] Better address BC --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index cb8882c7faba0..958ff35e7e8df 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -323,7 +323,7 @@ Cody, is presenting ERC-721 at the UN Future of Finance Hackathon. ## Backwards Compatibility -This standard is inspired by the semantics of ERC-20, but can't be compatible with it due to the fundamental differences between tokens and deeds. +This standard is inspired by the semantics of ERC-20, but can't be compatible with it due to the fundamental differences between tokens and deeds. However, we do note that a deed implementation is able to satisfy the read-only ERC-20 functionality by implementing the functions `totalSupply` and `balanceOf` as aliases of `countOfDeeds` and `countOfDeedsByOwner` respectively and by implementing `decimals` to return 0. Example deeds implementations as of January 2018: From 39285480caa015bb46b3a373c013a23d3045ace9 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 16 Feb 2018 18:57:27 -0500 Subject: [PATCH 0472/1085] Remove authors @VoR0220 @Souptacular @GriffGreen --- EIPS/eip-165.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index 392ff855547d4..aefeccb10a58c 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -3,7 +3,7 @@ ``` EIP: Title: ERC-165 Standard Interface Detection -Author: Christian Reitwießner , Nick Johnson , RJ Catalano , Fabian Vogelsteller , Hudson Jameson , Jordi Baylina , Griff Green , Konrad Feldmeier , William Entriken +Author: Christian Reitwießner , Nick Johnson , Fabian Vogelsteller , Jordi Baylina , Konrad Feldmeier , William Entriken Type: Standard Track Category: ERC Status: Draft From b97350cb1ba9fde52ea9776495d5a595b3dbd492 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 16 Feb 2018 19:34:44 -0500 Subject: [PATCH 0473/1085] Copyediting review --- EIPS/eip-165.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index aefeccb10a58c..a4c4a79b7a3f6 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -31,7 +31,7 @@ For some "standard interfaces" like [the ERC-20 token interface](https://github. ### How Interfaces are Identified -For this standard, an *interface* is a set of [function selectors as defined by the Ethereum ABI](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. +For this standard, an *interface* is a set of [function selectors as defined by the Ethereum ABI](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 defines return types, mutability and events. We define the interface identifier as the XOR of all function selectors in the interface. This code example shows how to calculate an interface identifier: @@ -51,7 +51,7 @@ contract Selector { } ``` -Note: interfaces do not permit optional functions, therefore, the interface identity will not them. +Note: interfaces do not permit optional functions, therefore, the interface identity will not include them. ### How a Contract will Publish the Interfaces it Implements @@ -64,7 +64,7 @@ interface ERC165 { /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @dev Interface identification is specified in ERC-165. This function - /// uses less than 30000 gas. + /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface(bytes4 interfaceID) external view returns (bool); @@ -80,22 +80,22 @@ Therefore the implementing contract will have a `supportsInterface` function tha - `true` for any other `interfaceID` this contract implements - `false` for any other `interfaceID` -This function must return a bool and use at most 30000 gas. +This function must return a bool and use at most 30,000 gas. Implementation note, there are several logical ways to implement this function. Please see the example implementations and the discussion on gas usage. ### How to Detect if a Contract Implements ERC-165 -1. 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")`. +1. The source contact makes a `STATICCALL` to the destination address with input data: `0x01ffc9a701ffc9a7` and gas 30,000. This corresponds to `contract.supportsInterface("0x01ffc9a7")`. 2. If the call fails or return false, the destination contract does not implement ERC-165. 3. If the call returns true, a second call is made with input data `0x01ffc9a7ffffffff`. 4. If the second call fails or returns true, the destination contract does not implement ERC-165. -5. Otherwise it implements EIP165. +5. Otherwise it implements ERC-165. ### How to Detect if a Contract Implements any Given Interface -1. If you are not sure if the contract implements ERC-165 Interface, use the previous procedure to confirm. -2. If it does not implement ERC-165, then you will have to see what methods it uses the old fashioned way. +1. If you are not sure if the contract implements ERC-165, use the above procedure to confirm. +2. If it does not implement ERC-165, then you will have to see what methods it uses the old-fashioned way. 3. If it implements ERC-165 then just call `supportsInterface(interfaceID)` to determine if it implements an interface you can use. ## Rationale @@ -168,7 +168,7 @@ contract ERC165Cache { mstore(add(x, 0x04), _interfaceId) // Place first argument directly next to signature success := staticcall( - 30000, // 5k gas + 30000, // 30k gas _contract, // To addr x, // Inputs are stored at location x 0x8, // Inputs are 8 byes long @@ -240,7 +240,7 @@ contract Homer is ERC165, Simpson { } ``` -With 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. +With three or more supported interfaces (including ERC165 itself as a required supported interface), the mapping approach (in every case) costs less gas than the pure approach (at worst case). ## Copyright From f346b609cfc45e2b98607257513cda4b6338a2ec Mon Sep 17 00:00:00 2001 From: Mandar Vaze Date: Mon, 19 Feb 2018 12:46:47 +0530 Subject: [PATCH 0474/1085] Fixed a typo --- EIPS/eip-20.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-20.md b/EIPS/eip-20.md index 01cd434d8100d..c870d176db3ca 100644 --- a/EIPS/eip-20.md +++ b/EIPS/eip-20.md @@ -186,7 +186,7 @@ Different implementations have been written by various teams that have different Historical links releated to this standard: -- Orginial proposal from Vitalik Buterin: https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs/499c882f3ec123537fc2fccd57eaa29e6032fe4a +- Original proposal from Vitalik Buterin: https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs/499c882f3ec123537fc2fccd57eaa29e6032fe4a - Reddit discussion: https://www.reddit.com/r/ethereum/comments/3n8fkn/lets_talk_about_the_coin_standard/ - Original Issue #20: https://github.com/ethereum/EIPs/issues/20 From 1a1295c903dfd2da18024c8c717054af394b847f Mon Sep 17 00:00:00 2001 From: William Entriken Date: Mon, 19 Feb 2018 02:54:55 -0500 Subject: [PATCH 0475/1085] Harmonize this standard to results from the ETHDenver event --- EIPS/eip-721.md | 359 ++++++++++++++++++++++++------------------------ 1 file changed, 177 insertions(+), 182 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 958ff35e7e8df..ba635e5b961a2 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -13,19 +13,25 @@ Requires: ERC-165 ## Simple Summary -A standard interface for deeds, also known as non-fungible tokens. +A standard interface for deeds. Deeds express ownership of *things*. ## Abstract -**This is a standard interface for smart contracts to handle deed ownership.** Deeds can represent ownership of physical property, like houses, or digital property, like unique pictures of kittens. In general, all houses are distinct and no two kittens are alike. Therefore you must track each deed separately; it is insufficient to simply count the deeds you own. +**This is a standard interface for smart contracts to handle deeds.** The scope of this interface includes **interrogating the smart contract about deeds**. It also allows **transferring deeds**. We consider use cases of deeds used by individuals as well as consignment to third party brokers/wallets/auctioneers. -The scope of this interface includes **interrogating the smart contract about deed ownership**. It also **allows deed owners to transfer assets**. The authors considered uses cases of individual deed ownership as well as custody by third party brokers/wallets/auctioneers. +The *things* to which deeds express ownership are an implementation detail. While writing this standard we considered a diverse univerise of *things*, and we know you will dream up many more: + +- Physical property — houses, unique artwork +- Digital property — unique pictures of kittens, collectable cards +- "Negative value" assets — loans, burdens and other responsibilities + +In general, all houses are distinct and no two kittens are alike. Therefore you must track each deed separately; it is insufficient to simply count the deeds you own. ## Motivation -A standard interface allows wallet/broker/auction applications to work with any deed on Ethereum. We provide for simple deed contracts as well as contracts that track a *large* number of deeds. Additional applications are discussed below. +A standard interface allows wallet/broker/auction applications to work with any deed on Ethereum. We provide for simple deed contracts as well as contracts that track an *arbitrarily large* number of deeds. Additional applications are discussed below. -This standard is inspired by [the ERC-20 token standard](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) and builds on two years of experience since EIP-20 was created. EIP-20 is insufficient for tracking deed ownership because each deed is distinct (non-fungible) whereas each token is identical (fungible). +This standard is inspired by [the ERC-20 token standard](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) and builds on two years of experience since EIP-20 was created. EIP-20 is insufficient for tracking deed ownership because each deed is distinct (non-fungible) whereas each of a quantity of tokens is identical (fungible). Differences between this standard and EIP-20 are examined below. @@ -33,167 +39,142 @@ Differences between this standard and EIP-20 are examined below. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt). -The **baseline specification** is REQUIRED for all ERC-721 implementations (subject to "caveats", below). +The **baseline specification** is REQUIRED for all ERC-721 implementations (see "caveats", below). ```solidity pragma solidity ^0.4.20; import "./ERC165.sol"; -/// @title Interface for contracts conforming to ERC-721: Deed Standard -/// @author William Entriken (https://phor.net), et. al. -/// @dev Specification at https://github.com/ethereum/eips/XXXFinalUrlXXX +/// @title Required part of ERC-721 Deed Standard +/// @author William Entriken (https://phor.net) +/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md +/// Note: the ERC-165 (DRAFT) identifier for this interface is 0xb3a99827 interface ERC721 /* is ERC165 */ { + /// @dev This emits when ownership of any deed changes by any mechanism. + /// This event emits when deeds are created (`from` == 0) and destroyed + /// (`to` == 0). Exception: during contract creation, any number of deeds + /// may be created and assigned without emitting Transfer. At the time of + /// any transfer, the "approved deed controller" is implicitly reset to the + /// zero address. + event Transfer(address indexed _from, address indexed _to, uint256 _deedId); + + /// @dev This emits when the "approved deed controller" for a deed is + /// changed or reaffirmed. The zero address indicates there is no approved + /// deed controller. When a Transfer event emits, this also indicates the + /// approved deed controller (if any) is reset to none. + event Approval(address indexed _owner, address indexed _approved, uint256 _deedId); + + /// @dev This emits when the "delegate operator" for an account is changed + /// or reaffirmed. The zero address indicates there is no delegate + /// operator. + event Delegation(address indexed _owner, address indexed _delegate); - // COMPLIANCE WITH ERC-165 (DRAFT) ///////////////////////////////////////// - - // bytes4 internal constant INTERFACE_SIGNATURE_ERC165 = // 0x01ffc9a7 - // this.supportsInterface.selector; - - /// @dev ERC-165 (draft) interface signature for itself - // bytes4 internal constant INTERFACE_SIGNATURE_ERC721 = // xxxxxx - // this.ownerOf.selector ^ - // this.countOfDeeds.selector ^ - // this.countOfDeedsByOwner.selector ^ - // this.deedOfOwnerByIndex.selector ^ - // this.approve.selector ^ - // this.takeOwnership.selector ^ - // this.transfer.selector; - - // PUBLIC QUERY FUNCTIONS ////////////////////////////////////////////////// + /// @notice Count all deeds assigned to an owner + /// @dev Deeds assigned to zero address are considered invalid, and this + /// function throws for queries about the zero address. + /// @param _owner An address for whom to query the balance + /// @return The number of deeds owned by `_owner`, possibly zero + function balanceOf(address _owner) external view returns (uint256 _balance); /// @notice Find the owner of a deed /// @param _deedId The identifier for a deed we are inspecting - /// @dev Deeds assigned to zero address are considered invalid, and - /// queries about them do throw. - /// @return The non-zero address of the owner of deed `_deedId`, or `throw` - /// if deed `_deedId` is not tracked by this contract + /// @dev Deeds assigned to zero address are considered invalid, and queries + /// about them do throw. + /// @return The address of the owner of the deed function ownerOf(uint256 _deedId) external view returns (address _owner); - /// @notice Count deeds tracked by this contract - /// @return A count of valid deeds tracked by this contract, where each one of - /// them has an assigned and queryable owner not equal to the zero address - function countOfDeeds() external view returns (uint256 _count); - - /// @notice Count all deeds assigned to an owner - /// @dev Throws if `_owner` is the zero address, representing invalid deeds. - /// Otherwise this function must not throw. - /// @param _owner An address where we are interested in deeds owned by them - /// @return The number of deeds owned by `_owner`, possibly zero - function countOfDeedsByOwner(address _owner) external view returns (uint256 _count); - - /// @notice Enumerate deeds assigned to an owner - /// @dev Throws if `_index` >= `countOfDeedsByOwner(_owner)` or if - /// `_owner` is the zero address, representing invalid deeds. - /// Otherwise this must not throw. - /// @param _owner An address where we are interested in deeds owned by them - /// @param _index A counter less than `countOfDeedsByOwner(_owner)` - /// @return The identifier for the `_index`th deed assigned to `_owner`, - /// (sort order not specified) - function deedOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256 _deedId); - - // TRANSFER MECHANISM ////////////////////////////////////////////////////// - - /// @dev This event emits when ownership of any deed changes by any - /// mechanism. This event emits when deeds are created (`from` == 0) and - /// destroyed (`to` == 0). Exception: during contract creation, any - /// transfers may occur without emitting `Transfer`. At the time of any transfer, - /// the "approved taker" is implicitly reset to the zero address. - event Transfer(address indexed from, address indexed to, uint256 indexed deedId); - - /// @dev The Approve event emits to log the "approved taker" for a deed -- whether - /// set for the first time, reaffirmed by setting the same value, or setting to - /// a new value. The "approved taker" is the zero address if nobody can take the - /// deed now or it is an address if that address can call `takeOwnership` to attempt - /// taking the deed. Any change to the "approved taker" for a deed SHALL cause - /// Approve to emit. However, an exception, the Approve event will not emit when - /// Transfer emits, this is because Transfer implicitly denotes the "approved taker" - /// is reset to the zero address. - event Approval(address indexed from, address indexed to, uint256 indexed deedId); - - /// @notice Set the "approved taker" for your deed, or revoke approval by - /// setting the zero address. You may `approve` any number of times while - /// the deed is assigned to you, only the most recent approval matters. Emits - /// an Approval event. - /// @dev Throws if `msg.sender` does not own deed `_deedId` or if `_to` == - /// `msg.sender` or if `_deedId` is not a valid deed. - /// @param _deedId The deed for which you are granting approval - function approve(address _to, uint256 _deedId) external payable; - - /// @notice Become owner of a deed for which you are currently approved - /// @dev Throws if `msg.sender` is not approved to become the owner of - /// `deedId` or if `msg.sender` currently owns `_deedId` or if `_deedId is not a - /// valid deed. - /// @param _deedId The deed that is being transferred - function takeOwnership(uint256 _deedId) external payable; - - /// @notice Set a new owner for your deed - /// @dev Throws if `msg.sender` does not own deed `_deedId` or if `_to` == - /// `msg.sender` or if `_deedId` is not a valid deed. - /// @param _deedId The deed that is being transferred + /// @notice Set a new owner for a deed + /// @dev Throws unless `msg.sender` is the current deed owner, the "delegate + /// operator" of the current deed owner, or the "approved deed controller". + /// Throws if `_to` currently owns the deed. Throws if `_to` is the zero + /// address. + /// @param _to The new owner for the deed + /// @param _deedId The deed to transfer function transfer(address _to, uint256 _deedId) external payable; + + /// @notice Set or reaffirm the "approved deed controller" for a deed + /// @dev The zero address indicates there is no approved deed controller. + /// @dev Throws unless `msg.sender` is the current deed owner, or the + /// "delegate operator" of the current deed owner. + /// @param _approved The new approved deed controller + /// @param _deedId The deed to approve + function approve(address _approved, uint256 _deedId) external payable; + + /// @notice Set or reaffirm the "delegate operator" for this account + /// @dev The zero address indicates there is no delegate operator. + /// @param _delegate The new delegate operator + function delegate(address _delegate) external; + + // CONFORMANCE TO ERC-165 (DRAFT) ////////////////////////////////////////// + + /// @notice Query if this implements an interface + /// @param interfaceID The interface identifier, as specified in ERC-165 + /// @dev Interface identification is specified in ERC-165. This function + /// uses less than 30,000 gas. + /// @return `true` if the contract implements `interfaceID` and + /// `interfaceID` is not 0xffffffff, `false` otherwise + function supportsInterface(bytes4 interfaceID) external view returns (bool); } ``` -Implementations MAY also choose to implement the **ERC-721 Metadata extension**. This is RECOMMENDED and will allow third party wallets to show your deeds in the best way. It will be a lot more flattering than - -> You just received deed ID `0xb9d6a94f1ab16f461b2af06aebab7e1cfe10ada985da001f274f370fbb848a40` from contract `0x0dcd2f752394c41875e259e00bb44fd505297caf`! +The **metadata extension** is OPTIONAL for ERC-721 implementations (see "caveats", below). This allows your contract to be interrogated for its name and for details about the *things*. ```solidity -/// @title Metadata extension to ERC-721 interface +/// @title Optional metadata extension to ERC-721 Deed Standard /// @author William Entriken (https://phor.net) -/// @dev Specification at https://github.com/ethereum/eips/issues/XXXX -interface ERC721Metadata { - - /// @dev ERC-165 (draft) interface signature for ERC721 - // bytes4 internal constant INTERFACE_SIGNATURE_ERC721Metadata = // 0x2a786f11 - // this.name.selector ^ - // this.symbol.selector ^ - // this.deedUri.selector; - - /// @notice A descriptive name for a collection of deeds managed by this - /// contract - /// @dev Wallets and exchanges MAY display this to the end user. +/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md +/// Note: the ERC-165 (DRAFT) identifier for this interface is 0x2a786f11 +interface ERC721Metadata /* is ERC721 */ { + /// @notice A descriptive name for a collection of deeds in this contract function name() external pure returns (string _name); - /// @notice An abbreviated name for deeds managed by this contract - /// @dev Wallets and exchanges MAY display this to the end user. + /// @notice An abbreviated name for deeds in this contract function symbol() external pure returns (string _symbol); - /// @notice A distinct URI (RFC 3986) for a given deed. - /// @dev If: - /// * The URI is a URL - /// * The URL is accessible - /// * The URL points to a valid JSON file format (ECMA-404 2nd ed.) - /// * The JSON base element is an object - /// then these names of the base element SHALL have special meaning: - /// * "name": A string identifying the item to which `_deedId` grants - /// ownership - /// * "description": A string detailing the item to which `_deedId` grants - /// ownership - /// * "image": A URI pointing to a file of image/* mime type representing - /// the item to which `_deedId` grants ownership - /// Wallets and exchanges MAY display this to the end user. - /// Consider making any images at a width between 320 and 1080 pixels and - /// aspect ratio between 1.91:1 and 4:5 inclusive. - /// Throws if `_deedId` is not a valid deed. + /// @notice A distinct Uniform Resource Identifier (URI) for a given deed. + /// @dev Throws if `_deedId` is not a valid deed. URIs are defined in RFC + /// 3986. The URI may point to a JSON file that conforms to the "ERC721 + /// Metadata JSON Schema". function deedUri(uint256 _deedId) external view returns (string _deedUri); } ``` -A second extension, the **ERC-721 Accountability Extension**, is OPTIONAL and allows your contract to make all deeds discoverable. +This is the "ERC721 Metadata JSON Schema" referenced above. Learn more about [JSON schemas](http://json-schema.org/). + +```json +{ + "title": "Deed Metadata", + "type": "object", + "properties": { + "name": { + "type": "string" + "description": "Identifies the thing to which the deed grants ownership", + }, + "description": { + "type": "string" + "description": "Describes the thing to which the deed grants ownership", + }, + "image": { + "type": "string" + "description": "A URI pointing to a resource with mime type image/* representing the thing to which the deeds grants ownership. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.", + } + } +} +``` + +The **enumeration extension** is OPTIONAL for ERC-721 implementations (see "caveats", below). This allows your contract to publish the the full list of deeds and make them discoverable. ```solidity -/// @title Enumeration extension to ERC-721 interface +/// @title Optional enumeration extension to ERC-721 Deed Standard /// @author William Entriken (https://phor.net) -/// @dev Specification at https://github.com/ethereum/eips/issues/XXXX -interface ERC721Enumerable { - - /// @dev ERC-165 (draft) interface signature for ERC721 - // bytes4 internal constant INTERFACE_SIGNATURE_ERC721Enumerable = // 0xa5e86824 - // this.deedByIndex.selector ^ - // this.countOfOwners.selector ^ - // this.ownerByIndex.selector; +/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md +/// Note: the ERC-165 (DRAFT) identifier for this interface is 0x5576ab6a +interface ERC721Enumerable /* is ERC721 */ { + /// @notice Count deeds tracked by this contract + /// @return A count of valid deeds tracked by this contract, where each one of + /// them has an assigned and queryable owner not equal to the zero address + function totalSupply() external view returns (uint256 _count); /// @notice Enumerate active deeds /// @dev Throws if `_index` >= `countOfDeeds()`. @@ -214,45 +195,33 @@ interface ERC721Enumerable { /// @param _index A counter less than `countOfOwners()` /// @return The address of the `_index`th owner (sort order not specified) function ownerByIndex(uint256 _index) external view returns (address _owner); -} -``` - -Here is a also an optional **ERC-721 Operators Extension** for delegating access to your deeds. This is copied from the ERC-777 efforts. At this time DO NOT recommend this extension because of [a security considuration](https://github.com/ethereum/EIPs/issues/777#issuecomment-366182824) but we are putting it forth as a starting point for discussion. - -```solidity -/// WARNING: THIS INTERFACE IS TO PROMOTE DISCUSSION, WE DO NOT RECOMMEND YOU -/// IMPLEMENT IT YET AS THERE ARE SECURITY CONSIDERATIONS -/// @title Delegated operator extension to ERC-721 interface -/// @author William Entriken (https://phor.net) -/// @dev Specification at https://github.com/ethereum/eips/issues/XXXX -interface ERC721Operators { - - /// @dev ERC-165 (draft) interface signature for ERC721 ... - function authorizeOperator(address operator) external; - function revokeOperator(address operator) external; - function isOperatorFor(address operator, address tokenHolder) external view returns (bool); - function operatorSend(address from, address to, uint256 _deedId) external; - event AuthorizedOperator(address indexed operator, address indexed tokenHolder); - event RevokedOperator(address indexed operator, address indexed tokenHolder); + /// @notice Enumerate deeds assigned to an owner + /// @dev Throws if `_index` >= `countOfDeedsByOwner(_owner)` or if + /// `_owner` is the zero address, representing invalid deeds. + /// Otherwise this must not throw. + /// @param _owner An address where we are interested in deeds owned by them + /// @param _index A counter less than `countOfDeedsByOwner(_owner)` + /// @return The identifier for the `_index`th deed assigned to `_owner`, + /// (sort order not specified) + function deedOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256 _deedId); } ``` - ### Caveats -The 0.4.19 Solidity interface grammar is not expressive enough to document the ERC-721 specification. A contract which complies with ERC-721 must also abide by the following: +The 0.4.20 Solidity interface grammar is not expressive enough to document the ERC-721 specification. A contract which complies with ERC-721 MUST also abide by the following: -- [Solidity issue #3412](https://github.com/ethereum/solidity/issues/3412): This interface includes explicit mutability guarantees for each function. Mutability guarantees are, in order weak to strong: `payable`, implicit nonpayable, `view`, and `pure`. Your implementation must meet the mutability guarantee in this interface or you may meet a stronger guarantee. For example, a `payable` function in this interface may be implemented as nonpayble (no state mutability specified) in your contract. We expect a later Solidity release will allow your stricter contract to inherit from this interface, but a workaround for version 0.4.19 is that you can edit this interface to add stricter mutability before inheriting from your contract. +- [Solidity issue #3412](https://github.com/ethereum/solidity/issues/3412): The above interfaces include explicit mutability guarantees for each function. Mutability guarantees are, in order weak to strong: `payable`, implicit nonpayable, `view`, and `pure`. Your implementation must meet the mutability guarantee in this interface or you may meet a stronger guarantee. For example, a `payable` function in this interface may be implemented as nonpayble (no state mutability specified) in your contract. We expect a later Solidity release will allow your stricter contract to inherit from this interface, but a workaround for version 0.4.20 is that you can edit this interface to add stricter mutability before inheriting from your contract. - [Solidity issue #3419](https://github.com/ethereum/solidity/issues/3419): If a contract is not compliant with `ERC721` then it is not compliant with `ERC721Metadata` or `ERC721Enumerable`. ERC-721 implements the requirements of interface [ERC-165](https://github.com/ethereum/EIPs/pull/881). - [Solidity issue #2330](https://github.com/ethereum/solidity/issues/2330): If a function is shown in this specification as `external` then a contract will be compliant if it uses `public` visibility. -- [Solidity issue #3494](https://github.com/ethereum/solidity/issues/3494): Use of `this.*.selector` is marked as a warning by Solidity, a future version of Solidity will not mark this as an error. +- Solidity issues [#3494](https://github.com/ethereum/solidity/issues/3494), [#3544](https://github.com/ethereum/solidity/issues/3544): Use of `this.*.selector` is marked as a warning by Solidity, a future version of Solidity will not mark this as an error. *If a newer version of Solidity allows the caveats to be expressed in code, then this EIP MAY be updated and the caveats removed, such will be equivalent to the original specification.* ## Rationale -There are many proposed uses of Ethereum smart contracts that depend on tracking individual deeds (non-fungible tokens). Examples of existing or planned NFTs are LAND in [Decentraland](https://decentraland.org/), the eponymous punks in [CryptoPunks](https://www.larvalabs.com/cryptopunks), and in-game items using systems like [Dmarket](https://www.dmarket.io/) or [EnjinCoin](https://enjincoin.io/). Future uses include tracking real-world non-fungible assets, like real-estate (as envisioned by companies like [Ubitquity](https://www.ubitquity.io/) or [Propy](https://tokensale.propy.com/)). It is critical in each of these cases that these items are not "lumped together" as numbers in a ledger, but instead, each token must have its ownership individually and atomically tracked. Regardless of the nature of these items, the ecosystem will be stronger if we have a standardized interface that allows for cross-functional deed management and sales platforms. +There are many proposed uses of Ethereum smart contracts that depend on tracking individual deeds (non-fungible tokens). Examples of existing or planned NFTs are LAND in [Decentraland](https://decentraland.org/), the eponymous punks in [CryptoPunks](https://www.larvalabs.com/cryptopunks), and in-game items using systems like [Dmarket](https://www.dmarket.io/) or [EnjinCoin](https://enjincoin.io/). Future uses include tracking real-world non-fungible assets, like real-estate (as envisioned by companies like [Ubitquity](https://www.ubitquity.io/) or [Propy](https://tokensale.propy.com/)). It is critical in each of these cases that these items are not "lumped together" as numbers in a ledger, but instead, each *thing* must have its ownership individually and atomically tracked. Regardless of the nature of these *things*, the ecosystem will be stronger if we have a standardized interface that allows for cross-functional deed management and sales platforms. **"Deed" word choice** @@ -260,27 +229,43 @@ The noun deed is defined in the Oxford Dictionary as: > A legal document that is signed and delivered, especially one regarding the ownership of property or legal rights. -This definition is consistent with the fact that ERC-721 contracts track ownership of other things, such as houses, pictures of kittens or collectable cards. If you gain ownership of a house via ERC-721 then the thing that the ERC-721 contract tracks is the *deed*, the place where you live is the *asset*. This standard is not concerned with the *collectable*, *item*, *thing*, or *asset* that you own -- we use these words interchangeably. +This definition is consistent with the fact that ERC-721 contracts track ownership of other *things*, such as houses, pictures of kittens or collectable cards. If you gain ownership of a house via ERC-721 then the ERC-721 contract manages the *deed* and the place where you live is the *thing*. + +We chose specifically to avoid the word "token" because it has a well known, and different, meaning in the Ethereum ecosystem, specifically ERC-20 tokens. *Alternatives considered: non-fungible token, title, token, asset, equity, ticket* **Deed identifiers** -The basis of this standard is that every deed is identified by a unique 256-bit unsigned integer within its tracking contract. This ID number MUST NOT change for the life of the contract. The pair `(contract address, deed ID)` will then be a globally unique and fully-qualified identifier for a specific deed within the Ethereum ecosystem. While some contracts may find it convenient to start with ID 0 and simply increment by one for each new NFT, callers MUST NOT assume that ID numbers have any specific pattern to them, and should treat the ID as a "black box". Also note that a deeds MAY become invalid (be destroyed). Please see the enumerations functions for a supported enumeration interface. +The basis of this standard is that every deed is identified by a unique 256-bit unsigned integer within its tracking contract. This ID number MUST NOT change for the life of the contract. The pair `(contract address, deed ID)` will then be a globally unique and fully-qualified identifier for a specific deed within the Ethereum ecosystem. While some contracts may find it convenient to start with ID 0 and simply increment by one for each new deed, callers MUST NOT assume that ID numbers have any specific pattern to them, and MUST treat the ID as a "black box". Also note that a deeds MAY become invalid (be destroyed). Please see the enumerations functions for a supported enumeration interface. The choice of uint256 allows a wide variety of applications because UUIDs and sha3 hashes are directly convertible to uint256. **Transfer mechanism** -ERC-721 standardizes a two-step process for transferring deeds inspired from [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md). This requires the sender to approve sending and the receiver to accept approval. In the original ERC-20, this caused a problem when `allowance` was called and then later modified to a different amount, as [disucssed on OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/issues/438). In this deed standard, there is no allowance because every deed is unique, the quantity is none or one. Therefore we receive the benefits of ERC-20's original design without problems that have been later discovered. +ERC-721 standardizes a single transfer function `transfer` and two levels of indirection: + +- The owner can transfer a deed to any address (except the zero address). +- The "approved deed controller" (if any) can transfer just like the owner. +- The "delegate operator" can transfer just like the owner and can assign the "approved deed controller". + +This provides a powerful set of tools for broker or auction applications to quickly use a *large* number of deeds. + +The `transfer` documentation only specifies conditions when the transaction MUST throw. Your implementation MAY also throw on calls `transfer`, `approve` and `delegate` in other situations. This allows implementations to achieve interesting results: -A careful reading of this standard's `approve`, `takeOwnership` and `transfer` functions also shows that *any* business reason may be used to deny transactions. Failed transactions will throw, a best practice identified in [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827) and [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol). Use of the `transfer` function is controversial and is discussed in [ERC-233](https://github.com/ethereum/EIPs/issues/223) and [ERC-677](https://github.com/ethereum/EIPs/issues/677), but we take the position that misuse of the `transfer` function is an implementation mistake not a standards mistake. +- **Disallow transfers if the contract is paused** — prior art, [Crypto Kitties](https://github.com/axiomzen/cryptokitties-bounty/blob/master/contracts/KittyOwnership.sol#L79) +- **Blacklist certain address from receiving deeds** — prior art, [Crypto Kitties, (lines 565, 566)](https://etherscan.io/address/0x06012c8cf97bead5deae237070f9587f8e7a266d#code). +- **Require every transaction to use the the approve-transfer workflow** — require `transfer` parameter `_to` to equal `msg.sender` +- **Charge a fee to both parties of a transaction** — require payment when calling `approve` with a non-zero `_approved` if it was previously the zero address, refund payment if calling `approve` with the zero address if it was previously a non-zero address, require payment when calling `transfer`, require `transfer` parameter `_to` to equal `msg.sender`, require `transfer` parameter `_to` to be the approved deed controller +- **Read only deed registry** — always throw from `transfer`, `approve` and `delegate` -Creating of new deeds and destruction of deeds is not included in the specification. Your implementing contract may implement these by other means. Please see the `event` documentation for your responsibilities when creating or destroying deeds. +Failed transactions will throw, a best practice identified in [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827) and [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol). [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) defined an `allowance` feature, this caused a problem when was called and then later modified to a different amount, as [disucssed on OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/issues/438). In this deed standard, there is no allowance because every deed is unique, the quantity is none or one. Therefore we receive the benefits of ERC-20's original design without problems that have been later discovered. -**Function mutability** +Use of the `transfer` function where the caller is the owner of the deed is controversial as discussed in [ERC-233](https://github.com/ethereum/EIPs/issues/223) and [ERC-677](https://github.com/ethereum/EIPs/issues/677). But we take the position that misuse of the `transfer` function is an implementation mistake not a standards mistake. -The transfer functions `approve`, `takeOwnership` and `transfer` are payable. Yes, really. The standard contemplates a real estate ownership application where transfer of property will require paying tax and/or various fees (including, but not limited to mining fees and pre-set transference fees), which may be paid by the old and/or new owner in any pre-arranged amount. Such an application would be compliant under this specification. Note that your contract may be nonpayable (syntactic sugar for `require(msg.value == 0)`) and be compliant, see caveats. +Creating of new deeds and destruction of deeds is not included in the specification. Your contract may implement these by other means. Please see the `event` documentation for your responsibilities when creating or destroying deeds. + +*Alternatives considered: only allow two-step ERC-20 style transaction, require that `transfer` never throw, require all functions to return a boolean indicating the success of the operation.* **ERC-165 interface** @@ -288,44 +273,54 @@ This specification includes a function `supportsInterface` which is standardized We chose ERC-165 over competing standard ERC-820 because of maturity. We consider ERC-165 low risk. But ERC-820, as recently as two weeks ago, [discovered a complete show-stopping flaw](https://github.com/ethereum/EIPs/issues/820#issuecomment-362049573). ERC-820 may be a great option, but we deem dependency on that standard an unacceptable risk at this time. -**Gas and complexity** +**Gas and complexity** (regarding the enumeration extension) + +This specification contemplates implementations that manage a few and *arbitrarily large* numbers of deeds. If your application is able to grow then [avoid using for/while loops in your code](https://github.com/axiomzen/cryptokitties-bounty/issues/4). These indicate your contract may be unable to scale and gas costs will rise over time without bound. + +[We have deployed](https://github.com/fulldecent/erc721-example) a contract to test net which instantiates and tracks 340282366920938463463374607431768211456 different deeds (2^128). That's enough to assign every IPV6 address to an Ethereum account owner, or to track ownership of nanobots a few micron in size and in aggregate totalling half the size of Earth. And you can query it from the blockchain. And every function takes less gas than [querying the ENS](https://ens.domains/). + +This illustration makes clear: the Deed Standard scales. -This specification contemplates contracts managing few and *many* deeds. Specifically, we note that a large contract, initially with `N` deeds owned by the contract owner, can be deployed with `O(1)` gas. All functions in the baseline and extension specifications can be implemented with `O(1)` gas and `O(Deed Count)` storage. We have an implementation with 1 billion deployed deeds on testnet. +*Alternatives considered: remove the deed enumeration function if it requries a for-loop, return a Soldity array type from enumeration functions.* -**Accountability** +**Privacy** -Minimally, only the functions `ownerOf`, `approve`, `takeOwnership` are necessary for a usable deed standard. But wallets/brokers/auctioneers identified in the motivation section have a strong need to identify which deeds an owner owns. +Wallets/brokers/auctioneers identified in the motivation section have a strong need to identify which deeds an owner owns. -It may be interesting to consider a use case where deeds are not enumerable or deeds are not enumerable by owner, such as a private registry of property ownership, or a partially-private registry. However, privacy cannot be attained because an attacker can simply (!) call `ownerOf` for every possible `deedId`. This is why we include just the most useful accounting in the baseline standard and the full accounting in the extension. +It may be interesting to consider a use case where deeds are not enumerable or deeds are not enumerable by owner, such as a private registry of property ownership, or a partially-private registry. However, privacy cannot be attained because an attacker can simply (!) call `ownerOf` for every possible `deedId`. -**Metadata** +**Metadata choices** (metadata extension) -We have chosen to make `name` and `symbol` both optional. These are interesting properties but are of limited utility. We remind wallet application authors that `name` and `symbol` cannot be trusted, a contract can easily return a value which overlaps with an existing well-known contract — or they may return an empty string / unusable value. +We have required `name` and `symbol` functions in the metadata extension. Every token EIP and draft we have reviewed ([ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md), [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827)) included these functions. Deeds **are not** tokens, but let's adopt existing conventions when it makes sense! + +We remind implementation authors that the empty string is a valid response to `name` and `symbol` if you protest to the usage of this mechanism. We also remind everyone that the official contract for tracking 0xProject tokens (`ZRX`) is [0xe41d2489571d322189246dafa5ebde1f4699f498](https://etherscan.io/address/0xe41d2489571d322189246dafa5ebde1f4699f498). Another contract that advertises a name of `0xProject` and symbol `ZRX` is not the well-known (canonical) contract. + +How a client may determine which token and deed contracts are well-known is outside the scope of this standard. A mechanism is provided to associate deeds with URIs. We expect that many implementations will take advantage of this to provide metadata for each deed. The image size recommendation is taken from Instagram, they probably know much about image usability. The URI MAY be mutable (i.e. it changes from time to time). We considered a deed representing ownership of a real-world asset, in this case metadata about such an asset may naturally change. Metadata is returned as a string value. Currently this is only usable as calling from `web3`, not from other contracts. This is acceptable because we have not considered a use case where an on-blockchain application would query such information. -**Operators** +*Alternatives considered: put all metadata for each deed on the blockchain (too expensive), use URL templates to query metadata parts (URL templates do not work with all URL schemes, especially P2P URLs), [multiaddr network address](https://github.com/multiformats/multiaddr) (not mature enough)* -[ERC-777 discusses "operators"](https://github.com/ethereum/EIPs/issues/777), entities that you may assign to control property for you. We have considered adding such a feature to this specification. We have considered against this because it should not be required — many contracts will not need this feature and such contracts have merit enough to be considered compliant with ERC-721. At this time, the operator model does not have much real-world experience. We expect that a future extension to this deed standard may introduce such functionality if warranted. - -**Discussions** +**Community consensus** A significant amount of discussion occurred on [the original ERC-721](ERC-721 issue), additionally we held a live meeting [on Gitter](https://gitter.im/ethereum/ERCs?at=5a62259b5ade18be3998eec4) that had good representation and [was](https://www.reddit.com/r/ethereum/comments/7r2ena/friday_119_live_discussion_on_erc_nonfungible/) [well](https://gitter.im/ethereum/EIPs?at=5a5f823fb48e8c3566f0a5e7) [advertised](https://github.com/ethereum/eips/issues/721#issuecomment-358369377) in relevant communities. Thank you to the participants: - [@ImAllInNow](https://github.com/imallinnow) Rob from DEC Gaming / Presenting Michigan Ethereum Meetup Feb 7 - [@Arachnid](https://github.com/arachnid) Nick Johnson - [@jadhavajay](https://github.com/jadhavajay) Ajay Jadhav from AyanWorks -- [@superphly](https://github.com/superphly) Cody Marx Bailey - XRAM Capital / Sharing at hackathon Jan 20 +- [@superphly](https://github.com/superphly) Cody Marx Bailey - XRAM Capital / Sharing at hackathon Jan 20 / UN Future of Finance Hackathon. + +A second event was held at ETHDenver 2018 to discuss deed standards (notes to be published). -Cody, is presenting ERC-721 at the UN Future of Finance Hackathon. +We have been very inclusive in this process and invite anyone with questions or contributions into our discussion. However, this standard is written only to support the identified use cases which are listed herein. ## Backwards Compatibility -This standard is inspired by the semantics of ERC-20, but can't be compatible with it due to the fundamental differences between tokens and deeds. However, we do note that a deed implementation is able to satisfy the read-only ERC-20 functionality by implementing the functions `totalSupply` and `balanceOf` as aliases of `countOfDeeds` and `countOfDeedsByOwner` respectively and by implementing `decimals` to return 0. +We have adopted `balanceOf`, `totalSupply`, `name` and `symbol` semantics from the [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) specification. An implementation may also include a function `decimals` that returns `uint8 0` if its intention is to be more compatible with ERC-20 while supporting this standard. However, we find it contrived to require all ERC-721 implementations to support the `decimals` function. -Example deeds implementations as of January 2018: +Example deeds implementations as of February 2018: - [CryptoKitties](https://www.cryptokitties.co/) — Compatible with an earlier version of this standard. - [CryptoPunks](https://www.larvalabs.com/cryptopunks) — Partially ERC-20 compatible, but not easily generalizable because it includes auction functionality directly in the contract and uses function names that explicitly refer to the deeds as "punks". From 7e33495cce02fe5bd68a29bd75be4e42724a8d4a Mon Sep 17 00:00:00 2001 From: "Daniel A. Nagy" Date: Mon, 19 Feb 2018 11:42:42 +0100 Subject: [PATCH 0476/1085] [ERC] Clarified gas and added 831 as a dependency. --- EIPS/eip-681.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-681.md b/EIPS/eip-681.md index 1174c3c516ddd..522b0a2c9732b 100644 --- a/EIPS/eip-681.md +++ b/EIPS/eip-681.md @@ -7,7 +7,7 @@ Category: ERC Status: Draft Created: 2017-08-01 - Requires: 20, 137 + Requires: 20, 137, 831 ## Simple Summary A standard way of representing various transactions, especially payment requests in Ethers and ERC #20 tokens as URLs. @@ -32,7 +32,7 @@ Payment request URLs contain "ethereum" in their schema (protocol) part and are ethereum_address = ( "0x" 40*40HEXDIG ) / ENS_NAME parameters = parameter *( "&" parameter ) parameter = key "=" value - key = "value" / "gas" / TYPE + key = "value" / "gas" / "gasLimit" / "gasPrice" / TYPE value = number / ethereum_address / STRING number = [ "-" / "+" ] *DIGIT [ "." 1*DIGIT ] [ ( "e" / "E" ) [ 1*DIGIT ] [ "+" UNIT ] @@ -47,7 +47,7 @@ the blockchain should refuse accepting requests with a non-empty `UNIT`, if it i Note that a `number` can be expressed in *scientific notation*, with a multiplier of a power of 10. The use of this notation is strongly encouraged when expressing monetary value in Ethers or ERC #20 tokens in atomic units (e. g. Wei, in case of Ether). -If *key* in the parameter list is `value` or `gas` then *value* MUST be a `number`. Otherwise, it must correspond to the `TYPE` string used as *key*. +If *key* in the parameter list is `value`, `gasLimit`, `gasPrice` or `gas` then *value* MUST be a `number`. Otherwise, it must correspond to the `TYPE` string used as *key*. For the syntax of ENS_NAME, please consult ERC #137 defining Ethereum Name Service. @@ -70,6 +70,8 @@ If the payer client has access to the blockchain, the interface should display t Note that the indicated amount is only a suggestion (as are all the supplied arguments) which the user is free to change. With no indicated amount, the user should be prompted to enter the amount to be paid. +Similarly `gasLimit` and `gasPrice` are suggested user-editable values for *gas limit* and *gas price*, respectively, for the requested transaction. It is acceptable to abbreviate `gasLimit` as `gas`, the two are treated synonymously. + ## Rationale The proposed format is chosen to resemble `bitcoin:` URLs as closely as possible, as both users and application programmers are already familiar with that format. In particular, this motivated the omission of the unit, which is often used in Ethereum ecosystem. Handling different orders of magnitude is delegated to the application, just like in the case of `bitcoin:`, but lacking access to the block chain, the application can take a hint from the exponent in the URL. Additional parameters may be added, if popular use cases requiring them emerge in practice. From 991d4f7bbf315a7425be33db90a0d5002de81857 Mon Sep 17 00:00:00 2001 From: "Daniel A. Nagy" Date: Mon, 19 Feb 2018 12:07:02 +0100 Subject: [PATCH 0477/1085] [ERC] Fixes Compatibility and Versioning Added explicit reference to #831 --- EIPS/eip-681.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-681.md b/EIPS/eip-681.md index 522b0a2c9732b..ab4b1cffe216a 100644 --- a/EIPS/eip-681.md +++ b/EIPS/eip-681.md @@ -76,7 +76,7 @@ Similarly `gasLimit` and `gasPrice` are suggested user-editable values for *gas The proposed format is chosen to resemble `bitcoin:` URLs as closely as possible, as both users and application programmers are already familiar with that format. In particular, this motivated the omission of the unit, which is often used in Ethereum ecosystem. Handling different orders of magnitude is delegated to the application, just like in the case of `bitcoin:`, but lacking access to the block chain, the application can take a hint from the exponent in the URL. Additional parameters may be added, if popular use cases requiring them emerge in practice. ## Compatibility and Versioning -Future upgrades that are partially or fully incompatible with this proposal should introduce a version prefix to `target_address` that is separated by a dash (`-`) character from whatever follows it. Exact specifications lie outside the scope of this document. +Future upgrades that are partially or fully incompatible with this proposal must use a prefix other than `pay-` that is separated by a dash (`-`) character from whatever follows it, as specified by ERC #831. ## Copyright From 881f577abbd5ca9c81d7e6d90d1b59e1446bc9b3 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Mon, 19 Feb 2018 16:43:01 -0500 Subject: [PATCH 0478/1085] Bytes, version 0.4.20, thanks @veox --- EIPS/eip-165.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index a4c4a79b7a3f6..4ce58d3f14408 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -171,7 +171,7 @@ contract ERC165Cache { 30000, // 30k gas _contract, // To addr x, // Inputs are stored at location x - 0x8, // Inputs are 8 byes long + 0x8, // Inputs are 8 bytes long x, // Store output over input (saves space) 0x20) // Outputs are 32 bytes long @@ -186,7 +186,7 @@ contract ERC165Cache { This 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. ```solidity -pragma solidity ^0.4.19; +pragma solidity ^0.4.20; import "./ERC165.sol"; @@ -221,7 +221,7 @@ contract Lisa is ERC165MappingImplementation, Simpson { Following 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. ```solidity -pragma solidity ^0.4.19; +pragma solidity ^0.4.20; import "./ERC165.sol"; From 734d68b6439941bf1577a4f1156b8e906185f7f5 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Mon, 19 Feb 2018 16:54:19 -0500 Subject: [PATCH 0479/1085] Use 32-byte words --- EIPS/eip-165.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index 4ce58d3f14408..740aa2d01a7e8 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -86,9 +86,9 @@ Implementation note, there are several logical ways to implement this function. ### How to Detect if a Contract Implements ERC-165 -1. The source contact makes a `STATICCALL` to the destination address with input data: `0x01ffc9a701ffc9a7` and gas 30,000. This corresponds to `contract.supportsInterface("0x01ffc9a7")`. +1. The source contact makes a `STATICCALL` to the destination address with input data: `0x01ffc9a700000000000000000000000001ffc9a7` and gas 30,000. This corresponds to `contract.supportsInterface("0x01ffc9a7")`. 2. If the call fails or return false, the destination contract does not implement ERC-165. -3. If the call returns true, a second call is made with input data `0x01ffc9a7ffffffff`. +3. If the call returns true, a second call is made with input data `0x01ffc9a7000000000000000000000000ffffffff`. 4. If the second call fails or returns true, the destination contract does not implement ERC-165. 5. Otherwise it implements ERC-165. @@ -171,7 +171,7 @@ contract ERC165Cache { 30000, // 30k gas _contract, // To addr x, // Inputs are stored at location x - 0x8, // Inputs are 8 bytes long + 0x20, // Inputs are 8 byes long x, // Store output over input (saves space) 0x20) // Outputs are 32 bytes long From b675b4b3fa453d8fdc218e1351668bfabb459ff5 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Tue, 20 Feb 2018 17:22:47 -0500 Subject: [PATCH 0480/1085] Update zero padding, thank you @veox --- EIPS/eip-165.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index 740aa2d01a7e8..ed4b91125ab6a 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -86,9 +86,9 @@ Implementation note, there are several logical ways to implement this function. ### How to Detect if a Contract Implements ERC-165 -1. The source contact makes a `STATICCALL` to the destination address with input data: `0x01ffc9a700000000000000000000000001ffc9a7` and gas 30,000. This corresponds to `contract.supportsInterface("0x01ffc9a7")`. +1. The source contact makes a `STATICCALL` to the destination address with input data: `0x01ffc9a701ffc9a7000000000000000000000000` and gas 30,000. This corresponds to `contract.supportsInterface("0x01ffc9a7")`. 2. If the call fails or return false, the destination contract does not implement ERC-165. -3. If the call returns true, a second call is made with input data `0x01ffc9a7000000000000000000000000ffffffff`. +3. If the call returns true, a second call is made with input data `0x01ffc9a7ffffffff000000000000000000000000`. 4. If the second call fails or returns true, the destination contract does not implement ERC-165. 5. Otherwise it implements ERC-165. From 12fe0b505c730a198b5f99df8b22e7adfd0c07f9 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Tue, 20 Feb 2018 17:33:49 -0500 Subject: [PATCH 0481/1085] Switch from a cache to a query contract, cache is out of scope --- EIPS/eip-165.md | 33 +++++++-------------------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index ed4b91125ab6a..af48ad201acdc 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -115,48 +115,29 @@ Following is a caching contract that detects which interfaces other contracts im ```solidity pragma solidity ^0.4.20; -contract ERC165Cache { +contract ERC165Query { bytes4 constant InvalidID = 0xffffffff; bytes4 constant ERC165ID = 0x01ffc9a7; - enum ImplStatus { Unknown, No, Yes } - mapping (address => mapping (bytes4 => ImplStatus)) cache; - - // Return value from cache if available - function interfaceSupported(address _contract, bytes4 _interfaceId) external returns (bool) { - ImplStatus status = cache[_contract][_interfaceId]; - if (status == ImplStatus.Unknown) { - return checkInterfaceSupported(_contract, _interfaceId); - } - return status == ImplStatus.Yes; - } - - // Repull result into cache - function checkInterfaceSupported(address _contract, bytes4 _interfaceId) public returns (bool) { - ImplStatus status = determineInterfaceImplementationStatus(_contract, _interfaceId); - cache[_contract][_interfaceId] = status; - return status == ImplStatus.Yes; - } - - function determineInterfaceImplementationStatus(address _contract, bytes4 _interfaceId) internal view returns (ImplStatus) { + function doesContractImplementInterface(address _contract, bytes4 _interfaceId) external view returns (bool) { uint256 success; uint256 result; (success, result) = noThrowCall(_contract, ERC165ID); if ((success==0)||(result==0)) { - return ImplStatus.No; + return false; } (success, result) = noThrowCall(_contract, InvalidID); if ((success==0)||(result!=0)) { - return ImplStatus.No; + return false; } (success, result) = noThrowCall(_contract, _interfaceId); if ((success==1)&&(result==1)) { - return ImplStatus.Yes; + return true; } - return ImplStatus.No; + return false; } function noThrowCall(address _contract, bytes4 _interfaceId) constant internal returns (uint256 success, uint256 result) { @@ -171,7 +152,7 @@ contract ERC165Cache { 30000, // 30k gas _contract, // To addr x, // Inputs are stored at location x - 0x20, // Inputs are 8 byes long + 0x20, // Inputs are 8 byes long x, // Store output over input (saves space) 0x20) // Outputs are 32 bytes long From 1947d2f676ff4efbb31217636d5223b20b8c97a0 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Tue, 20 Feb 2018 17:39:55 -0500 Subject: [PATCH 0482/1085] Complete Homer implementation --- EIPS/eip-165.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index af48ad201acdc..4eaac2992afc3 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -218,6 +218,9 @@ contract Homer is ERC165, Simpson { interfaceID == this.is2D.selector ^ this.skinColor.selector; // Simpson } + + function is2D() external returns (bool){} + function skinColor() external returns (string){} } ``` From 490ce29eca89bd921ed312d0e902a0bb7fb3e446 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Tue, 20 Feb 2018 17:45:23 -0500 Subject: [PATCH 0483/1085] not a cache --- EIPS/eip-165.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index 4eaac2992afc3..baf9224410780 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -110,7 +110,7 @@ Also [the ENS](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-137.md) alr ## Test Cases -Following is a caching contract that detects which interfaces other contracts implement. From @fulldecent and @jbaylina. +Following is a contract that detects which interfaces other contracts implement. From @fulldecent and @jbaylina. ```solidity pragma solidity ^0.4.20; From 4ecf5844603f4356e9784d5c5f6fe2591dba042e Mon Sep 17 00:00:00 2001 From: William Entriken Date: Tue, 20 Feb 2018 20:16:39 -0500 Subject: [PATCH 0484/1085] 32 bytes input --- EIPS/eip-165.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index baf9224410780..d3e42a27216ff 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -152,7 +152,7 @@ contract ERC165Query { 30000, // 30k gas _contract, // To addr x, // Inputs are stored at location x - 0x20, // Inputs are 8 byes long + 0x20, // Inputs are 32 bytes long x, // Store output over input (saves space) 0x20) // Outputs are 32 bytes long From 50ad36b0b1224f1306e9f919a52befe26fd56820 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 21 Feb 2018 13:40:29 -0500 Subject: [PATCH 0485/1085] Hex, not string --- EIPS/eip-165.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index d3e42a27216ff..5e5319001ae9b 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -86,7 +86,7 @@ Implementation note, there are several logical ways to implement this function. ### How to Detect if a Contract Implements ERC-165 -1. The source contact makes a `STATICCALL` to the destination address with input data: `0x01ffc9a701ffc9a7000000000000000000000000` and gas 30,000. This corresponds to `contract.supportsInterface("0x01ffc9a7")`. +1. The source contact makes a `STATICCALL` to the destination address with input data: `0x01ffc9a701ffc9a7000000000000000000000000` and gas 30,000. This corresponds to `contract.supportsInterface(0x01ffc9a7)`. 2. If the call fails or return false, the destination contract does not implement ERC-165. 3. If the call returns true, a second call is made with input data `0x01ffc9a7ffffffff000000000000000000000000`. 4. If the second call fails or returns true, the destination contract does not implement ERC-165. From e902727c3647263e33327d554efd26cd1d3c16ca Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 21 Feb 2018 13:44:16 -0500 Subject: [PATCH 0486/1085] Nibbles are not bytes, duh --- EIPS/eip-165.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index 5e5319001ae9b..aea9c8d176703 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -86,9 +86,9 @@ Implementation note, there are several logical ways to implement this function. ### How to Detect if a Contract Implements ERC-165 -1. The source contact makes a `STATICCALL` to the destination address with input data: `0x01ffc9a701ffc9a7000000000000000000000000` and gas 30,000. This corresponds to `contract.supportsInterface(0x01ffc9a7)`. +1. The source contact makes a `STATICCALL` to the destination address with input data: `0x01ffc9a701ffc9a700000000000000000000000000000000000000000000000000000000` and gas 30,000. This corresponds to `contract.supportsInterface(0x01ffc9a7)`. 2. If the call fails or return false, the destination contract does not implement ERC-165. -3. If the call returns true, a second call is made with input data `0x01ffc9a7ffffffff000000000000000000000000`. +3. If the call returns true, a second call is made with input data `0x01ffc9a7ffffffff00000000000000000000000000000000000000000000000000000000`. 4. If the second call fails or returns true, the destination contract does not implement ERC-165. 5. Otherwise it implements ERC-165. From d47923bc1b2550e9a22899e0b91e21d83ff2ffe7 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 21 Feb 2018 13:45:51 -0500 Subject: [PATCH 0487/1085] Update link https://github.com/ethereum/EIPs/pull/881#discussion_r169604965 --- EIPS/eip-165.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index aea9c8d176703..09009bcb5e670 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -25,7 +25,7 @@ Herein, we standardize the following: ## Motivation -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. +For some "standard interfaces" like [the ERC-20 token interface](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.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. ## Specification From 03c67d2e0867c051de6b500b7d2e55fc92dd99b5 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 21 Feb 2018 13:46:31 -0500 Subject: [PATCH 0488/1085] interfaced -> interacted https://github.com/ethereum/EIPs/pull/881#discussion_r169605418 --- EIPS/eip-165.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index 09009bcb5e670..d15ef2246d4ab 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -25,7 +25,7 @@ Herein, we standardize the following: ## Motivation -For some "standard interfaces" like [the ERC-20 token interface](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.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. +For some "standard interfaces" like [the ERC-20 token interface](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.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 interacted 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. ## Specification From 2cb6f9177fe409b49a4e9654edfb0e0e5f16a6f7 Mon Sep 17 00:00:00 2001 From: Nick Savers Date: Wed, 21 Feb 2018 23:43:12 +0100 Subject: [PATCH 0489/1085] Update eip-165.md --- EIPS/eip-165.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index d15ef2246d4ab..529b483eabd14 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -1,7 +1,7 @@ ## Preamble ``` -EIP: +EIP: 165 Title: ERC-165 Standard Interface Detection Author: Christian Reitwießner , Nick Johnson , Fabian Vogelsteller , Jordi Baylina , Konrad Feldmeier , William Entriken Type: Standard Track From 27035fa97e0ece058a1099f4c012774c856acba0 Mon Sep 17 00:00:00 2001 From: Nick Savers Date: Thu, 22 Feb 2018 00:08:01 +0100 Subject: [PATCH 0490/1085] Add ERC-165 and ERC-681 to README --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 13d65f9b75c61..b156d6714eca2 100644 --- a/README.md +++ b/README.md @@ -18,9 +18,11 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [5](EIPS/eip-5.md) | Gas Usage for `RETURN` and `CALL*` | Christian Reitwiessner | Core | Draft | | [101](EIPS/eip-101.md) | Serenity Currency and Crypto Abstraction | Vitalik Buterin | | Active | | [158](EIPS/eip-158.md) | State clearing | Vitalik Buterin | Core | Superseded | +| [165](EIPS/eip-165.md) | ERC-165 Standard Interface Detection | Christian Reitwiessner | Interface | Draft | | [234](EIPS/eip-234.md) | Add `blockHash` to JSON-RPC filter options | Micah Zoltu | Interface | Draft | -| [615](EIPS/eip-615.md) | Subroutines and Static Jumps for the EVM | Greg Colvin | Core | Draft | +| [615](EIPS/eip-615.md) | Subroutines and Static Jumps for the EVM | Greg Colvin | Core | Draft | | [616](EIPS/eip-EIPS/eip-616.md) | SIMD Operations for the EVM | Greg Colvin | Core | Draft | +| [681](EIPS/eip-681.md) | ERC-681 URL Format for Transaction Requests | Daniel A. Nagy | Interface | Draft | | [758](EIPS/eip-758.md) | Subscriptions and filters for transaction return data | Jack Peterson | Interface | Draft | | [801](EIPS/eip-801.md) | ERC-801 Canary Standard | ligi | Interface | Draft | From e694c6d862e02a6ba2555d6ecc35b045032403c9 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 23 Feb 2018 01:21:39 -0500 Subject: [PATCH 0491/1085] Use strong SHALL NOT language, thank you @carloschida --- EIPS/eip-721.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index ba635e5b961a2..9b5426d74e38a 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -213,7 +213,7 @@ interface ERC721Enumerable /* is ERC721 */ { The 0.4.20 Solidity interface grammar is not expressive enough to document the ERC-721 specification. A contract which complies with ERC-721 MUST also abide by the following: - [Solidity issue #3412](https://github.com/ethereum/solidity/issues/3412): The above interfaces include explicit mutability guarantees for each function. Mutability guarantees are, in order weak to strong: `payable`, implicit nonpayable, `view`, and `pure`. Your implementation must meet the mutability guarantee in this interface or you may meet a stronger guarantee. For example, a `payable` function in this interface may be implemented as nonpayble (no state mutability specified) in your contract. We expect a later Solidity release will allow your stricter contract to inherit from this interface, but a workaround for version 0.4.20 is that you can edit this interface to add stricter mutability before inheriting from your contract. -- [Solidity issue #3419](https://github.com/ethereum/solidity/issues/3419): If a contract is not compliant with `ERC721` then it is not compliant with `ERC721Metadata` or `ERC721Enumerable`. ERC-721 implements the requirements of interface [ERC-165](https://github.com/ethereum/EIPs/pull/881). +- [Solidity issue #3419](https://github.com/ethereum/solidity/issues/3419): A contract that implements `ERC721Metadata` or `ERC721Enumerable` SHALL also implement `ERC721`. sERC-721 implements the requirements of interface [ERC-165](https://github.com/ethereum/EIPs/pull/881). - [Solidity issue #2330](https://github.com/ethereum/solidity/issues/2330): If a function is shown in this specification as `external` then a contract will be compliant if it uses `public` visibility. - Solidity issues [#3494](https://github.com/ethereum/solidity/issues/3494), [#3544](https://github.com/ethereum/solidity/issues/3544): Use of `this.*.selector` is marked as a warning by Solidity, a future version of Solidity will not mark this as an error. @@ -237,7 +237,7 @@ We chose specifically to avoid the word "token" because it has a well known, and **Deed identifiers** -The basis of this standard is that every deed is identified by a unique 256-bit unsigned integer within its tracking contract. This ID number MUST NOT change for the life of the contract. The pair `(contract address, deed ID)` will then be a globally unique and fully-qualified identifier for a specific deed within the Ethereum ecosystem. While some contracts may find it convenient to start with ID 0 and simply increment by one for each new deed, callers MUST NOT assume that ID numbers have any specific pattern to them, and MUST treat the ID as a "black box". Also note that a deeds MAY become invalid (be destroyed). Please see the enumerations functions for a supported enumeration interface. +The basis of this standard is that every deed is identified by a unique 256-bit unsigned integer within its tracking contract. This ID number SHALL NOT change for the life of the contract. The pair `(contract address, deed ID)` will then be a globally unique and fully-qualified identifier for a specific deed within the Ethereum ecosystem. While some contracts may find it convenient to start with ID 0 and simply increment by one for each new deed, callers SHALL NOT assume that ID numbers have any specific pattern to them, and MUST treat the ID as a "black box". Also note that a deeds MAY become invalid (be destroyed). Please see the enumerations functions for a supported enumeration interface. The choice of uint256 allows a wide variety of applications because UUIDs and sha3 hashes are directly convertible to uint256. From ab00c604144a35ceb92a51c54538a66e1a4c96a1 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 23 Feb 2018 01:35:35 -0500 Subject: [PATCH 0492/1085] Update operator language --- EIPS/eip-721.md | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 9b5426d74e38a..9fc9fbe5aca26 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -3,7 +3,7 @@ ``` EIP: Title: ERC-721 Deed Standard -Author: William Entriken , Dieter Shirley , Nastassia Sachs +Author: William Entriken , Dieter Shirley , Jacob Evans , Nastassia Sachs Type: Standard Category ERC Status: Draft @@ -65,10 +65,9 @@ interface ERC721 /* is ERC165 */ { /// approved deed controller (if any) is reset to none. event Approval(address indexed _owner, address indexed _approved, uint256 _deedId); - /// @dev This emits when the "delegate operator" for an account is changed - /// or reaffirmed. The zero address indicates there is no delegate - /// operator. - event Delegation(address indexed _owner, address indexed _delegate); + /// @dev This emits when a third party ("operator") is enabled or disable for + /// an owner. The operator may manage all deeds of the owner. + event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); /// @notice Count all deeds assigned to an owner /// @dev Deeds assigned to zero address are considered invalid, and this @@ -84,7 +83,9 @@ interface ERC721 /* is ERC165 */ { /// @return The address of the owner of the deed function ownerOf(uint256 _deedId) external view returns (address _owner); - /// @notice Set a new owner for a deed + /// @notice Transfers the ownership of a deed -- warning the caller is + /// responsible to confirm that the sender is capable of receiving deeds + /// otherwise the deed may become inaccessible! /// @dev Throws unless `msg.sender` is the current deed owner, the "delegate /// operator" of the current deed owner, or the "approved deed controller". /// Throws if `_to` currently owns the deed. Throws if `_to` is the zero @@ -93,6 +94,17 @@ interface ERC721 /* is ERC165 */ { /// @param _deedId The deed to transfer function transfer(address _to, uint256 _deedId) external payable; + /// @notice Transfers the ownership of a given deed from one address to + /// another address + /// @dev Throws unless `msg.sender` is the current deed owner, the "delegate + /// operator" of the current deed owner, or the "approved deed controller". + /// Throws if `_to` currently owns the deed. Throws if `_to` is the zero + /// address. Throws if the deed is not currently owned by _from. + /// @param _from The current owner for the deed + /// @param _to The new owner for the deed + /// @param _deedId The deed to transfer + function transferFrom(address _from, address _to, uint256 _deedId) external payable; + /// @notice Set or reaffirm the "approved deed controller" for a deed /// @dev The zero address indicates there is no approved deed controller. /// @dev Throws unless `msg.sender` is the current deed owner, or the @@ -101,10 +113,12 @@ interface ERC721 /* is ERC165 */ { /// @param _deedId The deed to approve function approve(address _approved, uint256 _deedId) external payable; - /// @notice Set or reaffirm the "delegate operator" for this account - /// @dev The zero address indicates there is no delegate operator. - /// @param _delegate The new delegate operator - function delegate(address _delegate) external; + /// @notice Enable or disable approval for a third party ("operator") to manage + /// all your deeds. + /// @dev Emits the ApprovalForAll event + /// @param _operator Address to add to the set of authorized operators. + /// @param _approved True if the operators is approved, false to revoke approval + function setApprovalForAll(address _operateor, boolean _approved) payable; // CONFORMANCE TO ERC-165 (DRAFT) ////////////////////////////////////////// From 21e0d2472bc9c8b491457203128541e3a88f6bbb Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 23 Feb 2018 02:48:05 -0500 Subject: [PATCH 0493/1085] Rename to assets --- EIPS/eip-721.md | 272 ++++++++++++++++++++++++------------------------ 1 file changed, 138 insertions(+), 134 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 9fc9fbe5aca26..0fd68f607c146 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -2,7 +2,7 @@ ``` EIP: -Title: ERC-721 Deed Standard +Title: ERC-721 Distinguishable Assets Registry Author: William Entriken , Dieter Shirley , Jacob Evans , Nastassia Sachs Type: Standard Category ERC @@ -13,25 +13,25 @@ Requires: ERC-165 ## Simple Summary -A standard interface for deeds. Deeds express ownership of *things*. +A standard interface for any Distinguishable Assets Registry ("DAR"). A DAR tracks ownership of a set of assets that are mutually distinguishable. These assets may also be known as non-fungible tokens. ## Abstract -**This is a standard interface for smart contracts to handle deeds.** The scope of this interface includes **interrogating the smart contract about deeds**. It also allows **transferring deeds**. We consider use cases of deeds used by individuals as well as consignment to third party brokers/wallets/auctioneers. +Tracking the ownership of physical or digital distinguishable assets on a blockchain has a broad range of applications. We consider use cases of assets being owned and transacted by individuals as well as consignment to third party brokers/wallets/auctioneers ("operators"). -The *things* to which deeds express ownership are an implementation detail. While writing this standard we considered a diverse univerise of *things*, and we know you will dream up many more: +The kind of assets to which a DAR expresses ownership are an implementation detail. While writing this standard we considered a diverse univerise of assets, and we know you will dream up many more: - Physical property — houses, unique artwork -- Digital property — unique pictures of kittens, collectable cards +- Virtual collectables — unique pictures of kittens, collectable cards - "Negative value" assets — loans, burdens and other responsibilities -In general, all houses are distinct and no two kittens are alike. Therefore you must track each deed separately; it is insufficient to simply count the deeds you own. +In general, all houses are distinct and no two kittens are alike. Therefore you must track each asset separately; it is insufficient to simply count the assets you own. ## Motivation -A standard interface allows wallet/broker/auction applications to work with any deed on Ethereum. We provide for simple deed contracts as well as contracts that track an *arbitrarily large* number of deeds. Additional applications are discussed below. +A standard interface allows wallet/broker/auction applications to work with any DAR on Ethereum. We provide for simple DAR contracts as well as contracts that track an *arbitrarily large* number of assets. Additional applications are discussed below. -This standard is inspired by [the ERC-20 token standard](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) and builds on two years of experience since EIP-20 was created. EIP-20 is insufficient for tracking deed ownership because each deed is distinct (non-fungible) whereas each of a quantity of tokens is identical (fungible). +This standard is inspired by [the ERC-20 token standard](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) and builds on two years of experience since EIP-20 was created. EIP-20 is insufficient for tracking asset ownership because each asset is distinct (non-fungible) whereas each of a quantity of tokens is identical (fungible). Differences between this standard and EIP-20 are examined below. @@ -46,78 +46,79 @@ pragma solidity ^0.4.20; import "./ERC165.sol"; -/// @title Required part of ERC-721 Deed Standard +/// @title Required part of ERC-721 Distinguishable Assets Registry /// @author William Entriken (https://phor.net) /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md /// Note: the ERC-165 (DRAFT) identifier for this interface is 0xb3a99827 interface ERC721 /* is ERC165 */ { - /// @dev This emits when ownership of any deed changes by any mechanism. - /// This event emits when deeds are created (`from` == 0) and destroyed - /// (`to` == 0). Exception: during contract creation, any number of deeds + /// @dev This emits when ownership of any asset changes by any mechanism. + /// This event emits when assets are created (`from` == 0) and destroyed + /// (`to` == 0). Exception: during contract creation, any number of assets /// may be created and assigned without emitting Transfer. At the time of - /// any transfer, the "approved deed controller" is implicitly reset to the - /// zero address. - event Transfer(address indexed _from, address indexed _to, uint256 _deedId); + /// any transfer, the approved address for that assetis implicitly reset + /// to the zero address. + event Transfer(address indexed _from, address indexed _to, uint256 _assetId); - /// @dev This emits when the "approved deed controller" for a deed is - /// changed or reaffirmed. The zero address indicates there is no approved - /// deed controller. When a Transfer event emits, this also indicates the - /// approved deed controller (if any) is reset to none. - event Approval(address indexed _owner, address indexed _approved, uint256 _deedId); + /// @dev This emits when the approved address for an asset is changed or + /// reaffirmed. The zero address indicates there is no approved address for + /// that asset. When a Transfer event emits, this also indicates the + /// approved address is reset to none. + event Approval(address indexed _owner, address indexed _approved, uint256 _assetId); /// @dev This emits when a third party ("operator") is enabled or disable for - /// an owner. The operator may manage all deeds of the owner. + /// an owner. The operator may manage all assets of the owner. event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); - /// @notice Count all deeds assigned to an owner - /// @dev Deeds assigned to zero address are considered invalid, and this + /// @notice Count all assets assigned to an owner + /// @dev Assets assigned to zero address are considered invalid, and this /// function throws for queries about the zero address. /// @param _owner An address for whom to query the balance - /// @return The number of deeds owned by `_owner`, possibly zero + /// @return The number of assets owned by `_owner`, possibly zero function balanceOf(address _owner) external view returns (uint256 _balance); - /// @notice Find the owner of a deed - /// @param _deedId The identifier for a deed we are inspecting - /// @dev Deeds assigned to zero address are considered invalid, and queries + /// @notice Find the owner of an asset + /// @param _assetId The identifier for an asset we are inspecting + /// @dev Assets assigned to zero address are considered invalid, and queries /// about them do throw. - /// @return The address of the owner of the deed - function ownerOf(uint256 _deedId) external view returns (address _owner); - - /// @notice Transfers the ownership of a deed -- warning the caller is - /// responsible to confirm that the sender is capable of receiving deeds - /// otherwise the deed may become inaccessible! - /// @dev Throws unless `msg.sender` is the current deed owner, the "delegate - /// operator" of the current deed owner, or the "approved deed controller". - /// Throws if `_to` currently owns the deed. Throws if `_to` is the zero - /// address. - /// @param _to The new owner for the deed - /// @param _deedId The deed to transfer - function transfer(address _to, uint256 _deedId) external payable; - - /// @notice Transfers the ownership of a given deed from one address to - /// another address - /// @dev Throws unless `msg.sender` is the current deed owner, the "delegate - /// operator" of the current deed owner, or the "approved deed controller". - /// Throws if `_to` currently owns the deed. Throws if `_to` is the zero - /// address. Throws if the deed is not currently owned by _from. - /// @param _from The current owner for the deed - /// @param _to The new owner for the deed - /// @param _deedId The deed to transfer - function transferFrom(address _from, address _to, uint256 _deedId) external payable; - - /// @notice Set or reaffirm the "approved deed controller" for a deed - /// @dev The zero address indicates there is no approved deed controller. - /// @dev Throws unless `msg.sender` is the current deed owner, or the - /// "delegate operator" of the current deed owner. - /// @param _approved The new approved deed controller - /// @param _deedId The deed to approve - function approve(address _approved, uint256 _deedId) external payable; + /// @return The address of the owner of the asset + function ownerOf(uint256 _assetId) external view returns (address _owner); + + /// @notice Transfers the ownership of an asset -- warning the caller is + /// responsible to confirm that the sender is capable of receiving assets + /// otherwise the asset may become inaccessible! + /// @dev Throws unless `msg.sender` is the current asset owner, an operator + /// of the current asset owner, or the approved address of the asset. + /// Throws if `_to` currently owns the asset. + /// @param _to The new owner for the asset + /// @param _assetId The asset to transfer + function transfer(address _to, uint256 _assetId) external payable; + + /// @notice Transfers the ownership of a given asset from one address to + /// another address -- warning the caller is responsible to confirm that + /// the sender is capable of receiving assets otherwise the asset may become + /// inaccessible! + /// @dev Throws unless `msg.sender` is the current asset owner, an operator + /// of the current asset owner, or the approved address of the asset. + /// Throws if `_to` currently owns the asset. Throws if the asset is not + /// currently owned by _from. + /// @param _from The current owner for the asset + /// @param _to The new owner for the asset + /// @param _assetId The asset to transfer + function transferFrom(address _from, address _to, uint256 _assetId) external payable; + + /// @notice Set or reaffirm the authorized address for as asset + /// @dev The zero address indicates there is no authorized address. + /// @dev Throws unless `msg.sender` is the current asset owner, or an + /// operator of the current asset owner. + /// @param _approved The new authorized address + /// @param _assetId The asset to approve + function approve(address _approved, uint256 _assetId) external payable; /// @notice Enable or disable approval for a third party ("operator") to manage - /// all your deeds. + /// all your asset. /// @dev Emits the ApprovalForAll event /// @param _operator Address to add to the set of authorized operators. - /// @param _approved True if the operators is approved, false to revoke approval + /// @param _approved True to appove an operators, false to revoke approval function setApprovalForAll(address _operateor, boolean _approved) payable; // CONFORMANCE TO ERC-165 (DRAFT) ////////////////////////////////////////// @@ -132,25 +133,25 @@ interface ERC721 /* is ERC165 */ { } ``` -The **metadata extension** is OPTIONAL for ERC-721 implementations (see "caveats", below). This allows your contract to be interrogated for its name and for details about the *things*. +The **metadata extension** is OPTIONAL for ERC-721 implementations (see "caveats", below). This allows your contract to be interrogated for its name and for details about the assets. ```solidity -/// @title Optional metadata extension to ERC-721 Deed Standard +/// @title Optional metadata extension to ERC-721 Distinguishable Assets Registry /// @author William Entriken (https://phor.net) /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md /// Note: the ERC-165 (DRAFT) identifier for this interface is 0x2a786f11 interface ERC721Metadata /* is ERC721 */ { - /// @notice A descriptive name for a collection of deeds in this contract + /// @notice A descriptive name for a collection of assets in this contract function name() external pure returns (string _name); - /// @notice An abbreviated name for deeds in this contract + /// @notice An abbreviated name for assets in this contract function symbol() external pure returns (string _symbol); - /// @notice A distinct Uniform Resource Identifier (URI) for a given deed. - /// @dev Throws if `_deedId` is not a valid deed. URIs are defined in RFC + /// @notice A distinct Uniform Resource Identifier (URI) for a given asset. + /// @dev Throws if `_assetId` is not a valid asset. URIs are defined in RFC /// 3986. The URI may point to a JSON file that conforms to the "ERC721 /// Metadata JSON Schema". - function deedUri(uint256 _deedId) external view returns (string _deedUri); + function assetURI(uint256 _assetId) external view returns (string _assetURI); } ``` @@ -158,67 +159,68 @@ This is the "ERC721 Metadata JSON Schema" referenced above. Learn more about [JS ```json { - "title": "Deed Metadata", + "title": "Asset Metadata", "type": "object", "properties": { "name": { "type": "string" - "description": "Identifies the thing to which the deed grants ownership", + "description": "Identifies the asset to which the DAR grants ownership", }, "description": { "type": "string" - "description": "Describes the thing to which the deed grants ownership", + "description": "Describes the asset to which the DAR grants ownership", }, "image": { "type": "string" - "description": "A URI pointing to a resource with mime type image/* representing the thing to which the deeds grants ownership. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.", + "description": "A URI pointing to a resource with mime type image/* representing the asset to which the DAR grants ownership. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.", } } } ``` -The **enumeration extension** is OPTIONAL for ERC-721 implementations (see "caveats", below). This allows your contract to publish the the full list of deeds and make them discoverable. +The **enumeration extension** is OPTIONAL for ERC-721 implementations (see "caveats", below). This allows your contract to publish the the full list of assets and make them discoverable. ```solidity -/// @title Optional enumeration extension to ERC-721 Deed Standard +/// @title Optional enumeration extension to ERC-721 Distinguishable Assets Registry /// @author William Entriken (https://phor.net) /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md /// Note: the ERC-165 (DRAFT) identifier for this interface is 0x5576ab6a interface ERC721Enumerable /* is ERC721 */ { - /// @notice Count deeds tracked by this contract - /// @return A count of valid deeds tracked by this contract, where each one of + /// @notice Count assets tracked by this contract + /// @return A count of valid assets tracked by this contract, where each one of /// them has an assigned and queryable owner not equal to the zero address function totalSupply() external view returns (uint256 _count); - /// @notice Enumerate active deeds - /// @dev Throws if `_index` >= `countOfDeeds()`. - /// Otherwise must not throw. - /// @param _index A counter less than `countOfDeeds()` - /// @return The identifier for the `_index`th deed, (sort order not + /// @notice Enumerate active assets + /// @dev Throws if `_index` >= `totalSupply()`. + /// @param _index A counter less than `totalSupply()` + /// @return The identifier for the `_index`th asset, (sort order not /// specified) - function deedByIndex(uint256 _index) external view returns (uint256 _deedId); + function assetByIndex(uint256 _index) external view returns (uint256 _assetId); - /// @notice Count of owners which own at least one deed - /// Must not throw. - /// @return A count of the number of owners which own deeds + /// @notice Count of owners which own at least one asset + /// @return A count of the number of owners which own assets function countOfOwners() external view returns (uint256 _count); /// @notice Enumerate owners /// @dev Throws if `_index` >= `countOfOwners()` - /// Otherwise must not throw. /// @param _index A counter less than `countOfOwners()` /// @return The address of the `_index`th owner (sort order not specified) function ownerByIndex(uint256 _index) external view returns (address _owner); - /// @notice Enumerate deeds assigned to an owner - /// @dev Throws if `_index` >= `countOfDeedsByOwner(_owner)` or if - /// `_owner` is the zero address, representing invalid deeds. - /// Otherwise this must not throw. - /// @param _owner An address where we are interested in deeds owned by them - /// @param _index A counter less than `countOfDeedsByOwner(_owner)` - /// @return The identifier for the `_index`th deed assigned to `_owner`, + /// @notice Count assets of an owner + /// @param _owner The address to check + /// @return The number of valid assets owned by this owner + function countOfAssetsByOwner(address _owner) external view returns (uint256 _count); + + /// @notice Enumerate assets assigned to an owner + /// @dev Throws if `_index` >= `countOfAssetsByOwner(_owner)` or if + /// `_owner` is the zero address, representing invalid assets. + /// @param _owner An address where we are interested in assets owned by them + /// @param _index A counter less than `countOfAssetsByOwner(_owner)` + /// @return The identifier for the `_index`th asset assigned to `_owner`, /// (sort order not specified) - function deedOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256 _deedId); + function assetOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256 _assetId); } ``` @@ -226,8 +228,8 @@ interface ERC721Enumerable /* is ERC721 */ { The 0.4.20 Solidity interface grammar is not expressive enough to document the ERC-721 specification. A contract which complies with ERC-721 MUST also abide by the following: -- [Solidity issue #3412](https://github.com/ethereum/solidity/issues/3412): The above interfaces include explicit mutability guarantees for each function. Mutability guarantees are, in order weak to strong: `payable`, implicit nonpayable, `view`, and `pure`. Your implementation must meet the mutability guarantee in this interface or you may meet a stronger guarantee. For example, a `payable` function in this interface may be implemented as nonpayble (no state mutability specified) in your contract. We expect a later Solidity release will allow your stricter contract to inherit from this interface, but a workaround for version 0.4.20 is that you can edit this interface to add stricter mutability before inheriting from your contract. -- [Solidity issue #3419](https://github.com/ethereum/solidity/issues/3419): A contract that implements `ERC721Metadata` or `ERC721Enumerable` SHALL also implement `ERC721`. sERC-721 implements the requirements of interface [ERC-165](https://github.com/ethereum/EIPs/pull/881). +- [Solidity issue #3412](https://github.com/ethereum/solidity/issues/3412): The above interfaces include explicit mutability guarantees for each function. Mutability guarantees are, in order weak to strong: `payable`, implicit nonpayable, `view`, and `pure`. Your implementation must meet the mutability guarantee in this interface or you may meet a stronger guarantee. For example, a `payable` function in this interface may be implemented as nonpayble (no state mutability specified) in your contract. Workraound: until Solidity fixes this issue, you can edit this interface to add stricter mutability before inheriting from your contract. +- [Solidity issue #3419](https://github.com/ethereum/solidity/issues/3419): A contract that implements `ERC721Metadata` or `ERC721Enumerable` SHALL also implement `ERC721`. ERC-721 implements the requirements of interface [ERC-165](https://github.com/ethereum/EIPs/pull/881). - [Solidity issue #2330](https://github.com/ethereum/solidity/issues/2330): If a function is shown in this specification as `external` then a contract will be compliant if it uses `public` visibility. - Solidity issues [#3494](https://github.com/ethereum/solidity/issues/3494), [#3544](https://github.com/ethereum/solidity/issues/3544): Use of `this.*.selector` is marked as a warning by Solidity, a future version of Solidity will not mark this as an error. @@ -235,49 +237,51 @@ The 0.4.20 Solidity interface grammar is not expressive enough to document the E ## Rationale -There are many proposed uses of Ethereum smart contracts that depend on tracking individual deeds (non-fungible tokens). Examples of existing or planned NFTs are LAND in [Decentraland](https://decentraland.org/), the eponymous punks in [CryptoPunks](https://www.larvalabs.com/cryptopunks), and in-game items using systems like [Dmarket](https://www.dmarket.io/) or [EnjinCoin](https://enjincoin.io/). Future uses include tracking real-world non-fungible assets, like real-estate (as envisioned by companies like [Ubitquity](https://www.ubitquity.io/) or [Propy](https://tokensale.propy.com/)). It is critical in each of these cases that these items are not "lumped together" as numbers in a ledger, but instead, each *thing* must have its ownership individually and atomically tracked. Regardless of the nature of these *things*, the ecosystem will be stronger if we have a standardized interface that allows for cross-functional deed management and sales platforms. +There are many proposed uses of Ethereum smart contracts that depend on tracking distinguishable assets. Examples of existing or planned NFTs are LAND in [Decentraland](https://decentraland.org/), the eponymous punks in [CryptoPunks](https://www.larvalabs.com/cryptopunks), and in-game items using systems like [Dmarket](https://www.dmarket.io/) or [EnjinCoin](https://enjincoin.io/). Future uses include tracking real-world assets, like real-estate (as envisioned by companies like [Ubitquity](https://www.ubitquity.io/) or [Propy](https://tokensale.propy.com/)). It is critical in each of these cases that these items are not "lumped together" as numbers in a ledger, but instead, each asset must have its ownership individually and atomically tracked. Regardless of the nature of these assets, the ecosystem will be stronger if we have a standardized interface that allows for cross-functional asset management and sales platforms. -**"Deed" word choice** - -The noun deed is defined in the Oxford Dictionary as: - -> A legal document that is signed and delivered, especially one regarding the ownership of property or legal rights. - -This definition is consistent with the fact that ERC-721 contracts track ownership of other *things*, such as houses, pictures of kittens or collectable cards. If you gain ownership of a house via ERC-721 then the ERC-721 contract manages the *deed* and the place where you live is the *thing*. +**"Asset" word choice** We chose specifically to avoid the word "token" because it has a well known, and different, meaning in the Ethereum ecosystem, specifically ERC-20 tokens. -*Alternatives considered: non-fungible token, title, token, asset, equity, ticket* +The word "asset" well describes all the use cases we envisioned above. -**Deed identifiers** +*Alternatives considered: non-fungible token, title, token, asset, equity, ticket, deed* -The basis of this standard is that every deed is identified by a unique 256-bit unsigned integer within its tracking contract. This ID number SHALL NOT change for the life of the contract. The pair `(contract address, deed ID)` will then be a globally unique and fully-qualified identifier for a specific deed within the Ethereum ecosystem. While some contracts may find it convenient to start with ID 0 and simply increment by one for each new deed, callers SHALL NOT assume that ID numbers have any specific pattern to them, and MUST treat the ID as a "black box". Also note that a deeds MAY become invalid (be destroyed). Please see the enumerations functions for a supported enumeration interface. +**Asset identifiers** + +The basis of this standard is that every asset is identified by a unique 256-bit unsigned integer within its DAR. This ID number SHALL NOT change for the life of the contract. The pair `(contract address, uint265 assetId)` will then be a globally unique and fully-qualified identifier for a specific asset within the Ethereum ecosystem. While some contracts may find it convenient to start with ID 0 and simply increment by one for each new asset, callers SHALL NOT assume that ID numbers have any specific pattern to them, and MUST treat the ID as a "black box". Also note that a assets MAY become invalid (be destroyed). Please see the enumerations functions for a supported enumeration interface. The choice of uint256 allows a wide variety of applications because UUIDs and sha3 hashes are directly convertible to uint256. **Transfer mechanism** -ERC-721 standardizes a single transfer function `transfer` and two levels of indirection: +ERC-721 standardizes a single transfer function `transferFrom`, one convenience function, and two mechanisms for indirection: + +* The `transfer` function is equivalent to `transferFrom` except that the `_from` is calculated automatically — note that if a specific asset has an approved address then `transfer` has a race condition + 1. A and B approve operator C + 2. A transfers to B + 3. C uses `transfer` to get the asset + 4. Depending on the order of 2. and 3. getting mined, it is ambiguous whom C gets the asset from -- The owner can transfer a deed to any address (except the zero address). -- The "approved deed controller" (if any) can transfer just like the owner. -- The "delegate operator" can transfer just like the owner and can assign the "approved deed controller". +- The owner can transfer an asset to any address (except the zero address). +- The authorized address for an asset can transfer just like the owner. +- An operator can transfer just like the owner and can assign the authorized address. -This provides a powerful set of tools for broker or auction applications to quickly use a *large* number of deeds. +This provides a powerful set of tools for broker or auction applications to quickly use a *large* number of assets. -The `transfer` documentation only specifies conditions when the transaction MUST throw. Your implementation MAY also throw on calls `transfer`, `approve` and `delegate` in other situations. This allows implementations to achieve interesting results: +The `transfer` documentation only specifies conditions when the transaction MUST throw. Your implementation MAY also throw on calls `transfer`, `transfer `, `approve` and `setApproveForAll` in other situations. This allows implementations to achieve interesting results: - **Disallow transfers if the contract is paused** — prior art, [Crypto Kitties](https://github.com/axiomzen/cryptokitties-bounty/blob/master/contracts/KittyOwnership.sol#L79) -- **Blacklist certain address from receiving deeds** — prior art, [Crypto Kitties, (lines 565, 566)](https://etherscan.io/address/0x06012c8cf97bead5deae237070f9587f8e7a266d#code). +- **Blacklist certain address from receiving assets** — prior art, [Crypto Kitties, (lines 565, 566)](https://etherscan.io/address/0x06012c8cf97bead5deae237070f9587f8e7a266d#code). - **Require every transaction to use the the approve-transfer workflow** — require `transfer` parameter `_to` to equal `msg.sender` -- **Charge a fee to both parties of a transaction** — require payment when calling `approve` with a non-zero `_approved` if it was previously the zero address, refund payment if calling `approve` with the zero address if it was previously a non-zero address, require payment when calling `transfer`, require `transfer` parameter `_to` to equal `msg.sender`, require `transfer` parameter `_to` to be the approved deed controller -- **Read only deed registry** — always throw from `transfer`, `approve` and `delegate` +- **Charge a fee to both parties of a transaction** — require payment when calling `approve` with a non-zero `_approved` if it was previously the zero address, refund payment if calling `approve` with the zero address if it was previously a non-zero address, require payment when calling `transfer`, require `transfer` parameter `_to` to equal `msg.sender`, require `transfer` parameter `_to` to be the authorized address +- **Read only DAR** — always throw from `transfer`, `approve` and `delegate` -Failed transactions will throw, a best practice identified in [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827) and [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol). [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) defined an `allowance` feature, this caused a problem when was called and then later modified to a different amount, as [disucssed on OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/issues/438). In this deed standard, there is no allowance because every deed is unique, the quantity is none or one. Therefore we receive the benefits of ERC-20's original design without problems that have been later discovered. +Failed transactions will throw, a best practice identified in [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827) and [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol). [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) defined an `allowance` feature, this caused a problem when was called and then later modified to a different amount, as [disucssed on OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/issues/438). In this standard, there is no allowance because every asset is unique, the quantity is none or one. Therefore we receive the benefits of ERC-20's original design without problems that have been later discovered. -Use of the `transfer` function where the caller is the owner of the deed is controversial as discussed in [ERC-233](https://github.com/ethereum/EIPs/issues/223) and [ERC-677](https://github.com/ethereum/EIPs/issues/677). But we take the position that misuse of the `transfer` function is an implementation mistake not a standards mistake. +Use of the `transfer` function where the caller is the owner of the asset is controversial as discussed in [ERC-233](https://github.com/ethereum/EIPs/issues/223) and [ERC-677](https://github.com/ethereum/EIPs/issues/677). But we take the position that misuse of the `transfer` function is an implementation mistake not a standards mistake. -Creating of new deeds and destruction of deeds is not included in the specification. Your contract may implement these by other means. Please see the `event` documentation for your responsibilities when creating or destroying deeds. +Creating of new assets and destruction of assets is not included in the specification. Your contract may implement these by other means. Please see the `event` documentation for your responsibilities when creating or destroying assets. *Alternatives considered: only allow two-step ERC-20 style transaction, require that `transfer` never throw, require all functions to return a boolean indicating the success of the operation.* @@ -289,33 +293,33 @@ We chose ERC-165 over competing standard ERC-820 because of maturity. We conside **Gas and complexity** (regarding the enumeration extension) -This specification contemplates implementations that manage a few and *arbitrarily large* numbers of deeds. If your application is able to grow then [avoid using for/while loops in your code](https://github.com/axiomzen/cryptokitties-bounty/issues/4). These indicate your contract may be unable to scale and gas costs will rise over time without bound. +This specification contemplates implementations that manage a few and *arbitrarily large* numbers of assets. If your application is able to grow then [avoid using for/while loops in your code](https://github.com/axiomzen/cryptokitties-bounty/issues/4). These indicate your contract may be unable to scale and gas costs will rise over time without bound. -[We have deployed](https://github.com/fulldecent/erc721-example) a contract to test net which instantiates and tracks 340282366920938463463374607431768211456 different deeds (2^128). That's enough to assign every IPV6 address to an Ethereum account owner, or to track ownership of nanobots a few micron in size and in aggregate totalling half the size of Earth. And you can query it from the blockchain. And every function takes less gas than [querying the ENS](https://ens.domains/). +[We have deployed](https://github.com/fulldecent/erc721-example) a contract to test net which instantiates and tracks 340282366920938463463374607431768211456 different assets (2^128). That's enough to assign every IPV6 address to an Ethereum account owner, or to track ownership of nanobots a few micron in size and in aggregate totalling half the size of Earth. And you can query it from the blockchain. And every function takes less gas than [querying the ENS](https://ens.domains/). -This illustration makes clear: the Deed Standard scales. +This illustration makes clear: the Distinguishable Assets Registry standard scales. -*Alternatives considered: remove the deed enumeration function if it requries a for-loop, return a Soldity array type from enumeration functions.* +*Alternatives considered: remove the asset enumeration function if it requries a for-loop, return a Soldity array type from enumeration functions.* **Privacy** -Wallets/brokers/auctioneers identified in the motivation section have a strong need to identify which deeds an owner owns. +Wallets/brokers/auctioneers identified in the motivation section have a strong need to identify which assets an owner owns. -It may be interesting to consider a use case where deeds are not enumerable or deeds are not enumerable by owner, such as a private registry of property ownership, or a partially-private registry. However, privacy cannot be attained because an attacker can simply (!) call `ownerOf` for every possible `deedId`. +It may be interesting to consider a use case where assets are not enumerable or assets are not enumerable by owner, such as a private registry of property ownership, or a partially-private registry. However, privacy cannot be attained because an attacker can simply (!) call `ownerOf` for every possible `assetId`. **Metadata choices** (metadata extension) -We have required `name` and `symbol` functions in the metadata extension. Every token EIP and draft we have reviewed ([ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md), [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827)) included these functions. Deeds **are not** tokens, but let's adopt existing conventions when it makes sense! +We have required `name` and `symbol` functions in the metadata extension. Every token EIP and draft we have reviewed ([ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md), [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827)) included these functions. Assets **are not** tokens, but let's adopt existing conventions when it makes sense! We remind implementation authors that the empty string is a valid response to `name` and `symbol` if you protest to the usage of this mechanism. We also remind everyone that the official contract for tracking 0xProject tokens (`ZRX`) is [0xe41d2489571d322189246dafa5ebde1f4699f498](https://etherscan.io/address/0xe41d2489571d322189246dafa5ebde1f4699f498). Another contract that advertises a name of `0xProject` and symbol `ZRX` is not the well-known (canonical) contract. -How a client may determine which token and deed contracts are well-known is outside the scope of this standard. +How a client may determine which DARs are well-known is outside the scope of this standard. -A mechanism is provided to associate deeds with URIs. We expect that many implementations will take advantage of this to provide metadata for each deed. The image size recommendation is taken from Instagram, they probably know much about image usability. The URI MAY be mutable (i.e. it changes from time to time). We considered a deed representing ownership of a real-world asset, in this case metadata about such an asset may naturally change. +A mechanism is provided to associate assets with URIs. We expect that many implementations will take advantage of this to provide metadata for each asset. The image size recommendation is taken from Instagram, they probably know much about image usability. The URI MAY be mutable (i.e. it changes from time to time). We considered a asset representing ownership of a real-world asset, in this case metadata about such an asset may naturally change. Metadata is returned as a string value. Currently this is only usable as calling from `web3`, not from other contracts. This is acceptable because we have not considered a use case where an on-blockchain application would query such information. -*Alternatives considered: put all metadata for each deed on the blockchain (too expensive), use URL templates to query metadata parts (URL templates do not work with all URL schemes, especially P2P URLs), [multiaddr network address](https://github.com/multiformats/multiaddr) (not mature enough)* +*Alternatives considered: put all metadata for each asset on the blockchain (too expensive), use URL templates to query metadata parts (URL templates do not work with all URL schemes, especially P2P URLs), [multiaddr network address](https://github.com/multiformats/multiaddr) (not mature enough)* **Community consensus** @@ -326,7 +330,7 @@ A significant amount of discussion occurred on [the original ERC-721](ERC-721 is - [@jadhavajay](https://github.com/jadhavajay) Ajay Jadhav from AyanWorks - [@superphly](https://github.com/superphly) Cody Marx Bailey - XRAM Capital / Sharing at hackathon Jan 20 / UN Future of Finance Hackathon. -A second event was held at ETHDenver 2018 to discuss deed standards (notes to be published). +A second event was held at ETHDenver 2018 to discuss distinguishable asset standards (notes to be published). We have been very inclusive in this process and invite anyone with questions or contributions into our discussion. However, this standard is written only to support the identified use cases which are listed herein. @@ -334,13 +338,13 @@ We have been very inclusive in this process and invite anyone with questions or We have adopted `balanceOf`, `totalSupply`, `name` and `symbol` semantics from the [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) specification. An implementation may also include a function `decimals` that returns `uint8 0` if its intention is to be more compatible with ERC-20 while supporting this standard. However, we find it contrived to require all ERC-721 implementations to support the `decimals` function. -Example deeds implementations as of February 2018: +Example DAR implementations as of February 2018: - [CryptoKitties](https://www.cryptokitties.co/) — Compatible with an earlier version of this standard. -- [CryptoPunks](https://www.larvalabs.com/cryptopunks) — Partially ERC-20 compatible, but not easily generalizable because it includes auction functionality directly in the contract and uses function names that explicitly refer to the deeds as "punks". +- [CryptoPunks](https://www.larvalabs.com/cryptopunks) — Partially ERC-20 compatible, but not easily generalizable because it includes auction functionality directly in the contract and uses function names that explicitly refer to the assets as "punks". - [Auctionhouse Asset Interface](https://github.com/dob/auctionhouse/blob/master/contracts/Asset.sol) — [@dob](https://github.com/dob) needed a generic interface for his Auctionhouse dapp (currently ice-boxed). His "Asset" contract is very simple, but is missing ERC-20 compatibility, `approve()` functionality, and metadata. This effort is referenced in the discussion for [EIP-173](https://github.com/ethereum/EIPs/issues/173). -Note: "Limited edition, collectible tokens" like [Curio Cards](https://mycuriocards.com/) and [Rare Pepe](https://rarepepewallet.com/) are *not* deeds. They're actually a collection of individual fungible tokens, each of which is tracked by its own smart contract with its own total supply (which may be `1` in extreme cases). +Note: "Limited edition, collectible tokens" like [Curio Cards](https://mycuriocards.com/) and [Rare Pepe](https://rarepepewallet.com/) are *not* distinguishable assets. They're actually a collection of individual fungible tokens, each of which is tracked by its own smart contract with its own total supply (which may be `1` in extreme cases). ## Test Cases @@ -356,7 +360,7 @@ ERC721ExampleDeed, by Nastassia Sachs: https://github.com/nastassiasachs/ERC721E XXXXERC721, by William Entriken: https://github.com/fulldecent/erc721-example -- Deployed on testnet with 1 billion deeds and supporting all lookups with the metadata extension. This demonstrates that scaling is NOT a problem. +- Deployed on testnet with 1 billion assets and supporting all lookups with the metadata extension. This demonstrates that scaling is NOT a problem. ## Copyright From 29cf090a0d35546a3dd334d5ea17b22b40afef1a Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 23 Feb 2018 10:39:15 -0500 Subject: [PATCH 0494/1085] Correct typos in JSON schema --- EIPS/eip-721.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 9fc9fbe5aca26..fdcc0ba3f7364 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -162,15 +162,15 @@ This is the "ERC721 Metadata JSON Schema" referenced above. Learn more about [JS "type": "object", "properties": { "name": { - "type": "string" + "type": "string", "description": "Identifies the thing to which the deed grants ownership", }, "description": { - "type": "string" + "type": "string", "description": "Describes the thing to which the deed grants ownership", }, "image": { - "type": "string" + "type": "string", "description": "A URI pointing to a resource with mime type image/* representing the thing to which the deeds grants ownership. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.", } } From 868a208451d037fa6b3baf6d55fec525827dab44 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 23 Feb 2018 11:03:36 -0500 Subject: [PATCH 0495/1085] Remove my name as interface author, that isn't helping anything --- EIPS/eip-721.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index fdcc0ba3f7364..c59e6df05ff46 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -47,7 +47,6 @@ pragma solidity ^0.4.20; import "./ERC165.sol"; /// @title Required part of ERC-721 Deed Standard -/// @author William Entriken (https://phor.net) /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md /// Note: the ERC-165 (DRAFT) identifier for this interface is 0xb3a99827 interface ERC721 /* is ERC165 */ { @@ -136,7 +135,6 @@ The **metadata extension** is OPTIONAL for ERC-721 implementations (see "caveats ```solidity /// @title Optional metadata extension to ERC-721 Deed Standard -/// @author William Entriken (https://phor.net) /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md /// Note: the ERC-165 (DRAFT) identifier for this interface is 0x2a786f11 interface ERC721Metadata /* is ERC721 */ { @@ -181,7 +179,6 @@ The **enumeration extension** is OPTIONAL for ERC-721 implementations (see "cave ```solidity /// @title Optional enumeration extension to ERC-721 Deed Standard -/// @author William Entriken (https://phor.net) /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md /// Note: the ERC-165 (DRAFT) identifier for this interface is 0x5576ab6a interface ERC721Enumerable /* is ERC721 */ { From 39396a50a205e18db7e7aa5621f6da458c94a9d4 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 23 Feb 2018 11:04:06 -0500 Subject: [PATCH 0496/1085] Fix typo --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index c59e6df05ff46..2eeaf8eead623 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -224,7 +224,7 @@ interface ERC721Enumerable /* is ERC721 */ { The 0.4.20 Solidity interface grammar is not expressive enough to document the ERC-721 specification. A contract which complies with ERC-721 MUST also abide by the following: - [Solidity issue #3412](https://github.com/ethereum/solidity/issues/3412): The above interfaces include explicit mutability guarantees for each function. Mutability guarantees are, in order weak to strong: `payable`, implicit nonpayable, `view`, and `pure`. Your implementation must meet the mutability guarantee in this interface or you may meet a stronger guarantee. For example, a `payable` function in this interface may be implemented as nonpayble (no state mutability specified) in your contract. We expect a later Solidity release will allow your stricter contract to inherit from this interface, but a workaround for version 0.4.20 is that you can edit this interface to add stricter mutability before inheriting from your contract. -- [Solidity issue #3419](https://github.com/ethereum/solidity/issues/3419): A contract that implements `ERC721Metadata` or `ERC721Enumerable` SHALL also implement `ERC721`. sERC-721 implements the requirements of interface [ERC-165](https://github.com/ethereum/EIPs/pull/881). +- [Solidity issue #3419](https://github.com/ethereum/solidity/issues/3419): A contract that implements `ERC721Metadata` or `ERC721Enumerable` SHALL also implement `ERC721`. ERC-721 implements the requirements of interface [ERC-165](https://github.com/ethereum/EIPs/pull/881). - [Solidity issue #2330](https://github.com/ethereum/solidity/issues/2330): If a function is shown in this specification as `external` then a contract will be compliant if it uses `public` visibility. - Solidity issues [#3494](https://github.com/ethereum/solidity/issues/3494), [#3544](https://github.com/ethereum/solidity/issues/3544): Use of `this.*.selector` is marked as a warning by Solidity, a future version of Solidity will not mark this as an error. From 3442342c5a02e9fb061e32ae1848c3195cda2d85 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 23 Feb 2018 11:13:01 -0500 Subject: [PATCH 0497/1085] ERC-165 is now accepted, add strong support for 820 extension of 165 Thanks @eordano for bringing this up --- EIPS/eip-721.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 2eeaf8eead623..c59a5b1f4f37e 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -48,7 +48,7 @@ import "./ERC165.sol"; /// @title Required part of ERC-721 Deed Standard /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md -/// Note: the ERC-165 (DRAFT) identifier for this interface is 0xb3a99827 +/// Note: the ERC-165 identifier for this interface is 0xb3a99827 interface ERC721 /* is ERC165 */ { /// @dev This emits when ownership of any deed changes by any mechanism. /// This event emits when deeds are created (`from` == 0) and destroyed @@ -119,7 +119,7 @@ interface ERC721 /* is ERC165 */ { /// @param _approved True if the operators is approved, false to revoke approval function setApprovalForAll(address _operateor, boolean _approved) payable; - // CONFORMANCE TO ERC-165 (DRAFT) ////////////////////////////////////////// + // CONFORMANCE TO ERC-165 ////////////////////////////////////////////////// /// @notice Query if this implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 @@ -136,7 +136,7 @@ The **metadata extension** is OPTIONAL for ERC-721 implementations (see "caveats ```solidity /// @title Optional metadata extension to ERC-721 Deed Standard /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md -/// Note: the ERC-165 (DRAFT) identifier for this interface is 0x2a786f11 +/// Note: the ERC-165 identifier for this interface is 0x2a786f11 interface ERC721Metadata /* is ERC721 */ { /// @notice A descriptive name for a collection of deeds in this contract function name() external pure returns (string _name); @@ -180,7 +180,7 @@ The **enumeration extension** is OPTIONAL for ERC-721 implementations (see "cave ```solidity /// @title Optional enumeration extension to ERC-721 Deed Standard /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md -/// Note: the ERC-165 (DRAFT) identifier for this interface is 0x5576ab6a +/// Note: the ERC-165 identifier for this interface is 0x5576ab6a interface ERC721Enumerable /* is ERC721 */ { /// @notice Count deeds tracked by this contract /// @return A count of valid deeds tracked by this contract, where each one of @@ -280,9 +280,9 @@ Creating of new deeds and destruction of deeds is not included in the specificat **ERC-165 interface** -This specification includes a function `supportsInterface` which is standardized in [ERC-165](https://github.com/ethereum/EIPs/pull/881) (draft pending acceptance). So any contract MAY query your contract to see if it complies with ERC-721 and the extensions. This creates a dependency, which is a risk. However, ERC-165 is an extremely simple proposal, has implementations deployed in the wild for years and the draft meets all EIP requirements for acceptance, including [the new requirements](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2031.md#10957-decision-process-for-eips) that aren't even documented yet. The lead author of this standard is also the official champion for ERC-165. One EIP reviewer [has "ACK"ed the draft](https://github.com/ethereum/EIPs/pull/881#pullrequestreview-97124296). +This specification includes a function `supportsInterface` which is standardized in [ERC-165](https://github.com/ethereum/EIPs/pull/881). So any contract MAY query your contract to see if it complies with ERC-721 and the extensions. -We chose ERC-165 over competing standard ERC-820 because of maturity. We consider ERC-165 low risk. But ERC-820, as recently as two weeks ago, [discovered a complete show-stopping flaw](https://github.com/ethereum/EIPs/issues/820#issuecomment-362049573). ERC-820 may be a great option, but we deem dependency on that standard an unacceptable risk at this time. +A future EIP may create a global registry of interfaces for contracts. We strongly support such an EIP and it would allow your contract to to implement ERC721Enumerable, ERC721Metadata, or other interfaces by delegating to a separate contract. **Gas and complexity** (regarding the enumeration extension) From 2a56e50ece318e2a3112e00e7914233019bc5e82 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Sun, 25 Feb 2018 23:27:38 -0500 Subject: [PATCH 0498/1085] Allow to query the approved contracts --- EIPS/eip-721.md | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index c59a5b1f4f37e..2b33629055f1c 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -39,33 +39,30 @@ Differences between this standard and EIP-20 are examined below. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt). -The **baseline specification** is REQUIRED for all ERC-721 implementations (see "caveats", below). +**Every ERC-721 compliant contract must implement the `ERC721` and [`ERC165`](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md) interfaces** (subject to "caveats" below): ```solidity pragma solidity ^0.4.20; -import "./ERC165.sol"; - /// @title Required part of ERC-721 Deed Standard /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md -/// Note: the ERC-165 identifier for this interface is 0xb3a99827 +/// Note: the ERC-165 identifier for this interface is 0xTODO_FILL_IN interface ERC721 /* is ERC165 */ { /// @dev This emits when ownership of any deed changes by any mechanism. /// This event emits when deeds are created (`from` == 0) and destroyed /// (`to` == 0). Exception: during contract creation, any number of deeds /// may be created and assigned without emitting Transfer. At the time of - /// any transfer, the "approved deed controller" is implicitly reset to the - /// zero address. + /// any transfer, the approved address for that deed (if any) is reset to none. event Transfer(address indexed _from, address indexed _to, uint256 _deedId); - /// @dev This emits when the "approved deed controller" for a deed is - /// changed or reaffirmed. The zero address indicates there is no approved - /// deed controller. When a Transfer event emits, this also indicates the - /// approved deed controller (if any) is reset to none. + /// @dev This emits when the approved address for a single is changed or + /// reaffirmed. The zero address indicates there is no approved address. + /// When a Transfer event emits, this also indicates that the approved + /// address for that deed (if any) is reset to none. event Approval(address indexed _owner, address indexed _approved, uint256 _deedId); - /// @dev This emits when a third party ("operator") is enabled or disable for - /// an owner. The operator may manage all deeds of the owner. + /// @dev This emits when an operator is enabled or disable for an owner. + /// The operator may manage all deeds of the owner. event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); /// @notice Count all deeds assigned to an owner @@ -104,8 +101,8 @@ interface ERC721 /* is ERC165 */ { /// @param _deedId The deed to transfer function transferFrom(address _from, address _to, uint256 _deedId) external payable; - /// @notice Set or reaffirm the "approved deed controller" for a deed - /// @dev The zero address indicates there is no approved deed controller. + /// @notice Set or reaffirm the approved address for a deed + /// @dev The zero address indicates there is no approved address. /// @dev Throws unless `msg.sender` is the current deed owner, or the /// "delegate operator" of the current deed owner. /// @param _approved The new approved deed controller @@ -117,11 +114,23 @@ interface ERC721 /* is ERC165 */ { /// @dev Emits the ApprovalForAll event /// @param _operator Address to add to the set of authorized operators. /// @param _approved True if the operators is approved, false to revoke approval - function setApprovalForAll(address _operateor, boolean _approved) payable; - - // CONFORMANCE TO ERC-165 ////////////////////////////////////////////////// + function setApprovalForAll(address _operateor, boolean _approved) external; + + /// @notice Get the approved address for a single deed + /// @dev Throws if `_deedId` is not a valid deed + /// @param _deedId The deed to find the approved address for + /// @return The approved address for this deed, or the zero address if there is none + function getApproved(uint256 _deedId) returns (address); + + /// @notice Query if an address is an authorized operator for another address + /// @param _owner The address that owns the deeds + /// @param _operator The address that acts on behalf of the owner + /// @return True if `_operator` is an approved operator for `_owner`, false otherwise + function isApprovedForAll(address _owner, address _operator) returns (bool); +} - /// @notice Query if this implements an interface +interface ERC165 { + /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @dev Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. From 74dadccc858545aa89edaf6ec1cb5857cd261083 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Mon, 26 Feb 2018 00:40:30 -0500 Subject: [PATCH 0499/1085] Add transfer security, give everything else a once-over --- EIPS/eip-721.md | 111 +++++++++++++++++++++++++++++++----------------- 1 file changed, 73 insertions(+), 38 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 2b33629055f1c..e0ee440584fba 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -79,32 +79,49 @@ interface ERC721 /* is ERC165 */ { /// @return The address of the owner of the deed function ownerOf(uint256 _deedId) external view returns (address _owner); - /// @notice Transfers the ownership of a deed -- warning the caller is - /// responsible to confirm that the sender is capable of receiving deeds - /// otherwise the deed may become inaccessible! - /// @dev Throws unless `msg.sender` is the current deed owner, the "delegate - /// operator" of the current deed owner, or the "approved deed controller". - /// Throws if `_to` currently owns the deed. Throws if `_to` is the zero - /// address. + /// @notice Transfer ownership of a deed -- THE CALLER IS RESPONSIBLE + /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING DEEDS OR ELSE + /// THEY MAY BE PERMANENTLY LOST + /// @dev Throws unless `msg.sender` is the current deed owner, an authorized + /// operator, or the approved address for this deed. Throws if `_from` is + /// not the current owner of the deed. Throws if `_to` is the zero address. + /// Throws if `_deedId` is not a valid deed. + /// @param _from The new owner for the deed /// @param _to The new owner for the deed /// @param _deedId The deed to transfer - function transfer(address _to, uint256 _deedId) external payable; + function unsafeTransfer(address _from, address _to, uint256 _deedId) external payable; /// @notice Transfers the ownership of a given deed from one address to /// another address - /// @dev Throws unless `msg.sender` is the current deed owner, the "delegate - /// operator" of the current deed owner, or the "approved deed controller". - /// Throws if `_to` currently owns the deed. Throws if `_to` is the zero - /// address. Throws if the deed is not currently owned by _from. + /// @dev Throws unless `msg.sender` is the current deed owner, an authorized + /// operator, or the approved address for this deed. Throws if `_from` is + /// not the current owner of the deed. Throws if `_to` is the zero address. + /// Throws if `_deedId` is not a valid deed. When transfer is complete, + /// this function also calls `onNFTReceived` on `_to` and throws if the return + /// value is not `keccak256("ERC721_ONNFTRECEIVED")`. /// @param _from The current owner for the deed /// @param _to The new owner for the deed /// @param _deedId The deed to transfer - function transferFrom(address _from, address _to, uint256 _deedId) external payable; + /// @param data Additional data with no specified format, sent in call to `_to` + function transferFrom(address _from, address _to, uint256 _deedId, bytes[] data) external payable; + + /// @notice Transfers the ownership of a given deed from one address to + /// another address + /// @dev Throws unless `msg.sender` is the current deed owner, an authorized + /// operator, or the approved address for this deed. Throws if `_from` is + /// not the current owner of the deed. Throws if `_to` is the zero address. + /// Throws if `_deedId` is not a valid deed. When transfer is complete, + /// this function also calls `onNFTReceived` on `_to` and throws if the return + /// value is not `keccak256("ERC721_ONNFTRECEIVED")`. + /// @param _from The current owner for the deed + /// @param _to The new owner for the deed + /// @param _deedId The deed to transfer + function transferFrom(address _from, address _to, uint256 _deedId) external payable; /// @notice Set or reaffirm the approved address for a deed /// @dev The zero address indicates there is no approved address. - /// @dev Throws unless `msg.sender` is the current deed owner, or the - /// "delegate operator" of the current deed owner. + /// @dev Throws unless `msg.sender` is the current deed owner, or an authorized + /// operator of the current deed owner. /// @param _approved The new approved deed controller /// @param _deedId The deed to approve function approve(address _approved, uint256 _deedId) external payable; @@ -114,7 +131,7 @@ interface ERC721 /* is ERC165 */ { /// @dev Emits the ApprovalForAll event /// @param _operator Address to add to the set of authorized operators. /// @param _approved True if the operators is approved, false to revoke approval - function setApprovalForAll(address _operateor, boolean _approved) external; + function setApprovalForAll(address _operator, bool _approved) external; /// @notice Get the approved address for a single deed /// @dev Throws if `_deedId` is not a valid deed @@ -140,7 +157,25 @@ interface ERC165 { } ``` -The **metadata extension** is OPTIONAL for ERC-721 implementations (see "caveats", below). This allows your contract to be interrogated for its name and for details about the *things*. +A wallet/broker/auction application MUST implement the **wallet interface** if it will accept safe transfers. + +```solidity +interface ERC721TokenReceiver { + /// @notice Handle the receipt of a token + /// @dev The ERC721 smart contract calls this function on the recipient + /// after a `transfer`. This function MAY throw to revert and reject the + /// transfer. This function MUST use 50,000 gas or less. Return of other + /// than the magic value MUST result in the transaction being reverted. + /// Note: the contract address is always the message sender. + /// @param _from The sending address + /// @param _tokenId The deed identifier which was sent + /// @param data Additional data with no specified format + /// @return Always returns `keccak256("ERC721_ONNFTRECEIVED")`, unless throwing + function onNFTReceived(address _from, uint256 _tokenId, bytes data) external returns(bytes4); +} +``` + +The **metadata extension** is OPTIONAL for ERC-721 smart contracts (see "caveats", below). This allows your contract to be interrogated for its name and for details about the *things*. ```solidity /// @title Optional metadata extension to ERC-721 Deed Standard @@ -184,7 +219,7 @@ This is the "ERC721 Metadata JSON Schema" referenced above. Learn more about [JS } ``` -The **enumeration extension** is OPTIONAL for ERC-721 implementations (see "caveats", below). This allows your contract to publish the the full list of deeds and make them discoverable. +The **enumeration extension** is OPTIONAL for ERC-721 smart contracts (see "caveats", below). This allows your contract to publish the the full list of deeds and make them discoverable. ```solidity /// @title Optional enumeration extension to ERC-721 Deed Standard @@ -263,41 +298,39 @@ The choice of uint256 allows a wide variety of applications because UUIDs and sh **Transfer mechanism** -ERC-721 standardizes a single transfer function `transfer` and two levels of indirection: +ERC-721 standardizes a safe transfer function `transferFrom` (overloaded with and without a `bytes` parameter) and an unsafe function `unsafeTransfer`. Transfers may be initiated by: -- The owner can transfer a deed to any address (except the zero address). -- The "approved deed controller" (if any) can transfer just like the owner. -- The "delegate operator" can transfer just like the owner and can assign the "approved deed controller". +- The owner of a deed +- The approved address of a deed +- An authorized operator of the current owner of a deed -This provides a powerful set of tools for broker or auction applications to quickly use a *large* number of deeds. +Additionally, an authorized operator may set the approved address for a deed. This provides a powerful set of tools for wallet, broker or auction applications to quickly use a *large* number of deeds. -The `transfer` documentation only specifies conditions when the transaction MUST throw. Your implementation MAY also throw on calls `transfer`, `approve` and `delegate` in other situations. This allows implementations to achieve interesting results: +The transfer and accept functions documentation only specify conditions when the transaction MUST throw. Your implementation MAY also throw in other situations. This allows implementations to achieve interesting results: - **Disallow transfers if the contract is paused** — prior art, [Crypto Kitties](https://github.com/axiomzen/cryptokitties-bounty/blob/master/contracts/KittyOwnership.sol#L79) - **Blacklist certain address from receiving deeds** — prior art, [Crypto Kitties, (lines 565, 566)](https://etherscan.io/address/0x06012c8cf97bead5deae237070f9587f8e7a266d#code). -- **Require every transaction to use the the approve-transfer workflow** — require `transfer` parameter `_to` to equal `msg.sender` -- **Charge a fee to both parties of a transaction** — require payment when calling `approve` with a non-zero `_approved` if it was previously the zero address, refund payment if calling `approve` with the zero address if it was previously a non-zero address, require payment when calling `transfer`, require `transfer` parameter `_to` to equal `msg.sender`, require `transfer` parameter `_to` to be the approved deed controller -- **Read only deed registry** — always throw from `transfer`, `approve` and `delegate` +- **Disallow unsafe transfers** — `unsafeTransfer` throws unless `_to` equals `msg.sender` or `countOf(_to)` is non-zero (because such cases are safe) +- **Charge a fee to both parties of a transaction** — require payment when calling `approve` with a non-zero `_approved` if it was previously the zero address, refund payment if calling `approve` with the zero address if it was previously a non-zero address, require payment when calling `transfer`, require `transfer` parameter `_to` to equal `msg.sender`, require `transfer` parameter `_to` to be the approved address for the deed +- **Read only deed registry** — always throw from `unsafeTransfer`, `transferFrom`, `approve` and `setApprovalForAll` -Failed transactions will throw, a best practice identified in [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827) and [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol). [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) defined an `allowance` feature, this caused a problem when was called and then later modified to a different amount, as [disucssed on OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/issues/438). In this deed standard, there is no allowance because every deed is unique, the quantity is none or one. Therefore we receive the benefits of ERC-20's original design without problems that have been later discovered. +Failed transactions will throw, a best practice identified in [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827) and [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol). [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) defined an `allowance` feature, this caused a problem when called and then later modified to a different amount, as [disucssed on OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/issues/438). In ERC-721, there is no allowance because every deed is unique, the quantity is none or one. Therefore we receive the benefits of ERC-20's original design without problems that have been later discovered. -Use of the `transfer` function where the caller is the owner of the deed is controversial as discussed in [ERC-233](https://github.com/ethereum/EIPs/issues/223) and [ERC-677](https://github.com/ethereum/EIPs/issues/677). But we take the position that misuse of the `transfer` function is an implementation mistake not a standards mistake. - -Creating of new deeds and destruction of deeds is not included in the specification. Your contract may implement these by other means. Please see the `event` documentation for your responsibilities when creating or destroying deeds. +Creating of new deeds ("minting") and destruction of deeds ("burning") is not included in the specification. Your contract may implement these by other means. Please see the `event` documentation for your responsibilities when creating or destroying deeds. *Alternatives considered: only allow two-step ERC-20 style transaction, require that `transfer` never throw, require all functions to return a boolean indicating the success of the operation.* **ERC-165 interface** -This specification includes a function `supportsInterface` which is standardized in [ERC-165](https://github.com/ethereum/EIPs/pull/881). So any contract MAY query your contract to see if it complies with ERC-721 and the extensions. +We chose Standard Interface Detection [ERC-165](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md) to expose the interfaces that a ERC-721 smart contract supports. -A future EIP may create a global registry of interfaces for contracts. We strongly support such an EIP and it would allow your contract to to implement ERC721Enumerable, ERC721Metadata, or other interfaces by delegating to a separate contract. +A future EIP may create a global registry of interfaces for contracts. We strongly support such an EIP and it would allow your contract to to implement `ERC721Enumerable`, `ERC721Metadata`, or other interfaces by delegating to a separate contract. **Gas and complexity** (regarding the enumeration extension) This specification contemplates implementations that manage a few and *arbitrarily large* numbers of deeds. If your application is able to grow then [avoid using for/while loops in your code](https://github.com/axiomzen/cryptokitties-bounty/issues/4). These indicate your contract may be unable to scale and gas costs will rise over time without bound. -[We have deployed](https://github.com/fulldecent/erc721-example) a contract to test net which instantiates and tracks 340282366920938463463374607431768211456 different deeds (2^128). That's enough to assign every IPV6 address to an Ethereum account owner, or to track ownership of nanobots a few micron in size and in aggregate totalling half the size of Earth. And you can query it from the blockchain. And every function takes less gas than [querying the ENS](https://ens.domains/). +[We have deployed](https://github.com/fulldecent/erc721-example) a contract to test net which instantiates and tracks 340282366920938463463374607431768211456 different deeds (2^128). That's enough to assign every IPV6 address to an Ethereum account owner, or to track ownership of nanobots a few micron in size and in aggregate totalling half the size of Earth. You can query it from the blockchain. And every function takes less gas than [querying the ENS](https://ens.domains/). This illustration makes clear: the Deed Standard scales. @@ -311,13 +344,13 @@ It may be interesting to consider a use case where deeds are not enumerable or d **Metadata choices** (metadata extension) -We have required `name` and `symbol` functions in the metadata extension. Every token EIP and draft we have reviewed ([ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md), [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827)) included these functions. Deeds **are not** tokens, but let's adopt existing conventions when it makes sense! +We have required `name` and `symbol` functions in the metadata extension. Every token EIP and draft we reviewed ([ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md), [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-777](https://github.com/ethereum/EIPs/issues/777), [ERC-827](https://github.com/ethereum/EIPs/issues/827)) included these functions. We remind implementation authors that the empty string is a valid response to `name` and `symbol` if you protest to the usage of this mechanism. We also remind everyone that the official contract for tracking 0xProject tokens (`ZRX`) is [0xe41d2489571d322189246dafa5ebde1f4699f498](https://etherscan.io/address/0xe41d2489571d322189246dafa5ebde1f4699f498). Another contract that advertises a name of `0xProject` and symbol `ZRX` is not the well-known (canonical) contract. How a client may determine which token and deed contracts are well-known is outside the scope of this standard. -A mechanism is provided to associate deeds with URIs. We expect that many implementations will take advantage of this to provide metadata for each deed. The image size recommendation is taken from Instagram, they probably know much about image usability. The URI MAY be mutable (i.e. it changes from time to time). We considered a deed representing ownership of a real-world asset, in this case metadata about such an asset may naturally change. +A mechanism is provided to associate deeds with URIs. We expect that many implementations will take advantage of this to provide metadata for each deed. The image size recommendation is taken from Instagram, they probably know much about image usability. The URI MAY be mutable (i.e. it changes from time to time). We considered a deed representing ownership of a house, in this case metadata about the house (image, occupants, etc.) may naturally change. Metadata is returned as a string value. Currently this is only usable as calling from `web3`, not from other contracts. This is acceptable because we have not considered a use case where an on-blockchain application would query such information. @@ -325,7 +358,7 @@ Metadata is returned as a string value. Currently this is only usable as calling **Community consensus** -A significant amount of discussion occurred on [the original ERC-721](ERC-721 issue), additionally we held a live meeting [on Gitter](https://gitter.im/ethereum/ERCs?at=5a62259b5ade18be3998eec4) that had good representation and [was](https://www.reddit.com/r/ethereum/comments/7r2ena/friday_119_live_discussion_on_erc_nonfungible/) [well](https://gitter.im/ethereum/EIPs?at=5a5f823fb48e8c3566f0a5e7) [advertised](https://github.com/ethereum/eips/issues/721#issuecomment-358369377) in relevant communities. Thank you to the participants: +A significant amount of discussion occurred on [the original ERC-721](ERC-721 issue), additionally we held a live meeting [on Gitter](https://gitter.im/ethereum/ERCs?at=5a62259b5ade18be3998eec4) that had good representation and [was](https://www.reddit.com/r/ethereum/comments/7r2ena/friday_119_live_discussion_on_erc_nonfungible/) [well](https://gitter.im/ethereum/EIPs?at=5a5f823fb48e8c3566f0a5e7) [advertised](https://github.com/ethereum/eips/issues/721#issuecomment-358369377) in relevant communities. Thank you to the participants: - [@ImAllInNow](https://github.com/imallinnow) Rob from DEC Gaming / Presenting Michigan Ethereum Meetup Feb 7 - [@Arachnid](https://github.com/arachnid) Nick Johnson @@ -338,7 +371,7 @@ We have been very inclusive in this process and invite anyone with questions or ## Backwards Compatibility -We have adopted `balanceOf`, `totalSupply`, `name` and `symbol` semantics from the [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) specification. An implementation may also include a function `decimals` that returns `uint8 0` if its intention is to be more compatible with ERC-20 while supporting this standard. However, we find it contrived to require all ERC-721 implementations to support the `decimals` function. +We have adopted `balanceOf`, `totalSupply`, `name` and `symbol` semantics from the [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) specification. An implementation may also include a function `decimals` that returns `uint8(0)` if its goal is to be more compatible with ERC-20 while supporting this standard. However, we find it contrived to require all ERC-721 implementations to support the `decimals` function. Example deeds implementations as of February 2018: @@ -348,6 +381,8 @@ Example deeds implementations as of February 2018: Note: "Limited edition, collectible tokens" like [Curio Cards](https://mycuriocards.com/) and [Rare Pepe](https://rarepepewallet.com/) are *not* deeds. They're actually a collection of individual fungible tokens, each of which is tracked by its own smart contract with its own total supply (which may be `1` in extreme cases). +The `onNFTReceived` function specifically works around old deployed contracts which may inadvertently return 1 (`true`) in certain circumstances even if they don't implement a function. By returning, and checking for, a magic value we are able to distinguish actual affirmative responses versus these `true`s. + ## Test Cases **TO DO** From 223e46c7ce39de62c54bb6a2f9d1e630d3aff079 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Mon, 26 Feb 2018 02:05:54 -0500 Subject: [PATCH 0500/1085] More draft wording changes --- EIPS/eip-721.md | 269 +++++++++++++++++++++++------------------------- 1 file changed, 130 insertions(+), 139 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index e6f64102085d1..19d811df56e5d 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -2,7 +2,7 @@ ``` EIP: -Title: ERC-721 Distinguishable Assets Registry +Title: ERC-721 Non-Fungible Token Standard Author: William Entriken , Dieter Shirley , Jacob Evans , Nastassia Sachs Type: Standard Category ERC @@ -13,25 +13,25 @@ Requires: ERC-165 ## Simple Summary -A standard interface for any Distinguishable Assets Registry ("DAR"). A DAR tracks ownership of a set of assets that are mutually distinguishable. These assets may also be known as non-fungible tokens. +A standard interface for non-fungible tokens, also known as deeds. ## Abstract -Tracking the ownership of physical or digital distinguishable assets on a blockchain has a broad range of applications. We consider use cases of assets being owned and transacted by individuals as well as consignment to third party brokers/wallets/auctioneers ("operators"). +The following standard allows for the implementation of a standard API for NFTs within smart contracts. This standard provides basic functionality to track and transfer NFTs. -The kind of assets to which a DAR expresses ownership are an implementation detail. While writing this standard we considered a diverse univerise of assets, and we know you will dream up many more: +We considered use cases of NFTs being owned and transacted by individuals as well as consignment to third party brokers/wallets/auctioneers ("operators"). NFTs can represent ownership over digital or physical assets. We considered a diverse universe of assets, and we know you will dream up many more: - Physical property — houses, unique artwork - Virtual collectables — unique pictures of kittens, collectable cards - "Negative value" assets — loans, burdens and other responsibilities -In general, all houses are distinct and no two kittens are alike. Therefore you must track each asset separately; it is insufficient to simply count the assets you own. +In general, all houses are distinct and no two kittens are alike. NFTs are *distinguishable* and you must track the ownership of each one separately. ## Motivation -A standard interface allows wallet/broker/auction applications to work with any DAR on Ethereum. We provide for simple DAR contracts as well as contracts that track an *arbitrarily large* number of assets. Additional applications are discussed below. +A standard interface allows wallet/broker/auction applications to work with any NFT on Ethereum. We provide for simple ERC-721 smart contracts as well as contracts that track an *arbitrarily large* number of NFTs. Additional applications are discussed below. -This standard is inspired by [the ERC-20 token standard](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) and builds on two years of experience since EIP-20 was created. EIP-20 is insufficient for tracking asset ownership because each asset is distinct (non-fungible) whereas each of a quantity of tokens is identical (fungible). +This standard is inspired by [the ERC-20 token standard](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) and builds on two years of experience since EIP-20 was created. EIP-20 is insufficient for tracking NFTs because each asset is distinct (non-fungible) whereas each of a quantity of tokens is identical (fungible). Differences between this standard and EIP-20 are examined below. @@ -44,87 +44,85 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S ```solidity pragma solidity ^0.4.20; -/// @title Required part of ERC-721 Deed Standard +/// @title ERC-721 Non-Fungible Token Standard /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md /// Note: the ERC-165 identifier for this interface is 0xTODO_FILL_IN interface ERC721 /* is ERC165 */ { - /// @dev This emits when ownership of any asset changes by any mechanism. - /// This event emits when assets are created (`from` == 0) and destroyed - /// (`to` == 0). Exception: during contract creation, any number of assets + /// @dev This emits when ownership of any NFT changes by any mechanism. + /// This event emits when NFTs are created (`from` == 0) and destroyed + /// (`to` == 0). Exception: during contract creation, any number of NFTs /// may be created and assigned without emitting Transfer. At the time of - /// any transfer, the approved address for that asset (if any) is reset to none. - event Transfer(address indexed _from, address indexed _to, uint256 _assetId); + /// any transfer, the approved address for that NFT (if any) is reset to none. + event Transfer(address indexed _from, address indexed _to, uint256 _tokenId); - /// @dev This emits when the approved address for a single is changed or + /// @dev This emits when the approved address for an NFT is changed or /// reaffirmed. The zero address indicates there is no approved address. /// When a Transfer event emits, this also indicates that the approved - /// address for that asset (if any) is reset to none. - event Approval(address indexed _owner, address indexed _approved, uint256 _assetId); + /// address for that NFT (if any) is reset to none. + event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId); - /// @dev This emits when an operator is enabled or disable for an owner. - /// The operator may manage all assets of the owner. + /// @dev This emits when an operator is enabled or disabled for an owner. + /// The operator can manage all NFTs of the owner. event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); - /// @notice Count all assets assigned to an owner - /// @dev Assets assigned to zero address are considered invalid, and this + /// @notice Count all NFTs assigned to an owner + /// @dev NFTs assigned to the zero address are considered invalid, and this /// function throws for queries about the zero address. /// @param _owner An address for whom to query the balance - /// @return The number of assets owned by `_owner`, possibly zero - function balanceOf(address _owner) external view returns (uint256 _balance); + /// @return The number of NFTs owned by `_owner`, possibly zero + function balanceOf(address _owner) external view returns (uint256); - /// @notice Find the owner of an asset - /// @param _assetId The identifier for an asset we are inspecting - /// @dev Assets assigned to zero address are considered invalid, and queries + /// @notice Find the owner of an NFT + /// @param _tokenId The identifier for an NFT + /// @dev NFTs assigned to zero address are considered invalid, and queries /// about them do throw. - /// @return The address of the owner of the asset - function ownerOf(uint256 _assetId) external view returns (address _owner); + /// @return The address of the owner of the NFT + function ownerOf(uint256 _tokenId) external view returns (address); - /// @notice Transfer ownership of a asset -- THE CALLER IS RESPONSIBLE - /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING DEEDS OR ELSE + /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE + /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE /// THEY MAY BE PERMANENTLY LOST - /// @dev Throws unless `msg.sender` is the current asset owner, an authorized - /// operator, or the approved address for this asset. Throws if `_from` is - /// not the current owner of the asset. Throws if `_to` is the zero address. - /// Throws if `_deedId` is not a valid asset. - /// @param _from The new owner for the asset - /// @param _to The new owner for the asset - /// @param _assetId The deed to transfer - function unsafeTransfer(address _from, address _to, uint256 _assetId) external payable; - - /// @notice Transfers the ownership of a given asset from one address to - /// another address - /// @dev Throws unless `msg.sender` is the current asset owner, an authorized - /// operator, or the approved address for this asset. Throws if `_from` is - /// not the current owner of the asset. Throws if `_to` is the zero address. - /// Throws if `_assetId` is not a valid asset. When transfer is complete, - /// this function also calls `onNFTReceived` on `_to` and throws if the return - /// value is not `keccak256("ERC721_ONNFTRECEIVED")`. - /// @param _from The current owner for the asset - /// @param _to The new owner for the asset - /// @param _assetId The deed to transfer + /// @dev Throws unless `msg.sender` is the current owner, an authorized + /// operator, or the approved address for this NFT. Throws if `_from` is + /// not the current owner. Throws if `_to` is the zero address. Throws if + /// `_tokenId` is not a valid NFT. + /// @param _from The current owner of the NFT + /// @param _to The new owner + /// @param _tokenId The NFT to transfer + function unsafeTransfer(address _from, address _to, uint256 _tokenId) external payable; + + /// @notice Transfers the ownership of an NFT from one address to another address + /// @dev Throws unless `msg.sender` is the current owner, an authorized + /// operator, or the approved address for this NFT. Throws if `_from` is + /// not the current owner. Throws if `_to` is the zero address. Throws if + /// `_tokenId` is not a valid NFT. When transfer is complete, this function also + /// calls `onNFTReceived` on `_to` and throws if the return value is not + /// `keccak256("ERC721_ONNFTRECEIVED")`. + /// @param _from The current owner of the NFT + /// @param _to The new owner + /// @param _tokenId The NFT to transfer /// @param data Additional data with no specified format, sent in call to `_to` - function transferFrom(address _from, address _to, uint256 _assetId, bytes[] data) external payable; + function transferFrom(address _from, address _to, uint256 _tokenId, bytes[] data) external payable; - /// @notice Transfers the ownership of a given asset from one address to - /// another address - /// @dev Throws unless `msg.sender` is the current asset owner, an authorized - /// operator, or the approved address for this asset. Throws if `_from` is - /// not the current owner of the asset. Throws if `_to` is the zero address. - /// Throws if `_assetId` is not a valid asset. When transfer is complete, - /// this function also calls `onNFTReceived` on `_to` and throws if the return - /// value is not `keccak256("ERC721_ONNFTRECEIVED")`. - /// @param _from The current owner for the asset - /// @param _to The new owner for the asset - /// @param _assetId The asset to transfer - function transferFrom(address _from, address _to, uint256 _assetId) external payable; - - /// @notice Set or reaffirm the approved address for a asset + /// @notice Transfers the ownership of an NFT from one address to another address + /// @dev Throws unless `msg.sender` is the current owner, an authorized + /// operator, or the approved address for this NFT. Throws if `_from` is + /// not the current owner. Throws if `_to` is the zero address. Throws if + /// `_tokenId` is not a valid NFT. When transfer is complete, this function also + /// calls `onNFTReceived` on `_to` and throws if the return value is not + /// `keccak256("ERC721_ONNFTRECEIVED")`. + /// @param _from The current owner of the NFT + /// @param _to The new owner + /// @param _tokenId The NFT to transfer + function transferFrom(address _from, address _to, uint256 _tokenId) external payable; + + /// @notice Set or reaffirm the approved address for an NFT /// @dev The zero address indicates there is no approved address. - /// @dev Throws unless `msg.sender` is the current deed owner, or an authorized - /// operator of the current asset owner. - /// @param _approved The new approved deed controller - /// @param _assetId The deed to approve - function approve(address _approved, uint256 _assetId) external payable; + /// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized + /// operator of the current owner. + /// @param _approved The new approved NFT controller + /// @param _tokenId The NFT to approve + function approve(address _approved, uint256 _tokenId) external payable; /// @notice Enable or disable approval for a third party ("operator") to manage /// all your asset. @@ -133,14 +131,14 @@ interface ERC721 /* is ERC165 */ { /// @param _approved True if the operators is approved, false to revoke approval function setApprovalForAll(address _operator, bool _approved) external; - /// @notice Get the approved address for a single deed - /// @dev Throws if `_deedId` is not a valid deed - /// @param _deedId The deed to find the approved address for - /// @return The approved address for this deed, or the zero address if there is none - function getApproved(uint256 _deedId) returns (address); + /// @notice Get the approved address for a single NFT + /// @dev Throws if `_tokenId` is not a valid NFT + /// @param _tokenId The NFT to find the approved address for + /// @return The approved address for this NFT, or the zero address if there is none + function getApproved(uint256 _tokenId) returns (address); /// @notice Query if an address is an authorized operator for another address - /// @param _owner The address that owns the deeds + /// @param _owner The address that owns the NFTs /// @param _operator The address that acts on behalf of the owner /// @return True if `_operator` is an approved operator for `_owner`, false otherwise function isApprovedForAll(address _owner, address _operator) returns (bool); @@ -161,38 +159,38 @@ A wallet/broker/auction application MUST implement the **wallet interface** if i ```solidity interface ERC721TokenReceiver { - /// @notice Handle the receipt of a token + /// @notice Handle the receipt of an NFT /// @dev The ERC721 smart contract calls this function on the recipient /// after a `transfer`. This function MAY throw to revert and reject the /// transfer. This function MUST use 50,000 gas or less. Return of other /// than the magic value MUST result in the transaction being reverted. /// Note: the contract address is always the message sender. /// @param _from The sending address - /// @param _tokenId The deed identifier which was sent + /// @param _tokenId The NFT identifier which is being transfered /// @param data Additional data with no specified format /// @return Always returns `keccak256("ERC721_ONNFTRECEIVED")`, unless throwing function onNFTReceived(address _from, uint256 _tokenId, bytes data) external returns(bytes4); } ``` -The **metadata extension** is OPTIONAL for ERC-721 smart contracts (see "caveats", below). This allows your contract to be interrogated for its name and for details about the *things*. +The **metadata extension** is OPTIONAL for ERC-721 smart contracts (see "caveats", below). This allows your smart contract to be interrogated for its name and for details about the assets which your NFTs represent. ```solidity -/// @title Optional metadata extension to ERC-721 Distinguishable Assets Registry +/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md -/// Note: the ERC-165 identifier for this interface is 0x2a786f11 +/// Note: the ERC-165 identifier for this interface is 0xTODO_ADD_THIS interface ERC721Metadata /* is ERC721 */ { - /// @notice A descriptive name for a collection of assets in this contract + /// @notice A descriptive name for a collection of NFTs in this contract function name() external pure returns (string _name); - /// @notice An abbreviated name for assets in this contract + /// @notice An abbreviated name for NFTs in this contract function symbol() external pure returns (string _symbol); /// @notice A distinct Uniform Resource Identifier (URI) for a given asset. - /// @dev Throws if `_assetId` is not a valid asset. URIs are defined in RFC + /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC /// 3986. The URI may point to a JSON file that conforms to the "ERC721 /// Metadata JSON Schema". - function assetURI(uint256 _assetId) external view returns (string _assetURI); + function tokenURI(uint256 _tokenId) external view returns (string); } ``` @@ -205,72 +203,67 @@ This is the "ERC721 Metadata JSON Schema" referenced above. Learn more about [JS "properties": { "name": { "type": "string", - "description": "Identifies the asset to which the DAR grants ownership", + "description": "Identifies the asset to which this NFT represents", }, "description": { "type": "string", - "description": "Describes the asset to which the DAR grants ownership", + "description": "Describes the asset to which this NFT represents", }, "image": { "type": "string", - "description": "A URI pointing to a resource with mime type image/* representing the asset to which the DAR grants ownership. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.", + "description": "A URI pointing to a resource with mime type image/* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.", } } } ``` -The **enumeration extension** is OPTIONAL for ERC-721 smart contracts (see "caveats", below). This allows your contract to publish the the full list of assets and make them discoverable. +The **enumeration extension** is OPTIONAL for ERC-721 smart contracts (see "caveats", below). This allows your contract to publish its full list of NFTs and make them discoverable. ```solidity -/// @title Optional enumeration extension to ERC-721 Distinguishable Assets Registry +/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md -/// Note: the ERC-165 identifier for this interface is 0x5576ab6a +/// Note: the ERC-165 identifier for this interface is 0xTODO_ADD_THIS interface ERC721Enumerable /* is ERC721 */ { - /// @notice Count assets tracked by this contract - /// @return A count of valid assets tracked by this contract, where each one of + /// @notice Count NFTs tracked by this contract + /// @return A count of valid NFTs tracked by this contract, where each one of /// them has an assigned and queryable owner not equal to the zero address - function totalSupply() external view returns (uint256 _count); + function totalSupply() external view returns (uint256); - /// @notice Enumerate active assets + /// @notice Enumerate valid NFTs /// @dev Throws if `_index` >= `totalSupply()`. /// @param _index A counter less than `totalSupply()` - /// @return The identifier for the `_index`th asset, (sort order not - /// specified) - function assetByIndex(uint256 _index) external view returns (uint256 _assetId); + /// @return The token identifier for the `_index`th NFT, + /// (sort order not specified) + function tokenByIndex(uint256 _index) external view returns (uint256); - /// @notice Count of owners which own at least one asset - /// @return A count of the number of owners which own assets - function countOfOwners() external view returns (uint256 _count); + /// @notice Count of owners which own at least one NFT + /// @return A count of the number of owners which own NFTs + function countOfOwners() external view returns (uint256); - /// @notice Enumerate owners + /// @notice Enumerate owners which own at least one NFT /// @dev Throws if `_index` >= `countOfOwners()` /// @param _index A counter less than `countOfOwners()` /// @return The address of the `_index`th owner (sort order not specified) - function ownerByIndex(uint256 _index) external view returns (address _owner); - - /// @notice Count assets of an owner - /// @param _owner The address to check - /// @return The number of valid assets owned by this owner - function countOfAssetsByOwner(address _owner) external view returns (uint256 _count); - - /// @notice Enumerate assets assigned to an owner - /// @dev Throws if `_index` >= `countOfAssetsByOwner(_owner)` or if - /// `_owner` is the zero address, representing invalid assets. - /// @param _owner An address where we are interested in assets owned by them - /// @param _index A counter less than `countOfAssetsByOwner(_owner)` - /// @return The identifier for the `_index`th asset assigned to `_owner`, + function ownerByIndex(uint256 _index) external view returns (address); + + /// @notice Enumerate NFTs assigned to an owner + /// @dev Throws if `_index` >= `balanceOf(_owner)` or if + /// `_owner` is the zero address, representing invalid NFTs. + /// @param _owner An address where we are interested in NFTs owned by them + /// @param _index A counter less than `balanceOf(_owner)` + /// @return The token identifier for the `_index`th NFT assigned to `_owner`, /// (sort order not specified) - function assetOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256 _assetId); + function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256 _tokenId); } ``` ### Caveats -The 0.4.20 Solidity interface grammar is not expressive enough to document the ERC-721 specification. A contract which complies with ERC-721 MUST also abide by the following: +The 0.4.20 Solidity interface grammar is not expressive enough to document the ERC-721 standard. A contract which complies with ERC-721 MUST also abide by the following: -- [Solidity issue #3412](https://github.com/ethereum/solidity/issues/3412): The above interfaces include explicit mutability guarantees for each function. Mutability guarantees are, in order weak to strong: `payable`, implicit nonpayable, `view`, and `pure`. Your implementation must meet the mutability guarantee in this interface or you may meet a stronger guarantee. For example, a `payable` function in this interface may be implemented as nonpayble (no state mutability specified) in your contract. We expect a later Solidity release will allow your stricter contract to inherit from this interface, but a workaround for version 0.4.20 is that you can edit this interface to add stricter mutability before inheriting from your contract. +- [Solidity issue #3412](https://github.com/ethereum/solidity/issues/3412): The above interfaces include explicit mutability guarantees for each function. Mutability guarantees are, in order weak to strong: `payable`, implicit nonpayable, `view`, and `pure`. Your implementation MUST meet the mutability guarantee in this interface and you MAY meet a stronger guarantee. For example, a `payable` function in this interface may be implemented as nonpayble (no state mutability specified) in your contract. We expect a later Solidity release will allow your stricter contract to inherit from this interface, but a workaround for version 0.4.20 is that you can edit this interface to add stricter mutability before inheriting from your contract. - [Solidity issue #3419](https://github.com/ethereum/solidity/issues/3419): A contract that implements `ERC721Metadata` or `ERC721Enumerable` SHALL also implement `ERC721`. ERC-721 implements the requirements of interface [ERC-165](https://github.com/ethereum/EIPs/pull/881). -- [Solidity issue #2330](https://github.com/ethereum/solidity/issues/2330): If a function is shown in this specification as `external` then a contract will be compliant if it uses `public` visibility. +- [Solidity issue #2330](https://github.com/ethereum/solidity/issues/2330): If a function is shown in this specification as `external` then a contract will be compliant if it uses `public` visibility. As a workaround for version 0.4.20, you can edit this interface to switch to `public` before inheriting from your contract. - Solidity issues [#3494](https://github.com/ethereum/solidity/issues/3494), [#3544](https://github.com/ethereum/solidity/issues/3544): Use of `this.*.selector` is marked as a warning by Solidity, a future version of Solidity will not mark this as an error. *If a newer version of Solidity allows the caveats to be expressed in code, then this EIP MAY be updated and the caveats removed, such will be equivalent to the original specification.* @@ -279,29 +272,27 @@ The 0.4.20 Solidity interface grammar is not expressive enough to document the E There are many proposed uses of Ethereum smart contracts that depend on tracking distinguishable assets. Examples of existing or planned NFTs are LAND in [Decentraland](https://decentraland.org/), the eponymous punks in [CryptoPunks](https://www.larvalabs.com/cryptopunks), and in-game items using systems like [Dmarket](https://www.dmarket.io/) or [EnjinCoin](https://enjincoin.io/). Future uses include tracking real-world assets, like real-estate (as envisioned by companies like [Ubitquity](https://www.ubitquity.io/) or [Propy](https://tokensale.propy.com/)). It is critical in each of these cases that these items are not "lumped together" as numbers in a ledger, but instead, each asset must have its ownership individually and atomically tracked. Regardless of the nature of these assets, the ecosystem will be stronger if we have a standardized interface that allows for cross-functional asset management and sales platforms. -**"Asset" word choice** +**"NFT" word choice** -We chose specifically to avoid the word "token" because it has a well known, and different, meaning in the Ethereum ecosystem, specifically ERC-20 tokens. +"NFT" was satisfactory to nearly everyone surveyed and is widely applicable to a broad universe of distinguishable digital assets. We recongize that "deed" is very descriptive for certain applications of this standard (notably, physical property). -The word "asset" well describes all the use cases we envisioned above. +*Alternatives considered: distinguishable asset, title, token, asset, equity, ticket* -*Alternatives considered: non-fungible token, title, token, asset, equity, ticket, deed* +**NFT identifiers** -**Asset identifiers** +Every NFT is identified by a unique `uint265` ID inside the ERC-721 smart contract. This identifing number SHALL NOT change for the life of the contract. The pair `(contract address, uint265 tokenId)` will then be a globally unique and fully-qualified identifier for a specific asset on an Ethereum chain. While some ERC-721 smart contracts may find it convenient to start with ID 0 and simply increment by one for each new NFT, callers SHALL NOT assume that ID numbers have any specific pattern to them, and MUST treat the ID as a "black box". Also note that a NFTs MAY become invalid (be destroyed). Please see the enumerations functions for a supported enumeration interface. -The basis of this standard is that every asset is identified by a unique 256-bit unsigned integer within its DAR. This ID number SHALL NOT change for the life of the contract. The pair `(contract address, uint265 assetId)` will then be a globally unique and fully-qualified identifier for a specific asset within the Ethereum ecosystem. While some contracts may find it convenient to start with ID 0 and simply increment by one for each new asset, callers SHALL NOT assume that ID numbers have any specific pattern to them, and MUST treat the ID as a "black box". Also note that a assets MAY become invalid (be destroyed). Please see the enumerations functions for a supported enumeration interface. - -The choice of uint256 allows a wide variety of applications because UUIDs and sha3 hashes are directly convertible to uint256. +The choice of `uint256` allows a wide variety of applications because UUIDs and sha3 hashes are directly convertible to `uint256`. **Transfer mechanism** ERC-721 standardizes a safe transfer function `transferFrom` (overloaded with and without a `bytes` parameter) and an unsafe function `unsafeTransfer`. Transfers may be initiated by: -- The owner of an asset -- The approved address of an assec -- An authorized operator of the current owner of an asset +- The owner of an NFT +- The approved address of an NFT +- An authorized operator of the current owner of an NFT -Additionally, an authorized operator may set the approved address for an asset. This provides a powerful set of tools for wallet, broker or auction applications to quickly use a *large* number of deeds. +Additionally, an authorized operator may set the approved address for an NFT. This provides a powerful set of tools for wallet, broker and auction applications to quickly use a *large* number of NFTs. The transfer and accept functions documentation only specify conditions when the transaction MUST throw. Your implementation MAY also throw in other situations. This allows implementations to achieve interesting results: @@ -313,7 +304,7 @@ The transfer and accept functions documentation only specify conditions when the Failed transactions will throw, a best practice identified in [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827) and [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol). [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) defined an `allowance` feature, this caused a problem when called and then later modified to a different amount, as [disucssed on OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/issues/438). In ERC-721, there is no allowance because every deed is unique, the quantity is none or one. Therefore we receive the benefits of ERC-20's original design without problems that have been later discovered. -Creating of new deeds ("minting") and destruction of deeds ("burning") is not included in the specification. Your contract may implement these by other means. Please see the `event` documentation for your responsibilities when creating or destroying deeds. +Creating of NFTs ("minting") and destruction NFTs ("burning") is not included in the specification. Your contract may implement these by other means. Please see the `event` documentation for your responsibilities when creating or destroying NFTs. *Alternatives considered: only allow two-step ERC-20 style transaction, require that `transfer` never throw, require all functions to return a boolean indicating the success of the operation.* @@ -321,23 +312,23 @@ Creating of new deeds ("minting") and destruction of deeds ("burning") is not in We chose Standard Interface Detection [ERC-165](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md) to expose the interfaces that a ERC-721 smart contract supports. -A future EIP may create a global registry of interfaces for contracts. We strongly support such an EIP and it would allow your contract to to implement `ERC721Enumerable`, `ERC721Metadata`, or other interfaces by delegating to a separate contract. +A future EIP may create a global registry of interfaces for contracts. We strongly support such an EIP and it would allow your ERC-721 implementation to implement `ERC721Enumerable`, `ERC721Metadata`, or other interfaces by delegating to a separate contract. **Gas and complexity** (regarding the enumeration extension) -This specification contemplates implementations that manage a few and *arbitrarily large* numbers of assets. If your application is able to grow then [avoid using for/while loops in your code](https://github.com/axiomzen/cryptokitties-bounty/issues/4). These indicate your contract may be unable to scale and gas costs will rise over time without bound. +This specification contemplates implementations that manage a few and *arbitrarily large* numbers of NFTs. If your application is able to grow then [avoid using for/while loops in your code](https://github.com/axiomzen/cryptokitties-bounty/issues/4). These indicate your contract may be unable to scale and gas costs will rise over time without bound. -[We have deployed](https://github.com/fulldecent/erc721-example) a contract to test net which instantiates and tracks 340282366920938463463374607431768211456 different deeds (2^128). That's enough to assign every IPV6 address to an Ethereum account owner, or to track ownership of nanobots a few micron in size and in aggregate totalling half the size of Earth. You can query it from the blockchain. And every function takes less gas than [querying the ENS](https://ens.domains/). +[We have deployed](https://github.com/fulldecent/erc721-example) a contract to Testnet which instantiates and tracks 340282366920938463463374607431768211456 different deeds (2^128). That's enough to assign every IPV6 address to an Ethereum account owner, or to track ownership of nanobots a few micron in size and in aggregate totalling half the size of Earth. You can query it from the blockchain. And every function takes less gas than [querying the ENS](https://ens.domains/). -This illustration makes clear: the Distinguishable Assets Registry standard scales. +This illustration makes clear: the ERC-721 standard scales. *Alternatives considered: remove the asset enumeration function if it requries a for-loop, return a Soldity array type from enumeration functions.* **Privacy** -Wallets/brokers/auctioneers identified in the motivation section have a strong need to identify which assets an owner owns. +Wallets/brokers/auctioneers identified in the motivation section have a strong need to identify which NFTs an owner owns. -It may be interesting to consider a use case where assets are not enumerable or assets are not enumerable by owner, such as a private registry of property ownership, or a partially-private registry. However, privacy cannot be attained because an attacker can simply (!) call `ownerOf` for every possible `assetId`. +It may be interesting to consider a use case where NFTs are not enumerable, such as a private registry of property ownership, or a partially-private registry. However, privacy cannot be attained because an attacker can simply (!) call `ownerOf` for every possible `tokenId`. **Metadata choices** (metadata extension) @@ -345,9 +336,9 @@ We have required `name` and `symbol` functions in the metadata extension. Every We remind implementation authors that the empty string is a valid response to `name` and `symbol` if you protest to the usage of this mechanism. We also remind everyone that the official contract for tracking 0xProject tokens (`ZRX`) is [0xe41d2489571d322189246dafa5ebde1f4699f498](https://etherscan.io/address/0xe41d2489571d322189246dafa5ebde1f4699f498). Another contract that advertises a name of `0xProject` and symbol `ZRX` is not the well-known (canonical) contract. -How a client may determine which DARs are well-known is outside the scope of this standard. +How a client may determine which ERC-721 smart contracts are well-known is outside the scope of this standard. -A mechanism is provided to associate deeds with URIs. We expect that many implementations will take advantage of this to provide metadata for each deed. The image size recommendation is taken from Instagram, they probably know much about image usability. The URI MAY be mutable (i.e. it changes from time to time). We considered a deed representing ownership of a house, in this case metadata about the house (image, occupants, etc.) may naturally change. +A mechanism is provided to associate NFTs with URIs. We expect that many implementations will take advantage of this to provide metadata for each NFT. The image size recommendation is taken from Instagram, they probably know much about image usability. The URI MAY be mutable (i.e. it changes from time to time). We considered an NFT representing ownership of a house, in this case metadata about the house (image, occupants, etc.) can naturally change. Metadata is returned as a string value. Currently this is only usable as calling from `web3`, not from other contracts. This is acceptable because we have not considered a use case where an on-blockchain application would query such information. From 7e8345574ef2a18977054e0389ddb63c500e4a13 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Mon, 26 Feb 2018 11:13:12 -0500 Subject: [PATCH 0501/1085] Link to mentioned Solidity bug --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index e0ee440584fba..b87fe8727bea1 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -381,7 +381,7 @@ Example deeds implementations as of February 2018: Note: "Limited edition, collectible tokens" like [Curio Cards](https://mycuriocards.com/) and [Rare Pepe](https://rarepepewallet.com/) are *not* deeds. They're actually a collection of individual fungible tokens, each of which is tracked by its own smart contract with its own total supply (which may be `1` in extreme cases). -The `onNFTReceived` function specifically works around old deployed contracts which may inadvertently return 1 (`true`) in certain circumstances even if they don't implement a function. By returning, and checking for, a magic value we are able to distinguish actual affirmative responses versus these `true`s. +The `onNFTReceived` function specifically works around old deployed contracts [which may inadvertently return 1 (`true`)](http://solidity.readthedocs.io/en/develop/bugs.html#DelegateCallReturnValue) in certain circumstances even if they don't implement a function. By returning, and checking for, a magic value we are able to distinguish actual affirmative responses versus these `true`s. ## Test Cases From e847ffee78f029de514210c081c3c127209073c8 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Mon, 26 Feb 2018 22:10:41 -0500 Subject: [PATCH 0502/1085] Use a better magic value, clarify callback, thanks @abandeali1 --- EIPS/eip-721.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 8183da8ef516b..3ad491bca3859 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -95,9 +95,10 @@ interface ERC721 /* is ERC165 */ { /// @dev Throws unless `msg.sender` is the current owner, an authorized /// operator, or the approved address for this NFT. Throws if `_from` is /// not the current owner. Throws if `_to` is the zero address. Throws if - /// `_tokenId` is not a valid NFT. When transfer is complete, this function also - /// calls `onNFTReceived` on `_to` and throws if the return value is not - /// `keccak256("ERC721_ONNFTRECEIVED")`. + /// `_tokenId` is not a valid NFT. When transfer is complete, this function + /// checks if `_to` is a smart contract (code size > 0). If so, it calls + /// `onNFTReceived` on `_to` and throws if the return value is not + /// `bytes4(keccak256("onNFTReceived(address,uint256,bytes)"))`. /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer @@ -105,12 +106,8 @@ interface ERC721 /* is ERC165 */ { function transferFrom(address _from, address _to, uint256 _tokenId, bytes[] data) external payable; /// @notice Transfers the ownership of an NFT from one address to another address - /// @dev Throws unless `msg.sender` is the current owner, an authorized - /// operator, or the approved address for this NFT. Throws if `_from` is - /// not the current owner. Throws if `_to` is the zero address. Throws if - /// `_tokenId` is not a valid NFT. When transfer is complete, this function also - /// calls `onNFTReceived` on `_to` and throws if the return value is not - /// `keccak256("ERC721_ONNFTRECEIVED")`. + /// @dev This works identically to the other function with an extra data parameter, + /// except this function just sets data to [] /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer From 89d01622315f34340339e6a098c70a17fa856893 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 28 Feb 2018 12:18:48 -0500 Subject: [PATCH 0503/1085] Bytes, not bytes[], thanks @sz-piotr --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 3ad491bca3859..dccf8ba4b1fcd 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -103,7 +103,7 @@ interface ERC721 /* is ERC165 */ { /// @param _to The new owner /// @param _tokenId The NFT to transfer /// @param data Additional data with no specified format, sent in call to `_to` - function transferFrom(address _from, address _to, uint256 _tokenId, bytes[] data) external payable; + function transferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable; /// @notice Transfers the ownership of an NFT from one address to another address /// @dev This works identically to the other function with an extra data parameter, From 2bddd126def7c046e1e62408dc2b51bdd9e57f0f Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 28 Feb 2018 14:29:27 -0500 Subject: [PATCH 0504/1085] Update transfer naming and interface IDs --- EIPS/eip-721.md | 78 ++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 43 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index dccf8ba4b1fcd..1c34311f5b108 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -46,8 +46,8 @@ pragma solidity ^0.4.20; /// @title ERC-721 Non-Fungible Token Standard /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md -/// Note: the ERC-165 identifier for this interface is 0xTODO_FILL_IN -interface ERC721 /* is ERC165 */ { +/// Note: the ERC-165 identifier for this interface is 0x6466353c +interface ERC721 /* is ERC165 */ { /// @dev This emits when ownership of any NFT changes by any mechanism. /// This event emits when NFTs are created (`from` == 0) and destroyed /// (`to` == 0). Exception: during contract creation, any number of NFTs @@ -79,31 +79,19 @@ interface ERC721 /* is ERC165 */ { /// @return The address of the owner of the NFT function ownerOf(uint256 _tokenId) external view returns (address); - /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE - /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE - /// THEY MAY BE PERMANENTLY LOST - /// @dev Throws unless `msg.sender` is the current owner, an authorized - /// operator, or the approved address for this NFT. Throws if `_from` is - /// not the current owner. Throws if `_to` is the zero address. Throws if - /// `_tokenId` is not a valid NFT. - /// @param _from The current owner of the NFT - /// @param _to The new owner - /// @param _tokenId The NFT to transfer - function unsafeTransfer(address _from, address _to, uint256 _tokenId) external payable; - /// @notice Transfers the ownership of an NFT from one address to another address /// @dev Throws unless `msg.sender` is the current owner, an authorized /// operator, or the approved address for this NFT. Throws if `_from` is /// not the current owner. Throws if `_to` is the zero address. Throws if /// `_tokenId` is not a valid NFT. When transfer is complete, this function /// checks if `_to` is a smart contract (code size > 0). If so, it calls - /// `onNFTReceived` on `_to` and throws if the return value is not - /// `bytes4(keccak256("onNFTReceived(address,uint256,bytes)"))`. + /// `onERC721Received` on `_to` and throws if the return value is not + /// `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`. /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer /// @param data Additional data with no specified format, sent in call to `_to` - function transferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable; + function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable; /// @notice Transfers the ownership of an NFT from one address to another address /// @dev This works identically to the other function with an extra data parameter, @@ -111,6 +99,18 @@ interface ERC721 /* is ERC165 */ { /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer + function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; + + /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE + /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE + /// THEY MAY BE PERMANENTLY LOST + /// @dev Throws unless `msg.sender` is the current owner, an authorized + /// operator, or the approved address for this NFT. Throws if `_from` is + /// not the current owner. Throws if `_to` is the zero address. Throws if + /// `_tokenId` is not a valid NFT. + /// @param _from The current owner of the NFT + /// @param _to The new owner + /// @param _tokenId The NFT to transfer function transferFrom(address _from, address _to, uint256 _tokenId) external payable; /// @notice Set or reaffirm the approved address for an NFT @@ -132,13 +132,13 @@ interface ERC721 /* is ERC165 */ { /// @dev Throws if `_tokenId` is not a valid NFT /// @param _tokenId The NFT to find the approved address for /// @return The approved address for this NFT, or the zero address if there is none - function getApproved(uint256 _tokenId) returns (address); + function getApproved(uint256 _tokenId) external returns (address); /// @notice Query if an address is an authorized operator for another address /// @param _owner The address that owns the NFTs /// @param _operator The address that acts on behalf of the owner /// @return True if `_operator` is an approved operator for `_owner`, false otherwise - function isApprovedForAll(address _owner, address _operator) returns (bool); + function isApprovedForAll(address _owner, address _operator) external view returns (bool); } interface ERC165 { @@ -155,6 +155,7 @@ interface ERC165 { A wallet/broker/auction application MUST implement the **wallet interface** if it will accept safe transfers. ```solidity +/// @dev Note: the ERC-165 identifier for this interface is 0xf0b9e5ba interface ERC721TokenReceiver { /// @notice Handle the receipt of an NFT /// @dev The ERC721 smart contract calls this function on the recipient @@ -165,8 +166,9 @@ interface ERC721TokenReceiver { /// @param _from The sending address /// @param _tokenId The NFT identifier which is being transfered /// @param data Additional data with no specified format - /// @return Always returns `keccak256("ERC721_ONNFTRECEIVED")`, unless throwing - function onNFTReceived(address _from, uint256 _tokenId, bytes data) external returns(bytes4); + /// @return `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))` + /// unless throwing + function onERC721Received(address _from, uint256 _tokenId, bytes data) external returns(bytes4); } ``` @@ -175,7 +177,7 @@ The **metadata extension** is OPTIONAL for ERC-721 smart contracts (see "caveats ```solidity /// @title ERC-721 Non-Fungible Token Standard, optional metadata extension /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md -/// Note: the ERC-165 identifier for this interface is 0xTODO_ADD_THIS +/// Note: the ERC-165 identifier for this interface is 0x5b5e139f interface ERC721Metadata /* is ERC721 */ { /// @notice A descriptive name for a collection of NFTs in this contract function name() external pure returns (string _name); @@ -219,7 +221,7 @@ The **enumeration extension** is OPTIONAL for ERC-721 smart contracts (see "cave ```solidity /// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md -/// Note: the ERC-165 identifier for this interface is 0xTODO_ADD_THIS +/// Note: the ERC-165 identifier for this interface is 0x780e9d63 interface ERC721Enumerable /* is ERC721 */ { /// @notice Count NFTs tracked by this contract /// @return A count of valid NFTs tracked by this contract, where each one of @@ -233,16 +235,6 @@ interface ERC721Enumerable /* is ERC721 */ { /// (sort order not specified) function tokenByIndex(uint256 _index) external view returns (uint256); - /// @notice Count of owners which own at least one NFT - /// @return A count of the number of owners which own NFTs - function countOfOwners() external view returns (uint256); - - /// @notice Enumerate owners which own at least one NFT - /// @dev Throws if `_index` >= `countOfOwners()` - /// @param _index A counter less than `countOfOwners()` - /// @return The address of the `_index`th owner (sort order not specified) - function ownerByIndex(uint256 _index) external view returns (address); - /// @notice Enumerate NFTs assigned to an owner /// @dev Throws if `_index` >= `balanceOf(_owner)` or if /// `_owner` is the zero address, representing invalid NFTs. @@ -283,7 +275,7 @@ The choice of `uint256` allows a wide variety of applications because UUIDs and **Transfer mechanism** -ERC-721 standardizes a safe transfer function `transferFrom` (overloaded with and without a `bytes` parameter) and an unsafe function `unsafeTransfer`. Transfers may be initiated by: +ERC-721 standardizes a safe transfer function `safeTransferFrom` (overloaded with and without a `bytes` parameter) and an unsafe function `transferFrom`. Transfers may be initiated by: - The owner of an NFT - The approved address of an NFT @@ -291,19 +283,19 @@ ERC-721 standardizes a safe transfer function `transferFrom` (overloaded with an Additionally, an authorized operator may set the approved address for an NFT. This provides a powerful set of tools for wallet, broker and auction applications to quickly use a *large* number of NFTs. -The transfer and accept functions documentation only specify conditions when the transaction MUST throw. Your implementation MAY also throw in other situations. This allows implementations to achieve interesting results: +The transfer and accept functions' documentation only specify conditions when the transaction MUST throw. Your implementation MAY also throw in other situations. This allows implementations to achieve interesting results: - **Disallow transfers if the contract is paused** — prior art, [Crypto Kitties](https://github.com/axiomzen/cryptokitties-bounty/blob/master/contracts/KittyOwnership.sol#L79) -- **Blacklist certain address from receiving deeds** — prior art, [Crypto Kitties, (lines 565, 566)](https://etherscan.io/address/0x06012c8cf97bead5deae237070f9587f8e7a266d#code). -- **Disallow unsafe transfers** — `unsafeTransfer` throws unless `_to` equals `msg.sender` or `countOf(_to)` is non-zero (because such cases are safe) -- **Charge a fee to both parties of a transaction** — require payment when calling `approve` with a non-zero `_approved` if it was previously the zero address, refund payment if calling `approve` with the zero address if it was previously a non-zero address, require payment when calling `transfer`, require `transfer` parameter `_to` to equal `msg.sender`, require `transfer` parameter `_to` to be the approved address for the deed -- **Read only deed registry** — always throw from `unsafeTransfer`, `transferFrom`, `approve` and `setApprovalForAll` +- **Blacklist certain address from receiving NFTs** — prior art, [Crypto Kitties, (lines 565, 566)](https://etherscan.io/address/0x06012c8cf97bead5deae237070f9587f8e7a266d#code). +- **Disallow unsafe transfers** — `transferFrom` throws unless `_to` equals `msg.sender` or `countOf(_to)` is non-zero or was non-zero previously (because such cases are safe) +- **Charge a fee to both parties of a transaction** — require payment when calling `approve` with a non-zero `_approved` if it was previously the zero address, refund payment if calling `approve` with the zero address if it was previously a non-zero address, require payment when calling any transfer function, require transfer parameter `_to` to equal `msg.sender`, require transfer parameter `_to` to be the approved address for the NFT +- **Read only NFT registry** — always throw from `unsafeTransfer`, `transferFrom`, `approve` and `setApprovalForAll` -Failed transactions will throw, a best practice identified in [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827) and [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol). [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) defined an `allowance` feature, this caused a problem when called and then later modified to a different amount, as [disucssed on OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/issues/438). In ERC-721, there is no allowance because every deed is unique, the quantity is none or one. Therefore we receive the benefits of ERC-20's original design without problems that have been later discovered. +Failed transactions will throw, a best practice identified in [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827) and [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol). [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) defined an `allowance` feature, this caused a problem when called and then later modified to a different amount, as [disucssed on OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/issues/438). In ERC-721, there is no allowance because every NFT is unique, the quantity is none or one. Therefore we receive the benefits of ERC-20's original design without problems that have been later discovered. Creating of NFTs ("minting") and destruction NFTs ("burning") is not included in the specification. Your contract may implement these by other means. Please see the `event` documentation for your responsibilities when creating or destroying NFTs. -*Alternatives considered: only allow two-step ERC-20 style transaction, require that `transfer` never throw, require all functions to return a boolean indicating the success of the operation.* +*Alternatives considered: only allow two-step ERC-20 style transaction, require that transfer functions never throw, require all functions to return a boolean indicating the success of the operation.* **ERC-165 interface** @@ -358,7 +350,7 @@ We have been very inclusive in this process and invite anyone with questions or We have adopted `balanceOf`, `totalSupply`, `name` and `symbol` semantics from the [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) specification. An implementation may also include a function `decimals` that returns `uint8(0)` if its goal is to be more compatible with ERC-20 while supporting this standard. However, we find it contrived to require all ERC-721 implementations to support the `decimals` function. -Example DAR implementations as of February 2018: +Example NFT implementations as of February 2018: - [CryptoKitties](https://www.cryptokitties.co/) — Compatible with an earlier version of this standard. - [CryptoPunks](https://www.larvalabs.com/cryptopunks) — Partially ERC-20 compatible, but not easily generalizable because it includes auction functionality directly in the contract and uses function names that explicitly refer to the assets as "punks". @@ -366,7 +358,7 @@ Example DAR implementations as of February 2018: Note: "Limited edition, collectible tokens" like [Curio Cards](https://mycuriocards.com/) and [Rare Pepe](https://rarepepewallet.com/) are *not* distinguishable assets. They're actually a collection of individual fungible tokens, each of which is tracked by its own smart contract with its own total supply (which may be `1` in extreme cases). -The `onNFTReceived` function specifically works around old deployed contracts [which may inadvertently return 1 (`true`)](http://solidity.readthedocs.io/en/develop/bugs.html#DelegateCallReturnValue) in certain circumstances even if they don't implement a function. By returning, and checking for, a magic value we are able to distinguish actual affirmative responses versus these `true`s. +The `onERC721Received` function specifically works around old deployed contracts [which may inadvertently return 1 (`true`)](http://solidity.readthedocs.io/en/develop/bugs.html#DelegateCallReturnValue) in certain circumstances even if they don't implement a function. By returning, and checking for, a magic value we are able to distinguish actual affirmative responses versus these `true`s. ## Test Cases From e855ea66c885e0f6b4f1a911e4d40bf35113af3e Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 28 Feb 2018 23:54:45 -0500 Subject: [PATCH 0505/1085] Make getApproved constant view --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 1c34311f5b108..4d92fb23ef7eb 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -132,7 +132,7 @@ interface ERC721 /* is ERC165 */ { /// @dev Throws if `_tokenId` is not a valid NFT /// @param _tokenId The NFT to find the approved address for /// @return The approved address for this NFT, or the zero address if there is none - function getApproved(uint256 _tokenId) external returns (address); + function getApproved(uint256 _tokenId) external view returns (address); /// @notice Query if an address is an authorized operator for another address /// @param _owner The address that owns the NFTs From 7304cca060ad7dba0ca19175ea314c59ce6bfd54 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Thu, 1 Mar 2018 03:33:06 -0500 Subject: [PATCH 0506/1085] Update eip-721.md --- EIPS/eip-721.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 4d92fb23ef7eb..9bc32ab8d2e4e 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -368,6 +368,11 @@ Test cases for an implementation are mandatory for EIPs that are affecting conse ## Implementations +[Su Squares](https://tenthousandsu.com/) an advertising platform where you can rent space and place images + +- Bug bounty program https://github.com/fulldecent/su-squares-bounty +- Implements the complete standard and all optional interfaces + ERC721ExampleDeed, by Nastassia Sachs: https://github.com/nastassiasachs/ERC721ExampleDeed - Implements using the Open Zeppelin project format From bed6978cae1204ca3822977e5843c355d75bff04 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 2 Mar 2018 11:49:33 -0500 Subject: [PATCH 0507/1085] Correct reference name --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 9bc32ab8d2e4e..cd6d562600ae5 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -291,7 +291,7 @@ The transfer and accept functions' documentation only specify conditions when th - **Charge a fee to both parties of a transaction** — require payment when calling `approve` with a non-zero `_approved` if it was previously the zero address, refund payment if calling `approve` with the zero address if it was previously a non-zero address, require payment when calling any transfer function, require transfer parameter `_to` to equal `msg.sender`, require transfer parameter `_to` to be the approved address for the NFT - **Read only NFT registry** — always throw from `unsafeTransfer`, `transferFrom`, `approve` and `setApprovalForAll` -Failed transactions will throw, a best practice identified in [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827) and [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol). [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) defined an `allowance` feature, this caused a problem when called and then later modified to a different amount, as [disucssed on OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/issues/438). In ERC-721, there is no allowance because every NFT is unique, the quantity is none or one. Therefore we receive the benefits of ERC-20's original design without problems that have been later discovered. +Failed transactions will throw, a best practice identified in [ERC-223](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827) and [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol). [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) defined an `allowance` feature, this caused a problem when called and then later modified to a different amount, as [disucssed on OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/issues/438). In ERC-721, there is no allowance because every NFT is unique, the quantity is none or one. Therefore we receive the benefits of ERC-20's original design without problems that have been later discovered. Creating of NFTs ("minting") and destruction NFTs ("burning") is not included in the specification. Your contract may implement these by other means. Please see the `event` documentation for your responsibilities when creating or destroying NFTs. From 3d22a00e47b847c1da6dd68f44c94d527d300a5c Mon Sep 17 00:00:00 2001 From: William Entriken Date: Fri, 2 Mar 2018 12:00:47 -0500 Subject: [PATCH 0508/1085] Update eip-721.md --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index cd6d562600ae5..cdda490f630ee 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -335,7 +335,7 @@ Metadata is returned as a string value. Currently this is only usable as calling **Community consensus** -A significant amount of discussion occurred on [the original ERC-721](ERC-721 issue), additionally we held a live meeting [on Gitter](https://gitter.im/ethereum/ERCs?at=5a62259b5ade18be3998eec4) that had good representation and [was](https://www.reddit.com/r/ethereum/comments/7r2ena/friday_119_live_discussion_on_erc_nonfungible/) [well](https://gitter.im/ethereum/EIPs?at=5a5f823fb48e8c3566f0a5e7) [advertised](https://github.com/ethereum/eips/issues/721#issuecomment-358369377) in relevant communities. Thank you to the participants: +A significant amount of discussion occurred on [the original ERC-721](https://github.com/ethereum/eips/issues/721), additionally we held a live meeting [on Gitter](https://gitter.im/ethereum/ERCs?at=5a62259b5ade18be3998eec4) that had good representation and [was](https://www.reddit.com/r/ethereum/comments/7r2ena/friday_119_live_discussion_on_erc_nonfungible/) [well](https://gitter.im/ethereum/EIPs?at=5a5f823fb48e8c3566f0a5e7) [advertised](https://github.com/ethereum/eips/issues/721#issuecomment-358369377) in relevant communities. Thank you to the participants: - [@ImAllInNow](https://github.com/imallinnow) Rob from DEC Gaming / Presenting Michigan Ethereum Meetup Feb 7 - [@Arachnid](https://github.com/arachnid) Nick Johnson From 91f8558c13299bc987878ee024d72042cd8c8de4 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Mon, 5 Mar 2018 15:14:47 +0100 Subject: [PATCH 0509/1085] Fix the curve equation of G2 It is different from that of G1. See https://github.com/ethereum/yellowpaper/pull/659 --- EIPS/eip-197.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/EIPS/eip-197.md b/EIPS/eip-197.md index 0f5534721ddd2..7abcc842a1941 100644 --- a/EIPS/eip-197.md +++ b/EIPS/eip-197.md @@ -53,12 +53,11 @@ In order to check that an input is an element of `G_1`, verifying the encoding o ### Definition of the groups -The groups `G_1` and `G_2` are cyclic groups of prime order `q = 21888242871839275222246405745257275088548364400416034343698204186575808495617` on the elliptic curve `alt_bn128` defined by the curve equation -`Y^2 = X^3 + 3`. +The groups `G_1` and `G_2` are cyclic groups of prime order `q = 21888242871839275222246405745257275088548364400416034343698204186575808495617`. -The group `G_1` is a cyclic group on the above curve over the field `F_p` with `p = 21888242871839275222246405745257275088696311157297823662689037894645226208583` with generator `P1 = (1, 2)`. +The group `G_1` is defined on the curve `Y^2 = X^3 + 3` over the field `F_p` with `p = 21888242871839275222246405745257275088696311157297823662689037894645226208583` with generator `P1 = (1, 2)`. -The group `G_2` is a cyclic group on the same elliptic curve over a different field `F_p^2 = F_p[i] / (i^2 + 1)` (p is the same as above) with generator +The group `G_2` is defined on the curve `Y^2 = X^3 + 3 ((i+9)^(-1))` over a different field `F_p^2 = F_p[i] / (i^2 + 1)` (p is the same as above) with generator ``` P2 = ( 11559732032986387107991004021392285783925812861821192530917403151452391805634 * i + From 438c09e436fc594f0375e180218397d7fff961df Mon Sep 17 00:00:00 2001 From: William Entriken Date: Tue, 6 Mar 2018 22:35:52 -0500 Subject: [PATCH 0510/1085] Move all links to separate references section --- EIPS/eip-721.md | 133 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 93 insertions(+), 40 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index cdda490f630ee..afed1dce76ef9 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -31,15 +31,15 @@ In general, all houses are distinct and no two kittens are alike. NFTs are *dist A standard interface allows wallet/broker/auction applications to work with any NFT on Ethereum. We provide for simple ERC-721 smart contracts as well as contracts that track an *arbitrarily large* number of NFTs. Additional applications are discussed below. -This standard is inspired by [the ERC-20 token standard](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) and builds on two years of experience since EIP-20 was created. EIP-20 is insufficient for tracking NFTs because each asset is distinct (non-fungible) whereas each of a quantity of tokens is identical (fungible). +This standard is inspired by the ERC-20 token standard](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) and builds on two years of experience since EIP-20 was created. EIP-20 is insufficient for tracking NFTs because each asset is distinct (non-fungible) whereas each of a quantity of tokens is identical (fungible). Differences between this standard and EIP-20 are examined below. ## Specification -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt). +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. -**Every ERC-721 compliant contract must implement the `ERC721` and [`ERC165`](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md) interfaces** (subject to "caveats" below): +**Every ERC-721 compliant contract must implement the `ERC721` and `ERC165` interfaces** (subject to "caveats" below): ```solidity pragma solidity ^0.4.20; @@ -95,7 +95,7 @@ interface ERC721 /* is ERC165 */ { /// @notice Transfers the ownership of an NFT from one address to another address /// @dev This works identically to the other function with an extra data parameter, - /// except this function just sets data to [] + /// except this function just sets data to "" /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer @@ -193,7 +193,7 @@ interface ERC721Metadata /* is ERC721 */ { } ``` -This is the "ERC721 Metadata JSON Schema" referenced above. Learn more about [JSON schemas](http://json-schema.org/). +This is the "ERC721 Metadata JSON Schema" referenced above. ```json { @@ -250,30 +250,30 @@ interface ERC721Enumerable /* is ERC721 */ { The 0.4.20 Solidity interface grammar is not expressive enough to document the ERC-721 standard. A contract which complies with ERC-721 MUST also abide by the following: -- [Solidity issue #3412](https://github.com/ethereum/solidity/issues/3412): The above interfaces include explicit mutability guarantees for each function. Mutability guarantees are, in order weak to strong: `payable`, implicit nonpayable, `view`, and `pure`. Your implementation MUST meet the mutability guarantee in this interface and you MAY meet a stronger guarantee. For example, a `payable` function in this interface may be implemented as nonpayble (no state mutability specified) in your contract. We expect a later Solidity release will allow your stricter contract to inherit from this interface, but a workaround for version 0.4.20 is that you can edit this interface to add stricter mutability before inheriting from your contract. -- [Solidity issue #3419](https://github.com/ethereum/solidity/issues/3419): A contract that implements `ERC721Metadata` or `ERC721Enumerable` SHALL also implement `ERC721`. ERC-721 implements the requirements of interface [ERC-165](https://github.com/ethereum/EIPs/pull/881). -- [Solidity issue #2330](https://github.com/ethereum/solidity/issues/2330): If a function is shown in this specification as `external` then a contract will be compliant if it uses `public` visibility. As a workaround for version 0.4.20, you can edit this interface to switch to `public` before inheriting from your contract. -- Solidity issues [#3494](https://github.com/ethereum/solidity/issues/3494), [#3544](https://github.com/ethereum/solidity/issues/3544): Use of `this.*.selector` is marked as a warning by Solidity, a future version of Solidity will not mark this as an error. +- Solidity issue #3412: The above interfaces include explicit mutability guarantees for each function. Mutability guarantees are, in order weak to strong: `payable`, implicit nonpayable, `view`, and `pure`. Your implementation MUST meet the mutability guarantee in this interface and you MAY meet a stronger guarantee. For example, a `payable` function in this interface may be implemented as nonpayble (no state mutability specified) in your contract. We expect a later Solidity release will allow your stricter contract to inherit from this interface, but a workaround for version 0.4.20 is that you can edit this interface to add stricter mutability before inheriting from your contract. +- Solidity issue #3419: A contract that implements `ERC721Metadata` or `ERC721Enumerable` SHALL also implement `ERC721`. ERC-721 implements the requirements of interface ERC-165. +- Solidity issue #2330: If a function is shown in this specification as `external` then a contract will be compliant if it uses `public` visibility. As a workaround for version 0.4.20, you can edit this interface to switch to `public` before inheriting from your contract. +- Solidity issues #3494, #3544: Use of `this.*.selector` is marked as a warning by Solidity, a future version of Solidity will not mark this as an error. *If a newer version of Solidity allows the caveats to be expressed in code, then this EIP MAY be updated and the caveats removed, such will be equivalent to the original specification.* ## Rationale -There are many proposed uses of Ethereum smart contracts that depend on tracking distinguishable assets. Examples of existing or planned NFTs are LAND in [Decentraland](https://decentraland.org/), the eponymous punks in [CryptoPunks](https://www.larvalabs.com/cryptopunks), and in-game items using systems like [Dmarket](https://www.dmarket.io/) or [EnjinCoin](https://enjincoin.io/). Future uses include tracking real-world assets, like real-estate (as envisioned by companies like [Ubitquity](https://www.ubitquity.io/) or [Propy](https://tokensale.propy.com/)). It is critical in each of these cases that these items are not "lumped together" as numbers in a ledger, but instead, each asset must have its ownership individually and atomically tracked. Regardless of the nature of these assets, the ecosystem will be stronger if we have a standardized interface that allows for cross-functional asset management and sales platforms. +There are many proposed uses of Ethereum smart contracts that depend on tracking distinguishable assets. Examples of existing or planned NFTs are LAND in Decentraland, the eponymous punks in CryptoPunks, and in-game items using systems like DMarket or EnjinCoin. Future uses include tracking real-world assets, like real-estate (as envisioned by companies like Ubitquity or Propy. It is critical in each of these cases that these items are not "lumped together" as numbers in a ledger, but instead each asset must have its ownership individually and atomically tracked. Regardless of the nature of these assets, the ecosystem will be stronger if we have a standardized interface that allows for cross-functional asset management and sales platforms. -**"NFT" word choice** +**"NFT" Word Choice** "NFT" was satisfactory to nearly everyone surveyed and is widely applicable to a broad universe of distinguishable digital assets. We recongize that "deed" is very descriptive for certain applications of this standard (notably, physical property). *Alternatives considered: distinguishable asset, title, token, asset, equity, ticket* -**NFT identifiers** +**NFT Identifiers** Every NFT is identified by a unique `uint265` ID inside the ERC-721 smart contract. This identifing number SHALL NOT change for the life of the contract. The pair `(contract address, uint265 tokenId)` will then be a globally unique and fully-qualified identifier for a specific asset on an Ethereum chain. While some ERC-721 smart contracts may find it convenient to start with ID 0 and simply increment by one for each new NFT, callers SHALL NOT assume that ID numbers have any specific pattern to them, and MUST treat the ID as a "black box". Also note that a NFTs MAY become invalid (be destroyed). Please see the enumerations functions for a supported enumeration interface. The choice of `uint256` allows a wide variety of applications because UUIDs and sha3 hashes are directly convertible to `uint256`. -**Transfer mechanism** +**Transfer Mechanism** ERC-721 standardizes a safe transfer function `safeTransferFrom` (overloaded with and without a `bytes` parameter) and an unsafe function `transferFrom`. Transfers may be initiated by: @@ -285,29 +285,29 @@ Additionally, an authorized operator may set the approved address for an NFT. Th The transfer and accept functions' documentation only specify conditions when the transaction MUST throw. Your implementation MAY also throw in other situations. This allows implementations to achieve interesting results: -- **Disallow transfers if the contract is paused** — prior art, [Crypto Kitties](https://github.com/axiomzen/cryptokitties-bounty/blob/master/contracts/KittyOwnership.sol#L79) -- **Blacklist certain address from receiving NFTs** — prior art, [Crypto Kitties, (lines 565, 566)](https://etherscan.io/address/0x06012c8cf97bead5deae237070f9587f8e7a266d#code). +- **Disallow transfers if the contract is paused** — prior art, CryptoKitties deployed contract, line 611 +- **Blacklist certain address from receiving NFTs** — prior art, CryptoKitties deployed contract, lines 565, 566 - **Disallow unsafe transfers** — `transferFrom` throws unless `_to` equals `msg.sender` or `countOf(_to)` is non-zero or was non-zero previously (because such cases are safe) - **Charge a fee to both parties of a transaction** — require payment when calling `approve` with a non-zero `_approved` if it was previously the zero address, refund payment if calling `approve` with the zero address if it was previously a non-zero address, require payment when calling any transfer function, require transfer parameter `_to` to equal `msg.sender`, require transfer parameter `_to` to be the approved address for the NFT - **Read only NFT registry** — always throw from `unsafeTransfer`, `transferFrom`, `approve` and `setApprovalForAll` -Failed transactions will throw, a best practice identified in [ERC-223](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-827](https://github.com/ethereum/EIPs/issues/827) and [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol). [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) defined an `allowance` feature, this caused a problem when called and then later modified to a different amount, as [disucssed on OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/issues/438). In ERC-721, there is no allowance because every NFT is unique, the quantity is none or one. Therefore we receive the benefits of ERC-20's original design without problems that have been later discovered. +Failed transactions will throw, a best practice identified in ERC-223, ERC-677, ERC-827 and OpenZeppelin's implementation of SafeERC20.sol. ERC-20 defined an `allowance` feature, this caused a problem when called and then later modified to a different amount, as on OpenZeppelin issue \#438. In ERC-721, there is no allowance because every NFT is unique, the quantity is none or one. Therefore we receive the benefits of ERC-20's original design without problems that have been later discovered. Creating of NFTs ("minting") and destruction NFTs ("burning") is not included in the specification. Your contract may implement these by other means. Please see the `event` documentation for your responsibilities when creating or destroying NFTs. *Alternatives considered: only allow two-step ERC-20 style transaction, require that transfer functions never throw, require all functions to return a boolean indicating the success of the operation.* -**ERC-165 interface** +**ERC-165 Interface** -We chose Standard Interface Detection [ERC-165](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md) to expose the interfaces that a ERC-721 smart contract supports. +We chose Standard Interface Detection (ERC-165) to expose the interfaces that a ERC-721 smart contract supports. A future EIP may create a global registry of interfaces for contracts. We strongly support such an EIP and it would allow your ERC-721 implementation to implement `ERC721Enumerable`, `ERC721Metadata`, or other interfaces by delegating to a separate contract. -**Gas and complexity** (regarding the enumeration extension) +**Gas and Complexity** (regarding the enumeration extension) -This specification contemplates implementations that manage a few and *arbitrarily large* numbers of NFTs. If your application is able to grow then [avoid using for/while loops in your code](https://github.com/axiomzen/cryptokitties-bounty/issues/4). These indicate your contract may be unable to scale and gas costs will rise over time without bound. +This specification contemplates implementations that manage a few and *arbitrarily large* numbers of NFTs. If your application is able to grow then avoid using for/while loops in your code (see CryptoKitties bounty issue \#4). These indicate your contract may be unable to scale and gas costs will rise over time without bound. -[We have deployed](https://github.com/fulldecent/erc721-example) a contract to Testnet which instantiates and tracks 340282366920938463463374607431768211456 different deeds (2^128). That's enough to assign every IPV6 address to an Ethereum account owner, or to track ownership of nanobots a few micron in size and in aggregate totalling half the size of Earth. You can query it from the blockchain. And every function takes less gas than [querying the ENS](https://ens.domains/). +We have deployed a contract, XXXXERC721, to Testnet which instantiates and tracks 340282366920938463463374607431768211456 different deeds (2^128). That's enough to assign every IPV6 address to an Ethereum account owner, or to track ownership of nanobots a few micron in size and in aggregate totalling half the size of Earth. You can query it from the blockchain. And every function takes less gas than querying the ENS. This illustration makes clear: the ERC-721 standard scales. @@ -319,28 +319,27 @@ Wallets/brokers/auctioneers identified in the motivation section have a strong n It may be interesting to consider a use case where NFTs are not enumerable, such as a private registry of property ownership, or a partially-private registry. However, privacy cannot be attained because an attacker can simply (!) call `ownerOf` for every possible `tokenId`. -**Metadata choices** (metadata extension) +**Metadata Choices** (metadata extension) -We have required `name` and `symbol` functions in the metadata extension. Every token EIP and draft we reviewed ([ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md), [ERC-233](https://github.com/ethereum/EIPs/issues/223) , [ERC-677](https://github.com/ethereum/EIPs/issues/677), [ERC-777](https://github.com/ethereum/EIPs/issues/777), [ERC-827](https://github.com/ethereum/EIPs/issues/827)) included these functions. +We have required `name` and `symbol` functions in the metadata extension. Every token EIP and draft we reviewed (ERC-20, ERC-223, ERC-677, ERC-777, ERC-827) included these functions. -We remind implementation authors that the empty string is a valid response to `name` and `symbol` if you protest to the usage of this mechanism. We also remind everyone that the official contract for tracking 0xProject tokens (`ZRX`) is [0xe41d2489571d322189246dafa5ebde1f4699f498](https://etherscan.io/address/0xe41d2489571d322189246dafa5ebde1f4699f498). Another contract that advertises a name of `0xProject` and symbol `ZRX` is not the well-known (canonical) contract. - -How a client may determine which ERC-721 smart contracts are well-known is outside the scope of this standard. +We remind implementation authors that the empty string is a valid response to `name` and `symbol` if you protest to the usage of this mechanism. We also remind everyone that any smart contract can use the same name and symbol as *your* contract. How a client may determine which ERC-721 smart contracts are well-known (canonical) is outside the scope of this standard. A mechanism is provided to associate NFTs with URIs. We expect that many implementations will take advantage of this to provide metadata for each NFT. The image size recommendation is taken from Instagram, they probably know much about image usability. The URI MAY be mutable (i.e. it changes from time to time). We considered an NFT representing ownership of a house, in this case metadata about the house (image, occupants, etc.) can naturally change. Metadata is returned as a string value. Currently this is only usable as calling from `web3`, not from other contracts. This is acceptable because we have not considered a use case where an on-blockchain application would query such information. -*Alternatives considered: put all metadata for each asset on the blockchain (too expensive), use URL templates to query metadata parts (URL templates do not work with all URL schemes, especially P2P URLs), [multiaddr network address](https://github.com/multiformats/multiaddr) (not mature enough)* +*Alternatives considered: put all metadata for each asset on the blockchain (too expensive), use URL templates to query metadata parts (URL templates do not work with all URL schemes, especially P2P URLs), multiaddr network address (not mature enough)* -**Community consensus** +**Community Consensus** -A significant amount of discussion occurred on [the original ERC-721](https://github.com/ethereum/eips/issues/721), additionally we held a live meeting [on Gitter](https://gitter.im/ethereum/ERCs?at=5a62259b5ade18be3998eec4) that had good representation and [was](https://www.reddit.com/r/ethereum/comments/7r2ena/friday_119_live_discussion_on_erc_nonfungible/) [well](https://gitter.im/ethereum/EIPs?at=5a5f823fb48e8c3566f0a5e7) [advertised](https://github.com/ethereum/eips/issues/721#issuecomment-358369377) in relevant communities. Thank you to the participants: +A significant amount of discussion occurred on the original ERC-721 issue, additionally we held a first live meeting on Gitter that had good representation and well advertised (on Reddit, in the Gitter #ERC channel, and the original ERC-721 issue). Thank you to the participants: - [@ImAllInNow](https://github.com/imallinnow) Rob from DEC Gaming / Presenting Michigan Ethereum Meetup Feb 7 - [@Arachnid](https://github.com/arachnid) Nick Johnson - [@jadhavajay](https://github.com/jadhavajay) Ajay Jadhav from AyanWorks - [@superphly](https://github.com/superphly) Cody Marx Bailey - XRAM Capital / Sharing at hackathon Jan 20 / UN Future of Finance Hackathon. +- [@fulldecent](https://github.com/fulldecent) William Entriken A second event was held at ETHDenver 2018 to discuss distinguishable asset standards (notes to be published). @@ -348,17 +347,17 @@ We have been very inclusive in this process and invite anyone with questions or ## Backwards Compatibility -We have adopted `balanceOf`, `totalSupply`, `name` and `symbol` semantics from the [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) specification. An implementation may also include a function `decimals` that returns `uint8(0)` if its goal is to be more compatible with ERC-20 while supporting this standard. However, we find it contrived to require all ERC-721 implementations to support the `decimals` function. +We have adopted `balanceOf`, `totalSupply`, `name` and `symbol` semantics from the ERC-20 specification. An implementation may also include a function `decimals` that returns `uint8(0)` if its goal is to be more compatible with ERC-20 while supporting this standard. However, we find it contrived to require all ERC-721 implementations to support the `decimals` function. Example NFT implementations as of February 2018: -- [CryptoKitties](https://www.cryptokitties.co/) — Compatible with an earlier version of this standard. -- [CryptoPunks](https://www.larvalabs.com/cryptopunks) — Partially ERC-20 compatible, but not easily generalizable because it includes auction functionality directly in the contract and uses function names that explicitly refer to the assets as "punks". -- [Auctionhouse Asset Interface](https://github.com/dob/auctionhouse/blob/master/contracts/Asset.sol) — [@dob](https://github.com/dob) needed a generic interface for his Auctionhouse dapp (currently ice-boxed). His "Asset" contract is very simple, but is missing ERC-20 compatibility, `approve()` functionality, and metadata. This effort is referenced in the discussion for [EIP-173](https://github.com/ethereum/EIPs/issues/173). +- CryptoKitties -- Compatible with an earlier version of this standard. +- CryptoPunks -- Partially ERC-20 compatible, but not easily generalizable because it includes auction functionality directly in the contract and uses function names that explicitly refer to the assets as "punks". +- Auctionhouse Asset Interface -- The author needed a generic interface for the Auctionhouse ÐApp (currently ice-boxed). His "Asset" contract is very simple, but is missing ERC-20 compatibility, `approve()` functionality, and metadata. This effort is referenced in the discussion for EIP-173. -Note: "Limited edition, collectible tokens" like [Curio Cards](https://mycuriocards.com/) and [Rare Pepe](https://rarepepewallet.com/) are *not* distinguishable assets. They're actually a collection of individual fungible tokens, each of which is tracked by its own smart contract with its own total supply (which may be `1` in extreme cases). +Note: "Limited edition, collectible tokens" like Curio Cards and Rare Pepe are *not* distinguishable assets. They're actually a collection of individual fungible tokens, each of which is tracked by its own smart contract with its own total supply (which may be `1` in extreme cases). -The `onERC721Received` function specifically works around old deployed contracts [which may inadvertently return 1 (`true`)](http://solidity.readthedocs.io/en/develop/bugs.html#DelegateCallReturnValue) in certain circumstances even if they don't implement a function. By returning, and checking for, a magic value we are able to distinguish actual affirmative responses versus these `true`s. +The `onERC721Received` function specifically works around old deployed contracts which may inadvertently return 1 (`true`) in certain circumstances even if they don't implement a function (see Solidity DelegateCallReturnValue bug). By returning and checking for a magic value, we are able to distinguish actual affirmative responses versus these vacuous `true`s. ## Test Cases @@ -368,19 +367,73 @@ Test cases for an implementation are mandatory for EIPs that are affecting conse ## Implementations -[Su Squares](https://tenthousandsu.com/) an advertising platform where you can rent space and place images +Su Squares -- an advertising platform where you can rent space and place images -- Bug bounty program https://github.com/fulldecent/su-squares-bounty +- Complete the Su Squares Bug Bounty Program to seek problems with this standard or its implementation - Implements the complete standard and all optional interfaces -ERC721ExampleDeed, by Nastassia Sachs: https://github.com/nastassiasachs/ERC721ExampleDeed +ERC721ExampleDeed -- an example implementation -- Implements using the Open Zeppelin project format +- Implements using the OpenZeppelin project format -XXXXERC721, by William Entriken: https://github.com/fulldecent/erc721-example +XXXXERC721, by William Entriken -- a scalable example implementation - Deployed on testnet with 1 billion assets and supporting all lookups with the metadata extension. This demonstrates that scaling is NOT a problem. +## References + +**Standards** + +1. ERC-20 Token Standard. https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md +1. ERC-165 Standard Interface Detection. https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md +1. ERC-173 Owned Standard. https://github.com/ethereum/EIPs/issues/173 +1. ERC-223 Token Standard. https://github.com/ethereum/EIPs/issues/223 +1. ERC-677 `transferAndCall` Token Standard. https://github.com/ethereum/EIPs/issues/677 +1. ERC-827 Token Standard. https://github.com/ethereum/EIPs/issues/827 +1. Ethereum Name Service (ENS). https://ens.domains +1. Instagram -- What's the Image Resolution? https://help.instagram.com/1631821640426723 +1. JSON Schema. http://json-schema.org/ +1. Multiaddr. https://github.com/multiformats/multiaddr +1. RFC 2119 Key words for use in RFCs to Indicate Requirement Levels. https://www.ietf.org/rfc/rfc2119.txt + +**Issues** + +1. The Original ERC-721 Issue. https://github.com/ethereum/eips/issues/721 +1. Solidity Issue \#2330 -- Interface Functions are Axternal. https://github.com/ethereum/solidity/issues/2330 +1. Solidity Issue \#3412 -- Implement Interface: Allow Stricter Mutability. https://github.com/ethereum/solidity/issues/3412 +1. Solidity Issue \#3419 -- Interfaces Can't Inherit. https://github.com/ethereum/solidity/issues/3419 +1. Solidity Issue \#3494 -- Compiler Incorrectly Reasons About the `selector` Function. https://github.com/ethereum/solidity/issues/3494 +1. Solidity Issue \#3544 -- Cannot Calculate Selector of Function Named `transfer`. https://github.com/ethereum/solidity/issues/3544 +1. CryptoKitties Bounty Issue \#4 -- Listing all Kitties Owned by a User is `O(n^2)`. https://github.com/axiomzen/cryptokitties-bounty/issues/4 +1. OpenZeppelin Issue \#438 -- Implementation of `approve` method violates ERC20 standard. https://github.com/OpenZeppelin/zeppelin-solidity/issues/438 +1. Solidity DelegateCallReturnValue Bug. http://solidity.readthedocs.io/en/develop/bugs.html#DelegateCallReturnValue + +**Discussions** + +1. Reddit (announcement of first live discussion). https://www.reddit.com/r/ethereum/comments/7r2ena/friday_119_live_discussion_on_erc_nonfungible/ +1. Gitter #EIPs (announcement of first live discussion). https://gitter.im/ethereum/EIPs?at=5a5f823fb48e8c3566f0a5e7 +1. ERC-721 (announcement of first live discussion). https://github.com/ethereum/eips/issues/721#issuecomment-358369377 +1. ETHDenver 2018. https://ethdenver.com + +**NFT Implementations and Other Projects** + +1. CryptoKitties. https://www.cryptokitties.co +1. Su Squares. https://tenthousandsu.com +1. Decentraland. https://decentraland.org +1. CryptoPunks. https://www.larvalabs.com/cryptopunks +1. DMarket. https://www.dmarket.io +1. Enjin Coin. https://enjincoin.io +1. Ubitquity. https://www.ubitquity.io +1. Propy. https://tokensale.propy.com +1. CryptoKitties Deployed Contract. https://etherscan.io/address/0x06012c8cf97bead5deae237070f9587f8e7a266d#code +1. Su Squares Bug Bounty Program. https://github.com/fulldecent/su-squares-bounty +1. XXXXERC721. https://github.com/fulldecent/erc721-example +1. ERC721ExampleDeed. https://github.com/nastassiasachs/ERC721ExampleDeed +1. Curio Cards. https://mycuriocards.com +1. Rare Pepe. https://rarepepewallet.com +1. Auctionhouse Asset Interface. https://github.com/dob/auctionhouse/blob/master/contracts/Asset.sol +1. OpenZeppelin SafeERC20.sol Implementation. https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/SafeERC20.sol + ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 19a5f63ea1ba31bd9d6bfd83b0088ab3fc89bfaa Mon Sep 17 00:00:00 2001 From: William Entriken Date: Tue, 6 Mar 2018 22:50:01 -0500 Subject: [PATCH 0511/1085] Correct whitespace --- EIPS/eip-721.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index afed1dce76ef9..b132870aa3a7b 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -37,7 +37,7 @@ Differences between this standard and EIP-20 are examined below. ## Specification -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. **Every ERC-721 compliant contract must implement the `ERC721` and `ERC165` interfaces** (subject to "caveats" below): @@ -47,7 +47,7 @@ pragma solidity ^0.4.20; /// @title ERC-721 Non-Fungible Token Standard /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md /// Note: the ERC-165 identifier for this interface is 0x6466353c -interface ERC721 /* is ERC165 */ { +interface ERC721 /* is ERC165 */ { /// @dev This emits when ownership of any NFT changes by any mechanism. /// This event emits when NFTs are created (`from` == 0) and destroyed /// (`to` == 0). Exception: during contract creation, any number of NFTs @@ -287,7 +287,7 @@ The transfer and accept functions' documentation only specify conditions when th - **Disallow transfers if the contract is paused** — prior art, CryptoKitties deployed contract, line 611 - **Blacklist certain address from receiving NFTs** — prior art, CryptoKitties deployed contract, lines 565, 566 -- **Disallow unsafe transfers** — `transferFrom` throws unless `_to` equals `msg.sender` or `countOf(_to)` is non-zero or was non-zero previously (because such cases are safe) +- **Disallow unsafe transfers** — `transferFrom` throws unless `_to` equals `msg.sender` or `countOf(_to)` is non-zero or was non-zero previously (because such cases are safe) - **Charge a fee to both parties of a transaction** — require payment when calling `approve` with a non-zero `_approved` if it was previously the zero address, refund payment if calling `approve` with the zero address if it was previously a non-zero address, require payment when calling any transfer function, require transfer parameter `_to` to equal `msg.sender`, require transfer parameter `_to` to be the approved address for the NFT - **Read only NFT registry** — always throw from `unsafeTransfer`, `transferFrom`, `approve` and `setApprovalForAll` From 7eada30adeebb4301657e3184fd62a2f4dc62369 Mon Sep 17 00:00:00 2001 From: Rikard Hjort Date: Wed, 7 Mar 2018 14:18:21 +0900 Subject: [PATCH 0512/1085] Change `constant` modifier to `view` in functions As the `constant` modifier for functions [is deprecated and planned to be dropped in Solidity 0.5](http://solidity.readthedocs.io/en/develop/contracts.html#view-functions), wouldn't it make sense to reflect this in this standard's code examples? --- EIPS/eip-20.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/EIPS/eip-20.md b/EIPS/eip-20.md index c870d176db3ca..f9d132e89c769 100644 --- a/EIPS/eip-20.md +++ b/EIPS/eip-20.md @@ -42,7 +42,7 @@ but interfaces and other contracts MUST NOT expect these values to be present. ``` js -function name() constant returns (string name) +function name() view returns (string name) ``` @@ -54,7 +54,7 @@ OPTIONAL - This method can be used to improve usability, but interfaces and other contracts MUST NOT expect these values to be present. ``` js -function symbol() constant returns (string symbol) +function symbol() view returns (string symbol) ``` @@ -67,7 +67,7 @@ OPTIONAL - This method can be used to improve usability, but interfaces and other contracts MUST NOT expect these values to be present. ``` js -function decimals() constant returns (uint8 decimals) +function decimals() view returns (uint8 decimals) ``` @@ -76,7 +76,7 @@ function decimals() constant returns (uint8 decimals) Returns the total token supply. ``` js -function totalSupply() constant returns (uint256 totalSupply) +function totalSupply() view returns (uint256 totalSupply) ``` @@ -86,7 +86,7 @@ function totalSupply() constant returns (uint256 totalSupply) Returns the account balance of another account with address `_owner`. ``` js -function balanceOf(address _owner) constant returns (uint256 balance) +function balanceOf(address _owner) view returns (uint256 balance) ``` @@ -138,7 +138,7 @@ function approve(address _spender, uint256 _value) returns (bool success) Returns the amount which `_spender` is still allowed to withdraw from `_owner`. ``` js -function allowance(address _owner, address _spender) constant returns (uint256 remaining) +function allowance(address _owner, address _spender) view returns (uint256 remaining) ``` From 39687dca047e3bedc3502c9637b855e9b87c8626 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Wed, 7 Mar 2018 13:50:12 -0500 Subject: [PATCH 0513/1085] Cosmetic change, remove return name, thank you @nanolucas --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index b132870aa3a7b..9ccd32aabb54d 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -242,7 +242,7 @@ interface ERC721Enumerable /* is ERC721 */ { /// @param _index A counter less than `balanceOf(_owner)` /// @return The token identifier for the `_index`th NFT assigned to `_owner`, /// (sort order not specified) - function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256 _tokenId); + function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256); } ``` From faaec24907cd30eb51b8ab28ee5351c5f0181b85 Mon Sep 17 00:00:00 2001 From: zaq1tomo Date: Thu, 8 Mar 2018 17:19:21 +0900 Subject: [PATCH 0514/1085] add eip-3.md file --- EIPS/eip-3.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 EIPS/eip-3.md diff --git a/EIPS/eip-3.md b/EIPS/eip-3.md new file mode 100644 index 0000000000000..e69de29bb2d1d From f81465cf1bb18ca549a1a2b3582b90e7bfe288bb Mon Sep 17 00:00:00 2001 From: zaq1tomo Date: Thu, 8 Mar 2018 17:19:36 +0900 Subject: [PATCH 0515/1085] update eip-3.md --- EIPS/eip-3.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/EIPS/eip-3.md b/EIPS/eip-3.md index e69de29bb2d1d..e31dd8eb4e34f 100644 --- a/EIPS/eip-3.md +++ b/EIPS/eip-3.md @@ -0,0 +1,9 @@ +``` +EIP: 3 +Title: Addition of CALLDEPTH opcode +Author: Martin Holst Swende +Status: Draft +Type: Standards Track +Layer: Consensus (hard-fork) +Created: 2015-11-19 +``` \ No newline at end of file From 72c4820724502a15ffbb1e16735bb9214a5b45de Mon Sep 17 00:00:00 2001 From: zaq1tomo Date: Thu, 8 Mar 2018 17:20:58 +0900 Subject: [PATCH 0516/1085] update eip-3.md --- EIPS/eip-3.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-3.md b/EIPS/eip-3.md index e31dd8eb4e34f..10bb802d79a2b 100644 --- a/EIPS/eip-3.md +++ b/EIPS/eip-3.md @@ -6,4 +6,8 @@ Status: Draft Type: Standards Track Layer: Consensus (hard-fork) Created: 2015-11-19 -``` \ No newline at end of file +``` + +# Abstract + +This is a proposal to add a new opcode, `CALLDEPTH`. The `CALLDEPTH` opcode would return the remaining available call stack depth. From 8fa9860a5b52ece2cefd422c09593e931252fdcf Mon Sep 17 00:00:00 2001 From: zaq1tomo Date: Thu, 8 Mar 2018 17:24:50 +0900 Subject: [PATCH 0517/1085] update eip-3.md --- EIPS/eip-3.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/EIPS/eip-3.md b/EIPS/eip-3.md index 10bb802d79a2b..11af748064f79 100644 --- a/EIPS/eip-3.md +++ b/EIPS/eip-3.md @@ -11,3 +11,25 @@ Created: 2015-11-19 # Abstract This is a proposal to add a new opcode, `CALLDEPTH`. The `CALLDEPTH` opcode would return the remaining available call stack depth. + +# Motivation + +There is a limit specifying how deep contracts can call other contracts; the call stack. The limit is currently `256`. If a contract invokes another contract (either via `CALL` or `CALLCODE`), the operation will fail if the call stack depth limit has been reached. + +This behaviour makes it possible to subject a contract to a "call stack attack" [1]. In such an attack, an attacker first creates a suitable depth of the stack, e.g. by recursive calls. After this step, the attacker invokes the targeted contract. If the targeted calls another contract, that call will fail. If the return value is not properly checked to see if the call was successfull, the consequences could be damaging. + +Example: + +1. Contract `A` want's to be invoked regularly, and pays Ether to the invoker in every block. +2. When contract `A` is invoked, it calls contracts `B` and `C`, which consumes a lot of gas. After invocation, contract `A` pays Ether to the caller. +3. Malicious user `X` ensures that the stack depth is shallow before invoking A. Both calls to `B` and `C` fail, but `X` can still collect the reward. + +It is possible to defend against this in two ways: + +1. Check return value after invocation. +2. Check call stack depth experimentally. A library [2] by Piper Merriam exists for this purpose. This method is quite costly in gas. + + +[1] a.k.a "shallow stack attack" and "stack attack". However, to be precise, the word ''stack'' has a different meaning within the EVM, and is not to be confused with the ''call stack''. + +[2] https://github.com/pipermerriam/ethereum-stack-depth-lib From d964470d7979b562b037dbb96a6cd33ac159891a Mon Sep 17 00:00:00 2001 From: zaq1tomo Date: Thu, 8 Mar 2018 17:25:32 +0900 Subject: [PATCH 0518/1085] update eip-3.md --- EIPS/eip-3.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/EIPS/eip-3.md b/EIPS/eip-3.md index 11af748064f79..f6093fb2acd03 100644 --- a/EIPS/eip-3.md +++ b/EIPS/eip-3.md @@ -33,3 +33,7 @@ It is possible to defend against this in two ways: [1] a.k.a "shallow stack attack" and "stack attack". However, to be precise, the word ''stack'' has a different meaning within the EVM, and is not to be confused with the ''call stack''. [2] https://github.com/pipermerriam/ethereum-stack-depth-lib + +# Specification + +The opcode `CALLDEPTH` should return the remaining call stack depth. A value of `0` means that the call stack is exhausted, and no further calls can be made. From 510a0a2ac6708d965d393fdca950275d6e7586d2 Mon Sep 17 00:00:00 2001 From: zaq1tomo Date: Thu, 8 Mar 2018 17:26:10 +0900 Subject: [PATCH 0519/1085] update eip-3.md --- EIPS/eip-3.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/EIPS/eip-3.md b/EIPS/eip-3.md index f6093fb2acd03..5358108508025 100644 --- a/EIPS/eip-3.md +++ b/EIPS/eip-3.md @@ -37,3 +37,7 @@ It is possible to defend against this in two ways: # Specification The opcode `CALLDEPTH` should return the remaining call stack depth. A value of `0` means that the call stack is exhausted, and no further calls can be made. + +# Rationale + +The actual call stack depth, as well as the call stack depth limit, are present in the EVM during execution, but just not available within the EVM. The implementation should be fairly simple and would provide a cheap and way to protect against call stack attacks. From 97a48d9ba68b440ab1737b919ed07aa61994cb66 Mon Sep 17 00:00:00 2001 From: zaq1tomo Date: Thu, 8 Mar 2018 17:26:14 +0900 Subject: [PATCH 0520/1085] update eip-3.md --- EIPS/eip-3.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/EIPS/eip-3.md b/EIPS/eip-3.md index 5358108508025..a61468fc53c1d 100644 --- a/EIPS/eip-3.md +++ b/EIPS/eip-3.md @@ -41,3 +41,7 @@ The opcode `CALLDEPTH` should return the remaining call stack depth. A value of # Rationale The actual call stack depth, as well as the call stack depth limit, are present in the EVM during execution, but just not available within the EVM. The implementation should be fairly simple and would provide a cheap and way to protect against call stack attacks. + +# Implementation + +Not implemented. From 027f394c2e9af16f0aecb702490c612b4be2c1d5 Mon Sep 17 00:00:00 2001 From: zaq1tomo Date: Thu, 8 Mar 2018 17:26:53 +0900 Subject: [PATCH 0521/1085] delete eip-3.mediawiki --- EIPS/eip-3.mediawiki | 47 -------------------------------------------- 1 file changed, 47 deletions(-) delete mode 100644 EIPS/eip-3.mediawiki diff --git a/EIPS/eip-3.mediawiki b/EIPS/eip-3.mediawiki deleted file mode 100644 index 526781bcf1752..0000000000000 --- a/EIPS/eip-3.mediawiki +++ /dev/null @@ -1,47 +0,0 @@ -
-  EIP: 3
-  Title: Addition of CALLDEPTH opcode
-  Author: Martin Holst Swende 
-  Status: Draft
-  Type: Standards Track
-  Layer: Consensus (hard-fork)
-  Created: 2015-11-19
-
- -==Abstract== - -This is a proposal to add a new opcode, CALLDEPTH. The CALLDEPTH opcode would return the remaining available call stack depth. - -==Motivation== - -There is a limit specifying how deep contracts can call other contracts; the call stack. The limit is currently `256`. If a contract invokes another contract (either via `CALL` or `CALLCODE`), the operation will fail if the call stack depth limit has been reached. - -This behaviour makes it possible to subject a contract to a "call stack attack" [1]. In such an attack, an attacker first creates a suitable depth of the stack, e.g. by recursive calls. After this step, the attacker invokes the targeted contract. If the targeted calls another contract, that call will fail. If the return value is not properly checked to see if the call was successfull, the consequences could be damaging. - -Example: - -# Contract `A` want's to be invoked regularly, and pays Ether to the invoker in every block. -# When contract `A` is invoked, it calls contracts `B` and `C`, which consumes a lot of gas. After invocation, contract `A` pays Ether to the caller. -# Malicious user `X` ensures that the stack depth is shallow before invoking A. Both calls to `B` and `C` fail, but `X` can still collect the reward. - -It is possible to defend against this in two ways: - -# Check return value after invocation. -# Check call stack depth experimentally. A library [2] by Piper Merriam exists for this purpose. This method is quite costly in gas. - - -[1] a.k.a "shallow stack attack" and "stack attack". However, to be precise, the word ''stack'' has a different meaning within the EVM, and is not to be confused with the ''call stack''. - -[2] https://github.com/pipermerriam/ethereum-stack-depth-lib - -==Specification== - -The opcode CALLDEPTH should return the remaining call stack depth. A value of 0 means that the call stack is exhausted, and no further calls can be made. - -==Rationale== - -The actual call stack depth, as well as the call stack depth limit, are present in the EVM during execution, but just not available within the EVM. The implementation should be fairly simple and would provide a cheap and way to protect against call stack attacks. - -==Implementation== - -Not implemented. From b04ad3c9d1b4866fcf54caabcacc2dca3dbc658a Mon Sep 17 00:00:00 2001 From: zaq1tomo Date: Thu, 8 Mar 2018 17:29:10 +0900 Subject: [PATCH 0522/1085] Update REASDE.md (eip-3.mediawiki to eip-3.md) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b156d6714eca2..2211de9571f64 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP # Non-final EIPs | Number | Title | Author | Layer | Status | | ------------------------- | ------------------------------------------------------- | ----------------------------- | --------- | ---------- | -| [3](EIPS/eip-3.mediawiki) | Addition of CALLDEPTH opcode | Martin Holst Swende | Core | Draft | +| [3](EIPS/eip-3.md) | Addition of CALLDEPTH opcode | Martin Holst Swende | Core | Draft | | [4](EIPS/eip-4.md) | EIP Classification | Joseph Chow | Meta | Draft | | [5](EIPS/eip-5.md) | Gas Usage for `RETURN` and `CALL*` | Christian Reitwiessner | Core | Draft | | [101](EIPS/eip-101.md) | Serenity Currency and Crypto Abstraction | Vitalik Buterin | | Active | From 39067a2db9fc56a0a079a70c537814bd9c3c7f96 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Thu, 8 Mar 2018 15:54:12 -0500 Subject: [PATCH 0523/1085] Fix broken link --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 9ccd32aabb54d..c3dc3f84af240 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -31,7 +31,7 @@ In general, all houses are distinct and no two kittens are alike. NFTs are *dist A standard interface allows wallet/broker/auction applications to work with any NFT on Ethereum. We provide for simple ERC-721 smart contracts as well as contracts that track an *arbitrarily large* number of NFTs. Additional applications are discussed below. -This standard is inspired by the ERC-20 token standard](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md) and builds on two years of experience since EIP-20 was created. EIP-20 is insufficient for tracking NFTs because each asset is distinct (non-fungible) whereas each of a quantity of tokens is identical (fungible). +This standard is inspired by the ERC-20 token standard and builds on two years of experience since EIP-20 was created. EIP-20 is insufficient for tracking NFTs because each asset is distinct (non-fungible) whereas each of a quantity of tokens is identical (fungible). Differences between this standard and EIP-20 are examined below. From 90c54225f3ad6e53e5dbe6595cbbf00b9e610fd6 Mon Sep 17 00:00:00 2001 From: zaq1tomo Date: Fri, 9 Mar 2018 14:17:50 +0900 Subject: [PATCH 0524/1085] move eip-6i6.md --- EIPS/{eip-EIPS => }/eip-616.md | 0 README.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename EIPS/{eip-EIPS => }/eip-616.md (100%) diff --git a/EIPS/eip-EIPS/eip-616.md b/EIPS/eip-616.md similarity index 100% rename from EIPS/eip-EIPS/eip-616.md rename to EIPS/eip-616.md diff --git a/README.md b/README.md index b156d6714eca2..08c79f3c7b59a 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP | [165](EIPS/eip-165.md) | ERC-165 Standard Interface Detection | Christian Reitwiessner | Interface | Draft | | [234](EIPS/eip-234.md) | Add `blockHash` to JSON-RPC filter options | Micah Zoltu | Interface | Draft | | [615](EIPS/eip-615.md) | Subroutines and Static Jumps for the EVM | Greg Colvin | Core | Draft | -| [616](EIPS/eip-EIPS/eip-616.md) | SIMD Operations for the EVM | Greg Colvin | Core | Draft | +| [616](EIPS/eip-616.md) | SIMD Operations for the EVM | Greg Colvin | Core | Draft | | [681](EIPS/eip-681.md) | ERC-681 URL Format for Transaction Requests | Daniel A. Nagy | Interface | Draft | | [758](EIPS/eip-758.md) | Subscriptions and filters for transaction return data | Jack Peterson | Interface | Draft | | [801](EIPS/eip-801.md) | ERC-801 Canary Standard | ligi | Interface | Draft | From 698d42f5321f84d0b2bfdc593a2cfadc712bc727 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 9 Mar 2018 10:45:07 +0100 Subject: [PATCH 0525/1085] Simpler notation A division `/` is simpler than multiplying the inverse `^(-1)` --- EIPS/eip-197.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-197.md b/EIPS/eip-197.md index 7abcc842a1941..e4bab91e7b5b3 100644 --- a/EIPS/eip-197.md +++ b/EIPS/eip-197.md @@ -57,7 +57,7 @@ The groups `G_1` and `G_2` are cyclic groups of prime order `q = 218882428718392 The group `G_1` is defined on the curve `Y^2 = X^3 + 3` over the field `F_p` with `p = 21888242871839275222246405745257275088696311157297823662689037894645226208583` with generator `P1 = (1, 2)`. -The group `G_2` is defined on the curve `Y^2 = X^3 + 3 ((i+9)^(-1))` over a different field `F_p^2 = F_p[i] / (i^2 + 1)` (p is the same as above) with generator +The group `G_2` is defined on the curve `Y^2 = X^3 + 3/(i+9)` over a different field `F_p^2 = F_p[i] / (i^2 + 1)` (p is the same as above) with generator ``` P2 = ( 11559732032986387107991004021392285783925812861821192530917403151452391805634 * i + From 812f414d261ce04329938c36e3e4c60f1cfbeb01 Mon Sep 17 00:00:00 2001 From: Fang Date: Sat, 10 Mar 2018 21:26:49 +0100 Subject: [PATCH 0526/1085] Be explicit about setApprovalForAll's msg.sender requirement. Also correct a typo. --- EIPS/eip-721.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index c3dc3f84af240..a0a5d0d30060f 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -122,7 +122,8 @@ interface ERC721 /* is ERC165 */ { function approve(address _approved, uint256 _tokenId) external payable; /// @notice Enable or disable approval for a third party ("operator") to manage - /// all your asset. + /// all your assets. + /// @dev Throws unless `msg.sender` is the current NFT owner. /// @dev Emits the ApprovalForAll event /// @param _operator Address to add to the set of authorized operators. /// @param _approved True if the operators is approved, false to revoke approval From e31dae63b4cb0361050ca6d711e322201aefc4a7 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Mon, 12 Mar 2018 12:33:17 +0000 Subject: [PATCH 0527/1085] Create EIP-X-metadata-nickjohnson.md --- EIPS/EIP-X-metadata-nickjohnson.md | 72 ++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 EIPS/EIP-X-metadata-nickjohnson.md diff --git a/EIPS/EIP-X-metadata-nickjohnson.md b/EIPS/EIP-X-metadata-nickjohnson.md new file mode 100644 index 0000000000000..364d3f472f37a --- /dev/null +++ b/EIPS/EIP-X-metadata-nickjohnson.md @@ -0,0 +1,72 @@ +## Preamble + + EIP: + Title: Address metadata registry + Author: Nick Johnson + Type: Standard track + Category: ERC + Status: Draft + Created: 2018-03-12 + +## Abstract +This EIP specifies a registry for address metadata, permitting both contracts and external accounts to supply metadata about themselves to onchain and offchain callers. This permits use-cases such as generalised authorisations, providing token acceptance settings, and claims registries. + +## Motivation +An increasing set of use cases require storage of metadata associated with an address; see for instance EIP 777 and EIP 780, and the ENS reverse registry in EIP 181. Presently each use-case defines its own specialised registry. To prevent a proliferation of special-purpose registry contracts, we instead propose a single standardised registry using an extendable architecture that allows future standards to implement their own metadata standards. + +## Specification +The metadata registry has the following interface: +``` +interface AddressMetadataRegistry { + function provider(address target) view returns(address); + function setProvider(address _provider); +} +``` + +`setProvider` specifies the metadata registry to be associated with the caller's address, while `provider` returns the address of the metadata registry for the supplied address. + +The metadata registry will be compiled with an agreed-upon version of Solidity and deployed using the trustless deployment mechanism to a fixed address that can be replicated across all chains. + +## Provider specification + +Providers may implement any subset of the metadata record types specified here. Where a record types specification requires a provider to provide multiple functions, the provider MUST implement either all or none of them. Providers MUST throw if called with an unsupported function ID. + +Providers have one mandatory function: + +``` +function supportsInterface(bytes4 interfaceID) constant returns (bool) +``` + +The `supportsInterface` function is documented in [EIP 165](https://github.com/ethereum/EIPs/issues/165), and returns true if the provider implements the interface specified by the provided 4 byte identifier. An interface identifier consists of the XOR of the function signature hashes of the functions provided by that interface; in the degenerate case of single-function interfaces, it is simply equal to the signature hash of that function. If a provider returns `true` for `supportsInterface()`, it must implement the functions specified in that interface. + +`supportsInterface` must always return true for `0x01ffc9a7`, which is the interface ID of `supportsInterface` itself. + +The first argument to all provider functions MUST be the address being queried; this facilitates the creation of multi-user provider contracts. + +Currently standardised provider interfaces are specified in the table below. + +| Interface name | Interface hash | Specification | +| --- | --- | --- | + +EIPs may define new interfaces to be added to this registry. + +## Rationale +There are two obvious approaches for a generic metadata registry: the indirection approach employed here, or a generalised key/value store. While indirection incurs the cost of an additional contract call, and requires providers to change over time, it also provides for significantly enhanced flexibility over a key/value store; for that reason we selected this approach. + +## Backwards Compatibility +There are no backwards compatibility concerns. + +## Implementation +The canonical implementation of the metadata registry is as follows: +``` +contract AddressMetadataRegistry { + mapping(address=>address) public provider; + + function setProvider(address _provider) { + provider[msg.sender] = _provider; + } +} +``` + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 79509bed927c61c9624f0f460d0faeb68845c249 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Mon, 12 Mar 2018 12:54:18 +0000 Subject: [PATCH 0528/1085] Create EIP-X-authorisations-nickjohnson.md --- EIPS/EIP-X-authorisations-nickjohnson.md | 56 ++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 EIPS/EIP-X-authorisations-nickjohnson.md diff --git a/EIPS/EIP-X-authorisations-nickjohnson.md b/EIPS/EIP-X-authorisations-nickjohnson.md new file mode 100644 index 0000000000000..a754f94dfe034 --- /dev/null +++ b/EIPS/EIP-X-authorisations-nickjohnson.md @@ -0,0 +1,56 @@ +## Preamble + + EIP: + Title: Generalised authorisations + Author: Nick Johnson + Type: Standard track + Category: ERC + Status: Draft + Created: 2018-03-12 + +## Abstract +This EIP specifies a generic authorisation mechanism, which can be used to implement a variety of authorisation patterns, replacing approvals in ERC20, operators in ERC777, and bespoke authorisation patterns in a variety of other types of contract. + +## Motivation +Smart contracts commonly need to provide an interface that allows a third-party caller to perform actions on behalf of a user. The most common example of this is token authorisations/operators, but other similar situations exist throughout the ecosystem, including for instance authorising operations on ENS domains. Typically each standard reinvents this system for themselves, leading to a large number of incompatible implementations of the same basic pattern. Here, we propose a generic method usable by all such contracts. + +The pattern implemented here is inspired by [ds-auth](https://github.com/dapphub/ds-auth) and by OAuth. + +## Specification +The generalised authorisation interface is implemented as a metadata provider, as specified in EIP-X-metadata-nickjohnson. The following mandatory function is implemented: + +``` +function canCall(address owner, address caller, address callee, bytes4 func) view returns(bool); +``` + +Where: + - `owner` is the owner of the resource. If approved the function call is treated as being made by this address. + - `caller` is the address making the present call. + - `callee` is the address of the contract being called. + - `func` is the 4-byte signature of the function being called. + +For example, suppose Alice authorises Bob to transfer tokens on her behalf. When Bob does so, Alice is the `owner`, Bob is the `caller`, the token contract is the `callee`, and the function signature for the transfer function is `func`. + +As this standard uses EIP-X-metadata-nickjohnson, the authorisation flow is as follows: + + 1. The callee contract fetches the provider for the `owner` address from the metadata registry contract, which resides at a well-known address. + 2. The callee contract calls `canCall()` with the parameters described above. If the function returns false, the callee reverts execution. + +Commonly, providers will wish to supply a standardised interface for users to set and unset their own authorisations. They SHOULD implement the following interface: + +``` +function authoriseCaller(address owner, address caller, address callee, bytes4 func, bool authorised); +``` + +Arguments have the same meaning as in `canCall`, with the addition of `authorised,` which specifies if the authorisation is being set or cleared. Implementing contracts MUST ensure that `msg.sender` is authorised to call `authoriseCaller` on behalf of `owner`; this MUST always be true if `owner == msg.sender`. Implementing contracts SHOULD use the standard specified here to determine if other callers may provide authorisations as well. + +Implementing contracts SHOULD treat a `func` of 0 as authorising calls to all functions on `callee`. If `authorised` is `false` and `func` is 0, contracts need only clear any blanket authorisation; individual authorisations may remain in effect. + +## Backwards Compatibility +There are no backwards compatibility concerns. + +## Implementation +Example implementation TBD. + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 6519f179a9f2f2cc875c8057d5664d96e3376a5a Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Mon, 12 Mar 2018 13:51:12 +0000 Subject: [PATCH 0529/1085] Update EIP-X-authorisations-nickjohnson.md --- EIPS/EIP-X-authorisations-nickjohnson.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/EIPS/EIP-X-authorisations-nickjohnson.md b/EIPS/EIP-X-authorisations-nickjohnson.md index a754f94dfe034..31e93fb8e0757 100644 --- a/EIPS/EIP-X-authorisations-nickjohnson.md +++ b/EIPS/EIP-X-authorisations-nickjohnson.md @@ -39,10 +39,11 @@ As this standard uses EIP-X-metadata-nickjohnson, the authorisation flow is as f Commonly, providers will wish to supply a standardised interface for users to set and unset their own authorisations. They SHOULD implement the following interface: ``` -function authoriseCaller(address owner, address caller, address callee, bytes4 func, bool authorised); +function authoriseCaller(address owner, address caller, address callee, bytes4 func); +function revokeCaller(address owner, address caller, address callee, bytes4 func); ``` -Arguments have the same meaning as in `canCall`, with the addition of `authorised,` which specifies if the authorisation is being set or cleared. Implementing contracts MUST ensure that `msg.sender` is authorised to call `authoriseCaller` on behalf of `owner`; this MUST always be true if `owner == msg.sender`. Implementing contracts SHOULD use the standard specified here to determine if other callers may provide authorisations as well. +Arguments have the same meaning as in `canCall`. Implementing contracts MUST ensure that `msg.sender` is authorised to call `authoriseCaller` or `revokeCaller` on behalf of `owner`; this MUST always be true if `owner == msg.sender`. Implementing contracts SHOULD use the standard specified here to determine if other callers may provide authorisations as well. Implementing contracts SHOULD treat a `func` of 0 as authorising calls to all functions on `callee`. If `authorised` is `false` and `func` is 0, contracts need only clear any blanket authorisation; individual authorisations may remain in effect. From de3a3bcc248a44ffa0149feefca86c9e0e74ccc5 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Mon, 12 Mar 2018 14:40:33 +0000 Subject: [PATCH 0530/1085] Update EIP-X-metadata-nickjohnson.md --- EIPS/EIP-X-metadata-nickjohnson.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/EIPS/EIP-X-metadata-nickjohnson.md b/EIPS/EIP-X-metadata-nickjohnson.md index 364d3f472f37a..b0752808f2225 100644 --- a/EIPS/EIP-X-metadata-nickjohnson.md +++ b/EIPS/EIP-X-metadata-nickjohnson.md @@ -7,6 +7,7 @@ Category: ERC Status: Draft Created: 2018-03-12 + Dependencies: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md ## Abstract This EIP specifies a registry for address metadata, permitting both contracts and external accounts to supply metadata about themselves to onchain and offchain callers. This permits use-cases such as generalised authorisations, providing token acceptance settings, and claims registries. @@ -37,7 +38,7 @@ Providers have one mandatory function: function supportsInterface(bytes4 interfaceID) constant returns (bool) ``` -The `supportsInterface` function is documented in [EIP 165](https://github.com/ethereum/EIPs/issues/165), and returns true if the provider implements the interface specified by the provided 4 byte identifier. An interface identifier consists of the XOR of the function signature hashes of the functions provided by that interface; in the degenerate case of single-function interfaces, it is simply equal to the signature hash of that function. If a provider returns `true` for `supportsInterface()`, it must implement the functions specified in that interface. +The `supportsInterface` function is documented in [EIP 165](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md), and returns true if the provider implements the interface specified by the provided 4 byte identifier. An interface identifier consists of the XOR of the function signature hashes of the functions provided by that interface; in the degenerate case of single-function interfaces, it is simply equal to the signature hash of that function. If a provider returns `true` for `supportsInterface()`, it must implement the functions specified in that interface. `supportsInterface` must always return true for `0x01ffc9a7`, which is the interface ID of `supportsInterface` itself. From 41ea883d6e9ba805b5dd1334e7093edf382c6eea Mon Sep 17 00:00:00 2001 From: Maurelian Date: Tue, 13 Mar 2018 12:24:45 -0400 Subject: [PATCH 0531/1085] Update preamble to indicate final status --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index a0a5d0d30060f..fd2d8abfca708 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -1,7 +1,7 @@ ## Preamble ``` -EIP: +EIP: 721 Title: ERC-721 Non-Fungible Token Standard Author: William Entriken , Dieter Shirley , Jacob Evans , Nastassia Sachs Type: Standard From 4cf57f5dba49da61635420615728238863345659 Mon Sep 17 00:00:00 2001 From: Fang Date: Fri, 16 Mar 2018 21:53:36 +0100 Subject: [PATCH 0532/1085] Remove throw condition for setApprovalForAll. And tweak the description to more clearly indicate its difference from the other, per-NFT operations. --- EIPS/eip-721.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index fd2d8abfca708..7f0bbc432e478 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -122,8 +122,7 @@ interface ERC721 /* is ERC165 */ { function approve(address _approved, uint256 _tokenId) external payable; /// @notice Enable or disable approval for a third party ("operator") to manage - /// all your assets. - /// @dev Throws unless `msg.sender` is the current NFT owner. + /// all of `msg.sender`'s assets. /// @dev Emits the ApprovalForAll event /// @param _operator Address to add to the set of authorized operators. /// @param _approved True if the operators is approved, false to revoke approval From 47e16b4baf1d7355af5dbc08eaba2ad3af537241 Mon Sep 17 00:00:00 2001 From: "C. Brown" Date: Mon, 19 Mar 2018 19:19:08 -0500 Subject: [PATCH 0533/1085] Update eip-721 natspec --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 7f0bbc432e478..24482ce630d9a 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -73,9 +73,9 @@ interface ERC721 /* is ERC165 */ { function balanceOf(address _owner) external view returns (uint256); /// @notice Find the owner of an NFT - /// @param _tokenId The identifier for an NFT /// @dev NFTs assigned to zero address are considered invalid, and queries /// about them do throw. + /// @param _tokenId The identifier for an NFT /// @return The address of the owner of the NFT function ownerOf(uint256 _tokenId) external view returns (address); From d164cb2031503665c7dfbb759272f63c29b2b848 Mon Sep 17 00:00:00 2001 From: William Entriken Date: Mon, 19 Mar 2018 23:35:33 -0400 Subject: [PATCH 0534/1085] Correct ERC-165 id --- EIPS/eip-721.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 24482ce630d9a..645ad0dfb4b0f 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -46,7 +46,7 @@ pragma solidity ^0.4.20; /// @title ERC-721 Non-Fungible Token Standard /// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md -/// Note: the ERC-165 identifier for this interface is 0x6466353c +/// Note: the ERC-165 identifier for this interface is 0x80ac58cd interface ERC721 /* is ERC165 */ { /// @dev This emits when ownership of any NFT changes by any mechanism. /// This event emits when NFTs are created (`from` == 0) and destroyed From cdc9c981e9131426a15868c914be34928eec8cc9 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Tue, 20 Mar 2018 15:10:58 +0000 Subject: [PATCH 0535/1085] Fixed headers for existing EIPs to be conformant YAML frontmatter --- EIPS/eip-1.md | 16 +++--- EIPS/eip-100.md | 4 +- EIPS/eip-101.md | 16 +++--- EIPS/eip-107.md | 140 ++++++++++++++++++++++++------------------------ EIPS/eip-137.md | 20 +++---- EIPS/eip-140.md | 18 +++---- EIPS/eip-141.md | 18 +++---- EIPS/eip-145.md | 21 ++++---- EIPS/eip-150.md | 6 +-- EIPS/eip-155.md | 5 +- EIPS/eip-158.md | 4 +- EIPS/eip-160.md | 5 +- EIPS/eip-161.md | 5 +- EIPS/eip-162.md | 4 +- EIPS/eip-165.md | 16 +++--- EIPS/eip-170.md | 5 +- EIPS/eip-181.md | 26 ++++----- EIPS/eip-190.md | 6 +-- EIPS/eip-196.md | 22 ++++---- EIPS/eip-197.md | 22 ++++---- EIPS/eip-2.md | 5 +- EIPS/eip-20.md | 19 ++++--- EIPS/eip-211.md | 23 ++++---- EIPS/eip-214.md | 19 ++++--- EIPS/eip-234.md | 5 +- EIPS/eip-3.md | 24 ++++----- EIPS/eip-4.md | 18 +++---- EIPS/eip-5.md | 18 +++---- EIPS/eip-55.md | 4 +- EIPS/eip-6.md | 18 +++---- EIPS/eip-606.md | 20 +++---- EIPS/eip-607.md | 21 ++++---- EIPS/eip-608.md | 20 +++---- EIPS/eip-609.md | 22 ++++---- EIPS/eip-615.md | 19 +++---- EIPS/eip-616.md | 14 ++--- EIPS/eip-649.md | 20 +++---- EIPS/eip-658.md | 23 ++++---- EIPS/eip-681.md | 34 ++++++------ EIPS/eip-695.md | 19 ++++--- EIPS/eip-7.md | 15 +++--- EIPS/eip-706.md | 18 +++---- EIPS/eip-721.md | 14 +++-- EIPS/eip-758.md | 19 ++++--- EIPS/eip-779.md | 18 +++---- EIPS/eip-8.md | 18 +++---- EIPS/eip-801.md | 19 ++++--- EIPS/eip-831.md | 18 +++---- EIPS/eip-858.md | 18 +++---- EIPS/eip-868.md | 23 ++++---- 50 files changed, 458 insertions(+), 466 deletions(-) diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index d34fed1b37a0c..8b2fd892e4170 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -1,9 +1,11 @@ - EIP: 1 - Title: EIP Purpose and Guidelines - Status: Active - Type: Meta - Author: Martin Becze , Hudson Jameson - Created: 2015-10-27, 2017-02-01 +--- +EIP: 1 +Title: EIP Purpose and Guidelines +Status: Active +Type: Meta +Author: Martin Becze , Hudson Jameson +Created: 2015-10-27, 2017-02-01 +--- What is an EIP? -------------- @@ -40,7 +42,7 @@ The EIP process begins with a new idea for Ethereum. It is highly recommended th Each EIP must have a champion - someone who writes the EIP using the style and format described below, shepherds the discussions in the appropriate forums, and attempts to build community consensus around the idea. -Vetting an idea publicly before going as far as writing an EIP is meant to save the potential author time. Asking the Ethereum community first if an idea is original helps prevent too much time being spent on something that is guaranteed to be rejected based on prior discussions (searching the Internet does not always do the trick). It also helps to make sure the idea is applicable to the entire community and not just the author. Just because an idea sounds good to the author does not mean it will work for most people in most areas where Ethereum is used. Examples of appropriate public forums to gauge interest around your EIP include [the Ethereum subreddit], [the Issues section of this repository], and [one of the Ethereum Gitter chat rooms]. In particular, [the Issues section of this repository] is an excellent place to discuss your proposal with the community and start creating more formalized language around your EIP. +Vetting an idea publicly before going as far as writing an EIP is meant to save the potential author time. Asking the Ethereum community first if an idea is original helps prevent too much time being spent on something that is guaranteed to be rejected based on prior discussions (searching the Internet does not always do the trick). It also helps to make sure the idea is applicable to the entire community and not just the author. Just because an idea sounds good to the author does not mean it will work for most people in most areas where Ethereum is used. Examples of appropriate public forums to gauge interest around your EIP include [the Ethereum subreddit], [the Issues section of this repository], and [one of the Ethereum Gitter chat rooms]. In particular, [the Issues section of this repository] is an excellent place to discuss your proposal with the community and start creating more formalized language around your EIP. Once the champion has asked the Ethereum community whether an idea has any chance of acceptance a draft EIP should be presented as a [pull request]. This gives the author a chance to continuously edit the draft EIP for proper formatting and quality. This also allows for further public comment and the author of the EIP to address concerns about the proposal. diff --git a/EIPS/eip-100.md b/EIPS/eip-100.md index 12d7dda24a85e..61961def0a6cd 100644 --- a/EIPS/eip-100.md +++ b/EIPS/eip-100.md @@ -1,4 +1,4 @@ -``` +--- EIP: 100 Title: Change difficulty adjustment to target mean block time including uncles Author: Vitalik Buterin @@ -6,7 +6,7 @@ Type: Standard Track Category: Core Status: Final Created: 2016-04-28 -``` +--- ### Specification diff --git a/EIPS/eip-101.md b/EIPS/eip-101.md index f064741e3dc53..4ad6cff4bb746 100644 --- a/EIPS/eip-101.md +++ b/EIPS/eip-101.md @@ -1,11 +1,11 @@ -### Title - - EIP: 101 - Title: Serenity Currency and Crypto Abstraction - Author: Vitalik Buterin - Status: Active - Type: Serenity feature - Created: 2015-11-15 +--- +EIP: 101 +Title: Serenity Currency and Crypto Abstraction +Author: Vitalik Buterin +Status: Active +Type: Serenity feature +Created: 2015-11-15 +--- ### Specification diff --git a/EIPS/eip-107.md b/EIPS/eip-107.md index 2054368ab0f8d..5e3ab179297a3 100644 --- a/EIPS/eip-107.md +++ b/EIPS/eip-107.md @@ -1,16 +1,16 @@ -
-  EIP: 107
-  Title: safe "eth_sendTransaction" authorization via html popup
-  Author: Ronan Sandford 
-  Created: 2016-06-05
-  Status: Draft
-  Type: Standard
-  Category: Interface
-
+--- +EIP: 107 +Title: safe "eth_sendTransaction" authorization via html popup +Author: Ronan Sandford +Created: 2016-06-05 +Status: Draft +Type: Standard +Category: Interface +--- Abstract ======== -This draft EIP describes the details of an authorization method that if provided by rpc enabled ethereum nodes would allow regular websites to send transactions (via ```eth_sendTransaction```) without the need to enable CORS. Instead, user would be asked to confirm the transaction via an html popup. +This draft EIP describes the details of an authorization method that if provided by rpc enabled ethereum nodes would allow regular websites to send transactions (via ```eth_sendTransaction```) without the need to enable CORS. Instead, user would be asked to confirm the transaction via an html popup. Every read only rpc call the dapp wants to perform is redirected to an invisible iframe from the node's domain and for every transaction that the dapp wish to execute, an html popup is presented to the user to allow him/her to cancel or confirm the transaction. This allows the dapp to connect to the node's rpc api without being granted any kind of privileges. This allows users to safely interact with dapps running in their everyday web browser while their accounts are unlocked. In case the account is not unlocked, and the node has allowed the "personal" api via rpc,the html page also allow the user to enter their password to unlock the account for the scope of the transaction. @@ -50,16 +50,16 @@ In order for the mechanism to work, the node needs to serve an html file via htt This file will then be used by the dapp in 2 different modes (invisible iframe and popup window). -The invisible iframe will be embeded in the dapp to allow the dapp to send its read-only rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port. +The invisible iframe will be embeded in the dapp to allow the dapp to send its read-only rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port. In the iframe mode, the html file's javascript code will ensure that no call requiring an unlocked key can be made. This is to prevent dapps from embedding the invisible iframe and tricking the user into clicking the confirm button. If the dapp requires an ```eth_sendTransaction``` call, the dapp will instead open a new window using the same url. -In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (but not ```eth_sign```, as there is no way to display to the user the meaningful content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses, as well as the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request. +In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (but not ```eth_sign```, as there is no way to display to the user the meaningful content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses, as well as the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request. The html page also checks for the availability of the "personal" api and if so, will ask the user to unlock the account if necessary. The unlocking is temporary (3s) so the password will be asked again if a transaction is attempted before the end of this short time. -In both iframe mode and window mode, the communication with the dapp is achieved using ```window.postMessage```. +In both iframe mode and window mode, the communication with the dapp is achieved using ```window.postMessage```. The fist message the iframe/window sends is a message containing the string "ready" to let the dapp know that it now accepts messages. Then the dapp can start performing rpc call by sending message using the following object : ``` { @@ -81,7 +81,7 @@ In all the cases, the iframe/window will send a message back to the dapp using t } ``` -the error object cannot be a javascript Error object due to postMessage limitation. Instead it is +the error object cannot be a javascript Error object due to postMessage limitation. Instead it is ``` { message:, @@ -92,7 +92,7 @@ the error object cannot be a javascript Error object due to postMessage limitati Rationale ========= -The design for that proposal was chosen for its simplicity and security. A previous idea was to use an oauth-like protocol in order for the user to accept or deny a transaction request. It would have required deeper code change in the node and some geth contributors argues that such change did not fit into geth code base as it would have required dapp aware code. +The design for that proposal was chosen for its simplicity and security. A previous idea was to use an oauth-like protocol in order for the user to accept or deny a transaction request. It would have required deeper code change in the node and some geth contributors argues that such change did not fit into geth code base as it would have required dapp aware code. The current design, instead has a very simple implementation (self contained html file that can be shared across node's implementation) and its safeness is guarantess by browsers' cross domain policies. The use of iframe/ window was required to have both security and user friendliness. The invisble iframe allows the dapp to execute read only calls without the need for user input, and the window ensures user approval before making a call. While we could have made it without the window mode by making the iframe confirmation use the native browser ```window.confirm``` dialog, this would have prevented the use of a more elegant confirmation popup that the current design allows. It also happens to be that the ```window.confirm``` is not safe in some browsers, as it gives focus to the accept option and can be triggered automatically (https://bugs.chromium.org/p/chromium/issues/detail?id=260653). @@ -114,11 +114,11 @@ That's it. - + - +

Please wait...

- +

@@ -238,13 +238,13 @@ That's it.
- + - + diff --git a/EIPS/eip-137.md b/EIPS/eip-137.md index b28b6fd315516..e81ab076504d1 100644 --- a/EIPS/eip-137.md +++ b/EIPS/eip-137.md @@ -1,16 +1,16 @@ -
-  EIP: 137
-  Title: Ethereum Domain Name Service - Specification
-  Author: Nick Johnson 
-  Status: Final
-  Type: Standards Track
-  Category: ERC
-  Created: 2016-04-04
-
+--- +EIP: 137 +Title: Ethereum Domain Name Service - Specification +Author: Nick Johnson +Status: Final +Type: Standards Track +Category: ERC +Created: 2016-04-04 +--- # Abstract -This draft EIP describes the details of the Ethereum Name Service, a proposed protocol and ABI definition that provides flexible resolution of short, human-readable names to service and resource identifiers. This permits users and developers to refer to human-readable and easy to remember names, and permits those names to be updated as necessary when the underlying resource (contract, content-addressed data, etc) changes. +This draft EIP describes the details of the Ethereum Name Service, a proposed protocol and ABI definition that provides flexible resolution of short, human-readable names to service and resource identifiers. This permits users and developers to refer to human-readable and easy to remember names, and permits those names to be updated as necessary when the underlying resource (contract, content-addressed data, etc) changes. The goal of domain names is to provide stable, human-readable identifiers that can be used to specify network resources. In this way, users can enter a memorable string, such as 'vitalik.wallet' or 'www.mysite.swarm', and be directed to the appropriate resource. The mapping between names and resources may change over time, so a user may change wallets, a website may change hosts, or a swarm document may be updated to a new version, without the domain name changing. Further, a domain need not specify a single resource; different record types allow the same domain to reference different resources. For instance, a browser may resolve 'mysite.swarm' to the IP address of its server by fetching its A (address) record, while a mail client may resolve the same address to a mail server by fetching its MX (mail exchanger) record. # Motivation diff --git a/EIPS/eip-140.md b/EIPS/eip-140.md index 026e30255ae66..964870323d1ff 100644 --- a/EIPS/eip-140.md +++ b/EIPS/eip-140.md @@ -1,12 +1,12 @@ -## Preamble - - EIP: 140 - Title: REVERT instruction - Author: Alex Beregszaszi, Nikolai Mushegian (nikolai@nexusdev.us) - Type: Standard Track - Category: Core - Status: Final - Created: 2017-02-06 +--- +EIP: 140 +Title: REVERT instruction +Author: Alex Beregszaszi, Nikolai Mushegian (nikolai@nexusdev.us) +Type: Standard Track +Category: Core +Status: Final +Created: 2017-02-06 +--- ## Simple Summary diff --git a/EIPS/eip-141.md b/EIPS/eip-141.md index fed18d6d1dc7a..7794ff3e9a253 100644 --- a/EIPS/eip-141.md +++ b/EIPS/eip-141.md @@ -1,12 +1,12 @@ -## Preamble - - EIP: 141 - Title: Designated invalid EVM instruction - Author: Alex Beregszaszi - Type: Standard Track - Category: Core - Status: Final - Created: 2017-02-09 +--- +EIP: 141 +Title: Designated invalid EVM instruction +Author: Alex Beregszaszi +Type: Standard Track +Category: Core +Status: Final +Created: 2017-02-09 +--- ## Abstract diff --git a/EIPS/eip-145.md b/EIPS/eip-145.md index c993af140ab7a..20849c3e2d28f 100644 --- a/EIPS/eip-145.md +++ b/EIPS/eip-145.md @@ -1,13 +1,12 @@ -## Preamble - - EIP: 145 - Title: Bitwise shifting instructions in EVM - Author: Alex Beregszaszi, Paweł Bylica - Type: Standard Track - Category: Core - Status: Final - Created: 2017-02-13 - +--- +EIP: 145 +Title: Bitwise shifting instructions in EVM +Author: Alex Beregszaszi, Paweł Bylica +Type: Standard Track +Category: Core +Status: Final +Created: 2017-02-13 +--- ## Simple Summary @@ -158,7 +157,7 @@ The newly introduced instructions have no effect on bytecode created in the past --- 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe ``` - + ### `SHR` (logical shift right) diff --git a/EIPS/eip-150.md b/EIPS/eip-150.md index 9070389e78fe2..a6414f29e0f42 100644 --- a/EIPS/eip-150.md +++ b/EIPS/eip-150.md @@ -1,5 +1,4 @@ -## Preamble -``` +--- EIP: 150 Title: Gas cost changes for IO-heavy operations Author: Vitalik Buterin @@ -7,7 +6,8 @@ Type: Standard Track Category: Core Status: Final Created: 2016-09-24 -``` +--- + ### Meta reference [Tangerine Whistle](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-608.md). diff --git a/EIPS/eip-155.md b/EIPS/eip-155.md index 849fa1321d7e8..28bfa32268efb 100644 --- a/EIPS/eip-155.md +++ b/EIPS/eip-155.md @@ -1,5 +1,4 @@ -## Preamble -``` +--- EIP: 155 Title: Simple replay attack protection Author: Vitalik Buterin @@ -7,7 +6,7 @@ Type: Standard Track Category: Core Status: Final Created: 2016-10-14 -``` +--- ### Hard fork [Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md) diff --git a/EIPS/eip-158.md b/EIPS/eip-158.md index 46b945dc30758..a7bd99a7db324 100644 --- a/EIPS/eip-158.md +++ b/EIPS/eip-158.md @@ -1,4 +1,4 @@ -``` +--- EIP: 158 Title: State clearing Author: Vitalik Buterin @@ -7,7 +7,7 @@ Category: Core Status: Superseded Created: 2016-10-16 Superseded-By: 161 -``` +--- # Specification diff --git a/EIPS/eip-160.md b/EIPS/eip-160.md index 5c88e5f04c452..68892eb65dfbb 100644 --- a/EIPS/eip-160.md +++ b/EIPS/eip-160.md @@ -1,4 +1,4 @@ -``` +--- EIP: 160 Title: EXP cost increase Author: Vitalik Buterin @@ -6,7 +6,8 @@ Type: Standard Track Category: Core Status: Final Created: 2016-10-20 -``` +--- + ### Hard fork [Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md) diff --git a/EIPS/eip-161.md b/EIPS/eip-161.md index 09d6a4c29e509..d8f7ca959bb38 100644 --- a/EIPS/eip-161.md +++ b/EIPS/eip-161.md @@ -1,4 +1,4 @@ -``` +--- EIP: 161 Title: State trie clearing (invariant-preserving alternative) Author: Gavin Wood @@ -6,7 +6,8 @@ Type: Standard Track Category: Core Status: Final Created: 2016-10-24 -``` +--- + ### Hard fork [Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md) diff --git a/EIPS/eip-162.md b/EIPS/eip-162.md index ec6fd158fddc8..03c57539f40d3 100644 --- a/EIPS/eip-162.md +++ b/EIPS/eip-162.md @@ -1,4 +1,4 @@ -``` +--- EIP: 162 Title: Initial ENS Hash Registrar Author: Maurelian and Nick Johnson @@ -6,7 +6,7 @@ Status: Final Type: Standards Track Category: ERC Created: 2016-10-25 -``` +--- ## Contents - Abstract diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index 529b483eabd14..98b1962ebbea3 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -1,6 +1,4 @@ -## Preamble - -``` +--- EIP: 165 Title: ERC-165 Standard Interface Detection Author: Christian Reitwießner , Nick Johnson , Fabian Vogelsteller , Jordi Baylina , Konrad Feldmeier , William Entriken @@ -8,7 +6,7 @@ Type: Standard Track Category: ERC Status: Draft Created: 2018-01-23 -``` +--- ## Simple Summary @@ -122,7 +120,7 @@ contract ERC165Query { function doesContractImplementInterface(address _contract, bytes4 _interfaceId) external view returns (bool) { uint256 success; uint256 result; - + (success, result) = noThrowCall(_contract, ERC165ID); if ((success==0)||(result==0)) { return false; @@ -193,7 +191,7 @@ contract Lisa is ERC165MappingImplementation, Simpson { function Lisa() public { supportedInterfaces[this.is2D.selector ^ this.skinColor.selector] = true; } - + function is2D() external returns (bool){} function skinColor() external returns (string){} } @@ -213,12 +211,12 @@ interface Simpson { contract Homer is ERC165, Simpson { function supportsInterface(bytes4 interfaceID) external view returns (bool) { - return + return interfaceID == this.supportsInterface.selector || // ERC165 - interfaceID == this.is2D.selector + interfaceID == this.is2D.selector ^ this.skinColor.selector; // Simpson } - + function is2D() external returns (bool){} function skinColor() external returns (string){} } diff --git a/EIPS/eip-170.md b/EIPS/eip-170.md index 4dfa169e7117b..4ef64d012d204 100644 --- a/EIPS/eip-170.md +++ b/EIPS/eip-170.md @@ -1,4 +1,4 @@ -``` +--- EIP: 170 Title: Contract code size limit Author: Vitalik Buterin @@ -6,7 +6,8 @@ Type: Standard Track Category: Core Status: Final Created: 2016-11-04 -``` +--- + ### Hard fork [Spurious Dragon](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md) diff --git a/EIPS/eip-181.md b/EIPS/eip-181.md index bbd0f48e6ba2c..2615f6dbc3c7d 100644 --- a/EIPS/eip-181.md +++ b/EIPS/eip-181.md @@ -1,12 +1,12 @@ -
-  EIP: 181
-  Title: ENS support for reverse resolution of Ethereum addresses
-  Author: Nick Johnson 
-  Status: Final
-  Type: Standard Track
-  Category: ERC
-  Created: 2016-12-01
-
+--- +EIP: 181 +Title: ENS support for reverse resolution of Ethereum addresses +Author: Nick Johnson +Status: Final +Type: Standard Track +Category: ERC +Created: 2016-12-01 +--- # Abstract This EIP specifies a TLD, registrar, and resolver interface for reverse resolution of Ethereum addresses using ENS. This permits associating a human-readable name with any Ethereum blockchain address. Resolvers can be certain that the reverse record was published by the owner of the Ethereum address in question. @@ -24,7 +24,7 @@ Reverse ENS records are stored in the ENS hierarchy in the same fashion as regul Note that this means that contracts wanting to do dynamic reverse resolution of addresses will need to perform hex encoding in the contract. ## Registrar -The owner of the `addr.reverse` domain will be a registrar that permits the caller to take ownership of +The owner of the `addr.reverse` domain will be a registrar that permits the caller to take ownership of the reverse record for their own address. It provides the following method: function claim(address owner) returns (bytes32 node); @@ -57,7 +57,7 @@ This registrar, written in Solidity, implements the specifications outlined abov contract ReverseRegistrar { AbstractENS public ens; bytes32 public rootNode; - + /** * @dev Constructor * @param ensAddr The address of the ENS registry. @@ -67,7 +67,7 @@ This registrar, written in Solidity, implements the specifications outlined abov ens = AbstractENS(ensAddr); rootNode = node; } - + /** * @dev Transfers ownership of the reverse ENS record associated with the * calling account. @@ -79,7 +79,7 @@ This registrar, written in Solidity, implements the specifications outlined abov ens.setSubnodeOwner(rootNode, label, owner); return sha3(rootNode, label); } - + /** * @dev An optimised function to compute the sha3 of the lower-case * hexadecimal representation of an Ethereum address. diff --git a/EIPS/eip-190.md b/EIPS/eip-190.md index 7ef046e91e509..07e51f97eedbf 100644 --- a/EIPS/eip-190.md +++ b/EIPS/eip-190.md @@ -1,4 +1,4 @@ -``` +--- EIP: 190 Title: Ethereum Smart Contract Packaging Standard Authors: Piper Merriam, Tim Coulter, Denis Erfurt (mhhf), RJ Catalano (VoR0220), Iuri Matias (iurimatias) @@ -6,7 +6,7 @@ Status: Final Type: Standards Track Category: ERC Created: 2017-01-10 -``` +--- # Abstract @@ -38,7 +38,7 @@ Smart contract packaging should also have a direct positive effect on the end us The full specification for this standard is maintained separately in the repository [epm/epm-spec](https://github.com/ethpm/epm-spec). -This EIP refers to the `1.0.0` version of the specification: [https://github.com/ethpm/epm-spec/tree/v1.0.0](https://github.com/ethpm/epm-spec/tree/v1.0.0) +This EIP refers to the `1.0.0` version of the specification: [https://github.com/ethpm/epm-spec/tree/v1.0.0](https://github.com/ethpm/epm-spec/tree/v1.0.0) The specification contains details for a single document referred to as a *"Release Lockfile"*. diff --git a/EIPS/eip-196.md b/EIPS/eip-196.md index 3eaa411ee285e..f9e045d48b969 100644 --- a/EIPS/eip-196.md +++ b/EIPS/eip-196.md @@ -1,13 +1,13 @@ -## Preamble - - EIP: 196 - Title: Precompiled contracts for addition and scalar multiplication - on the elliptic curve alt_bn128 - Author: Christian Reitwiessner - Type: Standard Track - Category: Core - Status: Final - Created: 2017-02-02 +--- +EIP: 196 +Title: Precompiled contracts for addition and scalar multiplication + on the elliptic curve alt_bn128 +Author: Christian Reitwiessner +Type: Standard Track +Category: Core +Status: Final +Created: 2017-02-02 +--- ## Simple Summary @@ -46,7 +46,7 @@ Tuples of objects are encoded as their concatenation. For both precompiled contracts, if the input is shorter than expected, it is assumed to be virtually padded with zeros at the end (i.e. compatible with the semantics of the `CALLDATALOAD` opcode). If the input is longer than expected, surplus bytes at the end are ignored. -The length of the returned data is always as specified (i.e. it is not "unpadded"). +The length of the returned data is always as specified (i.e. it is not "unpadded"). ### Exact semantics diff --git a/EIPS/eip-197.md b/EIPS/eip-197.md index 0f5534721ddd2..df993abe69d5e 100644 --- a/EIPS/eip-197.md +++ b/EIPS/eip-197.md @@ -1,13 +1,13 @@ -## Preamble - - EIP: 197 - Title: Precompiled contracts for optimal ate pairing check - on the elliptic curve alt_bn128 - Author: Vitalik Buterin , Christian Reitwiessner - Type: Standard Track - Category: Core - Status: Final - Created: 2017-02-06 +--- +EIP: 197 +Title: Precompiled contracts for optimal ate pairing check + on the elliptic curve alt_bn128 +Author: Vitalik Buterin , Christian Reitwiessner +Type: Standard Track +Category: Core +Status: Final +Created: 2017-02-06 +--- ## Simple Summary @@ -81,7 +81,7 @@ Elliptic curve points are encoded as a Jacobian pair `(X, Y)` where the point at Note that the number `k` is derived from the input length. -The length of the returned data is always exactly 32 bytes and encoded as a 32 byte big-endian number. +The length of the returned data is always exactly 32 bytes and encoded as a 32 byte big-endian number. ### Gas costs diff --git a/EIPS/eip-2.md b/EIPS/eip-2.md index 18c4949c21b7f..0db000e4eb4ab 100644 --- a/EIPS/eip-2.md +++ b/EIPS/eip-2.md @@ -1,4 +1,4 @@ -``` +--- EIP: 2 Title: Homestead Hard-fork Changes Author: Vitalik Buterin @@ -6,7 +6,8 @@ Status: Final Type: Standard Track Category: Core Created: 2015-11-15 -``` +--- + ### Meta reference [Homestead](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-606.md). diff --git a/EIPS/eip-20.md b/EIPS/eip-20.md index f9d132e89c769..dba043f9223ed 100644 --- a/EIPS/eip-20.md +++ b/EIPS/eip-20.md @@ -1,13 +1,12 @@ -## Preamble - - EIP: 20 - Title: ERC-20 Token Standard - Author: Fabian Vogelsteller , Vitalik Buterin - Type: Standard - Category: ERC - Status: Accepted - Created: 2015-11-19 - +--- +EIP: 20 +Title: ERC-20 Token Standard +Author: Fabian Vogelsteller , Vitalik Buterin +Type: Standard +Category: ERC +Status: Accepted +Created: 2015-11-19 +--- ## Simple Summary diff --git a/EIPS/eip-211.md b/EIPS/eip-211.md index 14f65f917b756..9fa4c7f2ee83d 100644 --- a/EIPS/eip-211.md +++ b/EIPS/eip-211.md @@ -1,15 +1,14 @@ -## Preamble - - EIP: 211 - Title: New opcodes: RETURNDATASIZE and RETURNDATACOPY - Author: Christian Reitwiessner - Type: Standard Track - Category Core - Status: Final - Created: 2017-02-13 - Requires: - Replaces: 5/8 - +--- +EIP: 211 +Title: New opcodes: RETURNDATASIZE and RETURNDATACOPY +Author: Christian Reitwiessner +Type: Standard Track +Category Core +Status: Final +Created: 2017-02-13 +Requires: +Replaces: 5/8 +--- ## Simple Summary diff --git a/EIPS/eip-214.md b/EIPS/eip-214.md index 2e5756c0c57e0..cbdf7a3094eef 100644 --- a/EIPS/eip-214.md +++ b/EIPS/eip-214.md @@ -1,12 +1,12 @@ -## Preamble - - EIP: 214 - Title: New opcode STATICCALL - Author: Vitalik Buterin , Christian Reitwiessner ; - Type: Standard Track - Category: Core - Status: Final - Created: 2017-02-13 +--- +EIP: 214 +Title: New opcode STATICCALL +Author: Vitalik Buterin , Christian Reitwiessner ; +Type: Standard Track +Category: Core +Status: Final +Created: 2017-02-13 +--- ## Simple Summary @@ -49,4 +49,3 @@ To be written. ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). - diff --git a/EIPS/eip-234.md b/EIPS/eip-234.md index 7d8403e476a8c..de1752bbd466b 100644 --- a/EIPS/eip-234.md +++ b/EIPS/eip-234.md @@ -1,5 +1,4 @@ -## Preamble -``` +--- EIP: 234 Title: Add `blockHash` to JSON-RPC filter options. Author: Micah Zoltu @@ -7,7 +6,7 @@ Type: Standard Track Category: Interface Status: Draft Created: 2017-03-24 -``` +--- ## Simple Summary diff --git a/EIPS/eip-3.md b/EIPS/eip-3.md index a61468fc53c1d..de9ae751d0bdb 100644 --- a/EIPS/eip-3.md +++ b/EIPS/eip-3.md @@ -1,4 +1,4 @@ -``` +--- EIP: 3 Title: Addition of CALLDEPTH opcode Author: Martin Holst Swende @@ -6,37 +6,37 @@ Status: Draft Type: Standards Track Layer: Consensus (hard-fork) Created: 2015-11-19 -``` +--- # Abstract -This is a proposal to add a new opcode, `CALLDEPTH`. The `CALLDEPTH` opcode would return the remaining available call stack depth. +This is a proposal to add a new opcode, `CALLDEPTH`. The `CALLDEPTH` opcode would return the remaining available call stack depth. # Motivation -There is a limit specifying how deep contracts can call other contracts; the call stack. The limit is currently `256`. If a contract invokes another contract (either via `CALL` or `CALLCODE`), the operation will fail if the call stack depth limit has been reached. +There is a limit specifying how deep contracts can call other contracts; the call stack. The limit is currently `256`. If a contract invokes another contract (either via `CALL` or `CALLCODE`), the operation will fail if the call stack depth limit has been reached. -This behaviour makes it possible to subject a contract to a "call stack attack" [1]. In such an attack, an attacker first creates a suitable depth of the stack, e.g. by recursive calls. After this step, the attacker invokes the targeted contract. If the targeted calls another contract, that call will fail. If the return value is not properly checked to see if the call was successfull, the consequences could be damaging. +This behaviour makes it possible to subject a contract to a "call stack attack" [1]. In such an attack, an attacker first creates a suitable depth of the stack, e.g. by recursive calls. After this step, the attacker invokes the targeted contract. If the targeted calls another contract, that call will fail. If the return value is not properly checked to see if the call was successfull, the consequences could be damaging. -Example: +Example: 1. Contract `A` want's to be invoked regularly, and pays Ether to the invoker in every block. -2. When contract `A` is invoked, it calls contracts `B` and `C`, which consumes a lot of gas. After invocation, contract `A` pays Ether to the caller. -3. Malicious user `X` ensures that the stack depth is shallow before invoking A. Both calls to `B` and `C` fail, but `X` can still collect the reward. +2. When contract `A` is invoked, it calls contracts `B` and `C`, which consumes a lot of gas. After invocation, contract `A` pays Ether to the caller. +3. Malicious user `X` ensures that the stack depth is shallow before invoking A. Both calls to `B` and `C` fail, but `X` can still collect the reward. It is possible to defend against this in two ways: -1. Check return value after invocation. +1. Check return value after invocation. 2. Check call stack depth experimentally. A library [2] by Piper Merriam exists for this purpose. This method is quite costly in gas. [1] a.k.a "shallow stack attack" and "stack attack". However, to be precise, the word ''stack'' has a different meaning within the EVM, and is not to be confused with the ''call stack''. -[2] https://github.com/pipermerriam/ethereum-stack-depth-lib +[2] https://github.com/pipermerriam/ethereum-stack-depth-lib # Specification -The opcode `CALLDEPTH` should return the remaining call stack depth. A value of `0` means that the call stack is exhausted, and no further calls can be made. +The opcode `CALLDEPTH` should return the remaining call stack depth. A value of `0` means that the call stack is exhausted, and no further calls can be made. # Rationale @@ -44,4 +44,4 @@ The actual call stack depth, as well as the call stack depth limit, are present # Implementation -Not implemented. +Not implemented. diff --git a/EIPS/eip-4.md b/EIPS/eip-4.md index 260d842426145..9793b26efb8f8 100644 --- a/EIPS/eip-4.md +++ b/EIPS/eip-4.md @@ -1,12 +1,12 @@ -
-  EIP: 4
-  Layer: Process
-  Title: EIP Classification
-  Author: Joseph Chow
-  Status: Draft
-  Type: Process
-  Created: 2015-11-17
-
+--- +EIP: 4 +Layer: Process +Title: EIP Classification +Author: Joseph Chow +Status: Draft +Type: Process +Created: 2015-11-17 +--- # Abstract diff --git a/EIPS/eip-5.md b/EIPS/eip-5.md index 02408e2fc7a27..9214572a82384 100644 --- a/EIPS/eip-5.md +++ b/EIPS/eip-5.md @@ -1,12 +1,12 @@ -### Title - - EIP: 5 - Title: Gas Usage for `RETURN` and `CALL*` - Author: Christian Reitwiessner - Status: Draft - Type: Standards Track - Layer: Consensus (hard-fork) - Created: 2015-11-22 +--- +EIP: 5 +Title: Gas Usage for `RETURN` and `CALL*` +Author: Christian Reitwiessner +Status: Draft +Type: Standards Track +Layer: Consensus (hard-fork) +Created: 2015-11-22 +--- ### Abstract diff --git a/EIPS/eip-55.md b/EIPS/eip-55.md index e9e1c82af1bb6..75cf21111e327 100644 --- a/EIPS/eip-55.md +++ b/EIPS/eip-55.md @@ -1,4 +1,4 @@ -``` +--- EIP: 55 Title: Mixed-case checksum address encoding Author: Vitalik Buterin @@ -6,7 +6,7 @@ Type: Standard Track Category: ERC Status: Accepted Created: 2016-01-14 -``` +--- # Specification diff --git a/EIPS/eip-6.md b/EIPS/eip-6.md index d6d2bc8fdfeb8..d13bbc0f6e8e0 100644 --- a/EIPS/eip-6.md +++ b/EIPS/eip-6.md @@ -1,12 +1,12 @@ -### Title - - EIP: 6 - Title: Renaming SUICIDE opcode - Author: Hudson Jameson - Status: Final - Type: Standards Track - Layer: Applications - Created: 2015-11-22 +--- +EIP: 6 +Title: Renaming SUICIDE opcode +Author: Hudson Jameson +Status: Final +Type: Standards Track +Layer: Applications +Created: 2015-11-22 +--- ### Abstract The solution proposed in this EIP is to change the name of the `SUICIDE` opcode in Ethereum programming languages with `SELFDESTRUCT`. diff --git a/EIPS/eip-606.md b/EIPS/eip-606.md index c8dad7f004ab8..71f17e844b0c1 100644 --- a/EIPS/eip-606.md +++ b/EIPS/eip-606.md @@ -1,12 +1,12 @@ -## Preamble - - EIP: 606 - Title: Hardfork Meta: Homestead - Author: Alex Beregszaszi - Type: Meta - Status: Final - Created: 2017-04-23 - Requires: 2, 7 +--- +EIP: 606 +Title: Hardfork Meta: Homestead +Author: Alex Beregszaszi +Type: Meta +Status: Final +Created: 2017-04-23 +Requires: 2, 7 +--- ## Abstract @@ -23,7 +23,7 @@ This specifies the changes included in the hard fork named Homestead. - [EIP 2](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md) (Homestead Hard-fork Changes) - [EIP 7](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7.md) (DELEGATECALL) - [EIP 8](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-8.md) (Networking layer: devp2p Forward Compatibility Requirements for Homestead) - + ## References 1. https://blog.ethereum.org/2016/02/29/homestead-release/ diff --git a/EIPS/eip-607.md b/EIPS/eip-607.md index 15a2a2f256898..3247bd260a1be 100644 --- a/EIPS/eip-607.md +++ b/EIPS/eip-607.md @@ -1,13 +1,12 @@ - -## Preamble - - EIP: 607 - Title: Hardfork Meta: Spurious Dragon - Author: Alex Beregszaszi - Type: Meta - Status: Final - Created: 2017-04-23 - Requires: 155, 160, 161, 170 +--- +EIP: 607 +Title: Hardfork Meta: Spurious Dragon +Author: Alex Beregszaszi +Type: Meta +Status: Final +Created: 2017-04-23 +Requires: 155, 160, 161, 170 +--- ## Abstract @@ -25,7 +24,7 @@ This specifies the changes included in the hard fork named Spurious Dragon. - [EIP 160](eip-160.md) (EXP cost increase) - [EIP 161](eip-161.md) (State trie clearing) - [EIP 170](eip-170.md) (Contract code size limit) - + ## References 1. https://blog.ethereum.org/2016/11/18/hard-fork-no-4-spurious-dragon/ diff --git a/EIPS/eip-608.md b/EIPS/eip-608.md index 22ee846e127a5..9cf88d993a922 100644 --- a/EIPS/eip-608.md +++ b/EIPS/eip-608.md @@ -1,12 +1,12 @@ -## Preamble - - EIP: 608 - Title: Hardfork Meta: Tangerine Whistle - Author: Alex Beregszaszi - Type: Meta - Status: Final - Created: 2017-04-23 - Requires: 150 +--- +EIP: 608 +Title: Hardfork Meta: Tangerine Whistle +Author: Alex Beregszaszi +Type: Meta +Status: Final +Created: 2017-04-23 +Requires: 150 +--- ## Abstract @@ -20,7 +20,7 @@ This specifies the changes included in the hard fork named Tangerine Whistle (EI - Block >= 2,463,000 on Mainnet - Included EIPs: - [EIP 150](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-150.md) (Gas cost changes for IO-heavy operations) - + ## References 1. https://blog.ethereum.org/2016/10/13/announcement-imminent-hard-fork-eip150-gas-cost-changes/ diff --git a/EIPS/eip-609.md b/EIPS/eip-609.md index c849c24bad326..d805dc596634b 100644 --- a/EIPS/eip-609.md +++ b/EIPS/eip-609.md @@ -1,13 +1,13 @@ -## Preamble - - EIP: 609 - Title: Hardfork Meta: Byzantium - Author: Alex Beregszaszi - Type: Standard Track - Category: Core - Status: Final - Created: 2017-04-23 - Requires: 100, 140, 196, 197, 198, 211, 214, 649, 658 +--- +EIP: 609 +Title: Hardfork Meta: Byzantium +Author: Alex Beregszaszi +Type: Standard Track +Category: Core +Status: Final +Created: 2017-04-23 +Requires: 100, 140, 196, 197, 198, 211, 214, 649, 658 +--- ## Abstract @@ -30,7 +30,7 @@ This specifies the changes included in the hard fork named Byzantium. - [EIP 214](./eip-214.md) (New opcode STATICCALL) - [EIP 649](./eip-649.md) (Difficulty Bomb Delay and Block Reward Reduction) - [EIP 658](./eip-658.md) (Embedding transaction status code in receipts) - + ## References 1. https://blog.ethereum.org/2017/10/12/byzantium-hf-announcement/ diff --git a/EIPS/eip-615.md b/EIPS/eip-615.md index 8cf1a61081fe4..1a83014d34902 100644 --- a/EIPS/eip-615.md +++ b/EIPS/eip-615.md @@ -1,4 +1,4 @@ -``` +--- EIP: 615 Title: Subroutines and Static Jumps for the EVM Status: Draft @@ -6,7 +6,8 @@ Type: Core Author: Greg Colvin , Paweł Bylica, Christian Reitwiessner Created: 2016-12-10 Edited: 2017-25-4 -``` +--- + ## Abstract This EIP introduces new EVM opcodes and conditions on EVM code to support subroutines and static jumps, disallow dynamic jumps, and thereby make EVM code amenable to linear-time static analysis. This will provide for better compilation, interpretation, transpilation, and formal analysis of EVM code. @@ -84,7 +85,7 @@ specifies that all of the following bytes to the end of the bytecode are data, a ### Indirect Jumps -The primitive operations provide for static jumps. Dynamic jumps are also used for O(1) indirection: an address to jump to is selected to push on the stack and be jumped to. So we also propose two more instructions to provide for constrained indirection. We support these with vectors of `JUMPDEST` or `BEGINSUB` offsets stored inline, which can be selected with an index on the stack. That constrains validation to a specified subset of all possible destinations. The danger of quadratic blow up is avoided because it takes as much space to store the jump vectors as it does to code the worst case exploit. +The primitive operations provide for static jumps. Dynamic jumps are also used for O(1) indirection: an address to jump to is selected to push on the stack and be jumped to. So we also propose two more instructions to provide for constrained indirection. We support these with vectors of `JUMPDEST` or `BEGINSUB` offsets stored inline, which can be selected with an index on the stack. That constrains validation to a specified subset of all possible destinations. The danger of quadratic blow up is avoided because it takes as much space to store the jump vectors as it does to code the worst case exploit. Dynamic jumps to a `JUMPDEST` are used to implement O(1) jumptables, which are useful for dense switch statements, and are implemented as instructions similar to this one on most CPUs. * `JUMPV n, jumpdest ...` @@ -159,7 +160,7 @@ _Execution_ is as defined in the Yellow Paper - a sequence of changes in the EVM >5 Invalid instruction -We propose to expand and extend the Yellow Paper conditions to handle the new instructions we propose. +We propose to expand and extend the Yellow Paper conditions to handle the new instructions we propose. To handle the return stack we expand the conditions on stack size: >2a The size of the data stack does not exceed 1024. @@ -206,7 +207,7 @@ Validating that jumps are to valid addresses takes two sequential passes over th is_sub[code_size] // is there a BEGINSUB at PC? is_dest[code_size] // is there a JUMPDEST at PC? sub_for_pc[code_size] // which BEGINSUB is PC in? - + bool validate_jumps(PC) { current_sub = PC @@ -226,7 +227,7 @@ Validating that jumps are to valid addresses takes two sequential passes over th is_dest[PC] = true sub_for_pc[PC] = current_sub } - + // check that targets are in subroutine for (PC = 0; instruction = bytecode[PC]; PC = advance_pc(PC)) { @@ -322,10 +323,10 @@ The basic approach is to call `validate_subroutine(i, 0, 0)`, for _i_ equal to t if instruction is JUMPTO { PC = jump_target(PC) - continue + continue } - // recurse to jump to code to validate + // recurse to jump to code to validate if instruction is JUMPIF { if not validate_subroutine(jump_target(PC), return_pc, SP) @@ -367,6 +368,6 @@ These changes would need to be implemented in phases at decent intervals: >2 A later hard fork would require clients to place only valid code on the block chain. Note that despite the fork old EVM code will still need to be supported indefinitely. -If desired, the period of deprecation can be extended indefinitely by continuing to accept code not versioned as new - but without validation. That is, by delaying step 2. Since we must continue to run old code this is not technically difficult. +If desired, the period of deprecation can be extended indefinitely by continuing to accept code not versioned as new - but without validation. That is, by delaying step 2. Since we must continue to run old code this is not technically difficult. Implementation of this proposal need not be difficult, At the least, interpreters can simply be extended with the new opcodes and run unchanged otherwise. The new opcodes require only stacks for the frame pointers and return offsets and the few pushes, pops, and assignments described above. JIT code can use native calls. Further optimizations include minimizing runtime checks for exceptions and taking advantage of validated code wherever possible. diff --git a/EIPS/eip-616.md b/EIPS/eip-616.md index df54888a51607..6237f8d862af9 100644 --- a/EIPS/eip-616.md +++ b/EIPS/eip-616.md @@ -1,4 +1,4 @@ -``` +--- EIP: 616 Title: SIMD Operations for the EVM Author: Greg Colvin, greg@colvin.org @@ -6,7 +6,7 @@ Type: Standard Track Category: Core Status: Draft Created: 2017-04-25 -``` +--- ## ABSTRACT @@ -27,7 +27,7 @@ Most all modern CPUs include SIMD hardware that operates on wide registers of da ### Encoding -We propose a simple encoding of SIMD operations as extended two-byte codes. The first byte is the opcode, and the second byte is the SIMD type: scalar type, lane width, and number of elements. +We propose a simple encoding of SIMD operations as extended two-byte codes. The first byte is the opcode, and the second byte is the SIMD type: scalar type, lane width, and number of elements. N bits | Field -|- @@ -46,7 +46,7 @@ _Note that floating point operations are **not** proposed for inclusion in the i ### Semantics -We define the following extended versions of the EVM's arithmetic, logic, and comparison operations. As with the normal versions, they consume their arguments from the stack and place their results on the stack, except that their arguments are vectors rather than scalars. +We define the following extended versions of the EVM's arithmetic, logic, and comparison operations. As with the normal versions, they consume their arguments from the stack and place their results on the stack, except that their arguments are vectors rather than scalars. lo\hi | B | C -|-|- @@ -79,13 +79,13 @@ uint8[5, 7, 9] ``` on the stack. -XSHUFFLE takes two vectors on the stack: a vector to permute and a permutation mask. E.g. +XSHUFFLE takes two vectors on the stack: a vector to permute and a permutation mask. E.g. ``` PUSH uint64[4, 5, 6, 0] PUSH uint8[2, 0, 1, 3] SHUFFLE ``` -leaves +leaves ``` uint64[6, 4, 5 , 0] ``` @@ -110,7 +110,7 @@ marks the **single** entry to a subroutine. `n_args` items are taken off of the ## RATIONALE -Currently, the lowest common denominator for SIMD hardware (e.g. Intel SSE2 and ARM Neon) is 16-byte registers supporting integer lanes of 1, 2, 4, and 8 bytes, and floating point lanes of 4 and 8 bytes. More recent SIMD hardware (e.g. Intel AVX) supports 32-byte registers, and EVM stack items are also 32 bytes wide. The limits above derive from these numbers, assuring that EVM code is within the bounds of available hardware - and the reserved bits provide room for growth. +Currently, the lowest common denominator for SIMD hardware (e.g. Intel SSE2 and ARM Neon) is 16-byte registers supporting integer lanes of 1, 2, 4, and 8 bytes, and floating point lanes of 4 and 8 bytes. More recent SIMD hardware (e.g. Intel AVX) supports 32-byte registers, and EVM stack items are also 32 bytes wide. The limits above derive from these numbers, assuring that EVM code is within the bounds of available hardware - and the reserved bits provide room for growth. For most modern languages (including Rust, Python, Go, Java, and C++) compilers can do a good job of generating SIMD code for parallelizable loops, and/or there are intrinsics or libraries available for explicit access to SIMD hardware. So a portable software implementation will likely provide good use of the hardware on most platforms, and intrinsics or libraries can be used as available and needed. Thus we can expect these operations to take about the same (or for 256-bit vectors on 128-bit hardware up to twice) the time to execute regardless of element size or number of elements. diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index e2adda472a9fc..33199f1103c75 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -1,13 +1,13 @@ -## Preamble - - EIP: 649 - Title: Metropolis Difficulty Bomb Delay and Block Reward Reduction - Authors: Afri Schoedon, Vitalik Buterin - Type: Standard Track - Category: Core - Status: Final - Created: 2017-06-21 - Replaces: 186 +--- +EIP: 649 +Title: Metropolis Difficulty Bomb Delay and Block Reward Reduction +Authors: Afri Schoedon, Vitalik Buterin +Type: Standard Track +Category: Core +Status: Final +Created: 2017-06-21 +Replaces: 186 +--- ## Simple Summary The average block times are increasing due to the difficulty bomb (also known as the "_ice age_") slowly accelerating. This EIP proposes to delay the difficulty bomb for approximately one and a half year and to reduce the block rewards with the Byzantium fork, the first part of the Metropolis fork. diff --git a/EIPS/eip-658.md b/EIPS/eip-658.md index 09afc15ec28dc..782832dc4eaea 100644 --- a/EIPS/eip-658.md +++ b/EIPS/eip-658.md @@ -1,15 +1,14 @@ -## Preamble - - EIP: 658 - Title: Embedding transaction status code in receipts - Author: Nick Johnson - Type: Standard Track - Category Core - Status: Final - Created: 2017-06-30 - Requires: 140 - Replaces: 98 - +--- +EIP: 658 +Title: Embedding transaction status code in receipts +Author: Nick Johnson +Type: Standard Track +Category Core +Status: Final +Created: 2017-06-30 +Requires: 140 +Replaces: 98 +--- ## Abstract This EIP replaces the intermediate state root field of the receipt with a status code indicating if the top-level call succeeded or failed. diff --git a/EIPS/eip-681.md b/EIPS/eip-681.md index ab4b1cffe216a..57a83203d6366 100644 --- a/EIPS/eip-681.md +++ b/EIPS/eip-681.md @@ -1,13 +1,13 @@ -## Preamble - - EIP: 681 - Title: URL Format for Transaction Requests - Author: Daniel A. Nagy - Type: Standard Track - Category: ERC - Status: Draft - Created: 2017-08-01 - Requires: 20, 137, 831 +--- +EIP: 681 +Title: URL Format for Transaction Requests +Author: Daniel A. Nagy +Type: Standard Track +Category: ERC +Status: Draft +Created: 2017-08-01 +Requires: 20, 137, 831 +--- ## Simple Summary A standard way of representing various transactions, especially payment requests in Ethers and ERC #20 tokens as URLs. @@ -37,12 +37,12 @@ Payment request URLs contain "ethereum" in their schema (protocol) part and are number = [ "-" / "+" ] *DIGIT [ "." 1*DIGIT ] [ ( "e" / "E" ) [ 1*DIGIT ] [ "+" UNIT ] -Where `TYPE` is a standard ABI type name, as defined in [Ethereum Contract ABI specification](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI). `STRING` is a URL-encoded unicode string of arbitrary length, where delimiters and the +Where `TYPE` is a standard ABI type name, as defined in [Ethereum Contract ABI specification](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI). `STRING` is a URL-encoded unicode string of arbitrary length, where delimiters and the percentage symbol (`%`) are mandatorily hex-encoded with a `%` prefix. -`UNIT` is a URL-encoded unicode string. If `UNIT` is ETH, it always means a multiplier of 1018. If it is something -else AND the addressed contract has a `symbol` field exactly matching this string AND the contract has a `decimals` field, then -10 to that power is used as a multiplier. Otherwise, the payment request is deemed invalid. Applications that have no access to +`UNIT` is a URL-encoded unicode string. If `UNIT` is ETH, it always means a multiplier of 1018. If it is something +else AND the addressed contract has a `symbol` field exactly matching this string AND the contract has a `decimals` field, then +10 to that power is used as a multiplier. Otherwise, the payment request is deemed invalid. Applications that have no access to the blockchain should refuse accepting requests with a non-empty `UNIT`, if it is not ETH. Note that a `number` can be expressed in *scientific notation*, with a multiplier of a power of 10. The use of this notation is strongly encouraged when expressing monetary value in Ethers or ERC #20 tokens in atomic units (e. g. Wei, in case of Ether). @@ -57,11 +57,11 @@ For the syntax of ENS_NAME, please consult ERC #137 defining Ethereum Name Servi `chain_id` is optional and contains the decimal chain ID, such that transactions on various test- and private networks can be requested. If no `chain_id` is present, the client's current network setting remains effective. -If `function_name` is missing, then the URL is requesting payment in the native token of the blockchain, which is Ether in our case. The amount is specified in `value` parameter, in the atomic unit (i.e. Wei). The use of scientific notation is strongly encouraged. For example, requesting 2.014 ETH to address `0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359` would look as follows: +If `function_name` is missing, then the URL is requesting payment in the native token of the blockchain, which is Ether in our case. The amount is specified in `value` parameter, in the atomic unit (i.e. Wei). The use of scientific notation is strongly encouraged. For example, requesting 2.014 ETH to address `0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359` would look as follows: [ethereum:0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359?value=2.014e18](ethereum:0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359?value=2.014e18) -Requesting payments in ERC #20 tokens involves a request to call the `transfer` function of the token contract with an `address` and a `uint256` typed parameter, containing the *beneficiary address* and the *amount in atomic units*, respectively. For example, -requesting a Unicorn to address `0x8e23ee67d1332ad560396262c48ffbb01f93d052` looks as follows: +Requesting payments in ERC #20 tokens involves a request to call the `transfer` function of the token contract with an `address` and a `uint256` typed parameter, containing the *beneficiary address* and the *amount in atomic units*, respectively. For example, +requesting a Unicorn to address `0x8e23ee67d1332ad560396262c48ffbb01f93d052` looks as follows: [ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7/transfer?address=0x8e23ee67d1332ad560396262c48ffbb01f93d052&uint256=1](ethereum:0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7/transfer?address=0x8e23ee67d1332ad560396262c48ffbb01f93d052&uint256=1) If using ENS names instead of hexadecimal addresses, the resolution is up to the payer, at any time between receiving the URL and sending the transaction. Hexadecimal addresses always take precedence over ENS names, i. e. even if there exists a matching ENS name consisting of 40 hexadecimal digits, it should never be resolved. Instead, the hexadecimal address should be used directly. diff --git a/EIPS/eip-695.md b/EIPS/eip-695.md index c917d29ced092..02ace809474d7 100644 --- a/EIPS/eip-695.md +++ b/EIPS/eip-695.md @@ -1,13 +1,12 @@ -## Preamble - - EIP: 695 - Title: Create `eth_chainId` method for JSON-RPC - Author: Isaac Ardis: isaac.ardis@gmail.com, Wei Tang: hi@that.world, [@tcz001](https://github.com/tcz001) - Type: Standard Track - Category: Interface - Status: Draft - Created: 2017-08-21 - +--- +EIP: 695 +Title: Create `eth_chainId` method for JSON-RPC +Author: Isaac Ardis: isaac.ardis@gmail.com, Wei Tang: hi@that.world, [@tcz001](https://github.com/tcz001) +Type: Standard Track +Category: Interface +Status: Draft +Created: 2017-08-21 +--- ## Simple Summary Include `eth_chainId` method in `eth_`-namespaced JSON-RPC methods. diff --git a/EIPS/eip-7.md b/EIPS/eip-7.md index f33ca94350f16..989d1f4085c2e 100644 --- a/EIPS/eip-7.md +++ b/EIPS/eip-7.md @@ -1,10 +1,11 @@ -### Title - EIP: 7 - Title: DELEGATECALL - Author: Vitalik Buterin - Status: Final - Type: Homestead feature - Created: 2015-11-15 +--- +EIP: 7 +Title: DELEGATECALL +Author: Vitalik Buterin +Status: Final +Type: Homestead feature +Created: 2015-11-15 +--- ### Hard Fork [Homestead](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-606.md) diff --git a/EIPS/eip-706.md b/EIPS/eip-706.md index 638b15646aad5..712b5f56eb03d 100644 --- a/EIPS/eip-706.md +++ b/EIPS/eip-706.md @@ -1,12 +1,12 @@ -## Preamble - - EIP: 706 - Title: DEVp2p snappy compression - Author: Péter Szilágyi - Type: Standard Track - Category: Networking - Status: Final - Created: 2017-09-07 +--- +EIP: 706 +Title: DEVp2p snappy compression +Author: Péter Szilágyi +Type: Standard Track +Category: Networking +Status: Final +Created: 2017-09-07 +--- ## Abstract The base networking protocol (DEVp2p) used by Ethereum currently does not employ any form of compression. This results in a massive amount of bandwidth wasted in the entire network, making both initial sync as well as normal operation slower and laggier. diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 645ad0dfb4b0f..55626a1f986a4 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -1,6 +1,4 @@ -## Preamble - -``` +--- EIP: 721 Title: ERC-721 Non-Fungible Token Standard Author: William Entriken , Dieter Shirley , Jacob Evans , Nastassia Sachs @@ -9,7 +7,7 @@ Category ERC Status: Draft Created: 2018-01-24 Requires: ERC-165 -``` +--- ## Simple Summary @@ -92,7 +90,7 @@ interface ERC721 /* is ERC165 */ { /// @param _tokenId The NFT to transfer /// @param data Additional data with no specified format, sent in call to `_to` function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable; - + /// @notice Transfers the ownership of an NFT from one address to another address /// @dev This works identically to the other function with an extra data parameter, /// except this function just sets data to "" @@ -163,7 +161,7 @@ interface ERC721TokenReceiver { /// transfer. This function MUST use 50,000 gas or less. Return of other /// than the magic value MUST result in the transaction being reverted. /// Note: the contract address is always the message sender. - /// @param _from The sending address + /// @param _from The sending address /// @param _tokenId The NFT identifier which is being transfered /// @param data Additional data with no specified format /// @return `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))` @@ -263,7 +261,7 @@ There are many proposed uses of Ethereum smart contracts that depend on tracking **"NFT" Word Choice** -"NFT" was satisfactory to nearly everyone surveyed and is widely applicable to a broad universe of distinguishable digital assets. We recongize that "deed" is very descriptive for certain applications of this standard (notably, physical property). +"NFT" was satisfactory to nearly everyone surveyed and is widely applicable to a broad universe of distinguishable digital assets. We recongize that "deed" is very descriptive for certain applications of this standard (notably, physical property). *Alternatives considered: distinguishable asset, title, token, asset, equity, ticket* @@ -343,7 +341,7 @@ A significant amount of discussion occurred on the original ERC-721 issue, addit A second event was held at ETHDenver 2018 to discuss distinguishable asset standards (notes to be published). -We have been very inclusive in this process and invite anyone with questions or contributions into our discussion. However, this standard is written only to support the identified use cases which are listed herein. +We have been very inclusive in this process and invite anyone with questions or contributions into our discussion. However, this standard is written only to support the identified use cases which are listed herein. ## Backwards Compatibility diff --git a/EIPS/eip-758.md b/EIPS/eip-758.md index edb102c9478a8..4cdec48b36867 100644 --- a/EIPS/eip-758.md +++ b/EIPS/eip-758.md @@ -1,13 +1,12 @@ -## Preamble - - EIP: 758 - Title: Subscriptions and filters for transaction return data - Author: Jack Peterson - Type: Standard Track - Category: Interface - Status: Draft - Created: 2017-11-09 - +--- +EIP: 758 +Title: Subscriptions and filters for transaction return data +Author: Jack Peterson +Type: Standard Track +Category: Interface +Status: Draft +Created: 2017-11-09 +--- ## Simple Summary Provide a way for external callers to access the return data of functions executed during Ethereum transactions. diff --git a/EIPS/eip-779.md b/EIPS/eip-779.md index 08568a51d2ddf..0b90a5213603b 100644 --- a/EIPS/eip-779.md +++ b/EIPS/eip-779.md @@ -1,11 +1,11 @@ -## Preamble - - EIP: 779 - Title: Hardfork Info: DAO Fork - Author: Casey Detrio - Type: Informational - Status: Final - Created: 2017-11-26 +--- +EIP: 779 +Title: Hardfork Info: DAO Fork +Author: Casey Detrio +Type: Informational +Status: Final +Created: 2017-11-26 +--- ## Abstract @@ -22,7 +22,7 @@ See references [1] and [2] for the original, full specification. It is summarize At block 1880000, the following accounts are encoded into a list `L`: * The DAO (`0xbb9bc244d798123fde783fcc1c72d3bb8c189413`) * its extraBalance (`0x807640a13483f8ac783c557fcdf27be11ea4ac7a`) -* all children of the DAO creator (`0x4a574510c7014e4ae985403536074abe582adfc8`) +* all children of the DAO creator (`0x4a574510c7014e4ae985403536074abe582adfc8`) * and the extraBalance of each child At the beginning of block 1920000, all ether throughout all accounts in `L` will be transferred to a contract deployed at `0xbf4ed7b27f1d666546e30d74d50d173d20bca754`. The contract was created from the following Solidity code (compiler version `v0.3.5-2016-07-01-48238c9`): diff --git a/EIPS/eip-8.md b/EIPS/eip-8.md index 11e8efcfa4d05..58db0a0899f06 100644 --- a/EIPS/eip-8.md +++ b/EIPS/eip-8.md @@ -1,12 +1,12 @@ -### Title - - EIP: 8 - Title: devp2p Forward Compatibility Requirements for Homestead - Author: Felix Lange - Status: Final - Type: Standards Track - Layer: Networking - Created: 2015-12-18 +--- +EIP: 8 +Title: devp2p Forward Compatibility Requirements for Homestead +Author: Felix Lange +Status: Final +Type: Standards Track +Layer: Networking +Created: 2015-12-18 +--- ### Abstract diff --git a/EIPS/eip-801.md b/EIPS/eip-801.md index 0862d6916aeab..adf8e557e6563 100644 --- a/EIPS/eip-801.md +++ b/EIPS/eip-801.md @@ -1,13 +1,12 @@ -## Preamble - - EIP: 801 - Title: ERC-801 Canary Standard - Author: ligi - Type: Standard - Category: ERC - Status: Draft - Created: 2017-12-16 - +--- +EIP: 801 +Title: ERC-801 Canary Standard +Author: ligi +Type: Standard +Category: ERC +Status: Draft +Created: 2017-12-16 +--- ## Simple Summary diff --git a/EIPS/eip-831.md b/EIPS/eip-831.md index 4196a550eafc9..7cc0dde11ea2c 100644 --- a/EIPS/eip-831.md +++ b/EIPS/eip-831.md @@ -1,12 +1,12 @@ -## Preamble - - EIP: 831 - Title: URL Format for Ethereum - Author: ligi - Type: Standard Track - Category: ERC - Status: Draft - Created: 2018-01-15 +--- +EIP: 831 +Title: URL Format for Ethereum +Author: ligi +Type: Standard Track +Category: ERC +Status: Draft +Created: 2018-01-15 +--- ## Simple Summary diff --git a/EIPS/eip-858.md b/EIPS/eip-858.md index e111e4acb8bb6..4698879d9eaa9 100644 --- a/EIPS/eip-858.md +++ b/EIPS/eip-858.md @@ -1,12 +1,12 @@ -## Preamble - - EIP: 858 - Title: Reduce block reward - Author: Carl Larson - Type: Standard Track - Category: Core - Status: Draft - Created: 2018-01-29 +--- +EIP: 858 +Title: Reduce block reward +Author: Carl Larson +Type: Standard Track +Category: Core +Status: Draft +Created: 2018-01-29 +--- ## Simple Summary Reduce the block reward to 1 ETH. diff --git a/EIPS/eip-868.md b/EIPS/eip-868.md index 33fc329a3d616..e3f3ce08c726c 100644 --- a/EIPS/eip-868.md +++ b/EIPS/eip-868.md @@ -1,13 +1,13 @@ -# Preamble - - EIP: 868 - Title: Node Discovery v4 ENR Extension - Author: Felix Lange - Type: Standard Track - Category: Networking - Status: Draft - Created: 2018-02-02 - Requires: EIP-8, EIP-778 +--- +EIP: 868 +Title: Node Discovery v4 ENR Extension +Author: Felix Lange +Type: Standard Track +Category: Networking +Status: Draft +Created: 2018-02-02 +Requires: EIP-8, EIP-778 +--- # Abstract @@ -40,7 +40,7 @@ other existing packets, i.e. no reply should be sent if it refers to a time in t RLP: `[ requestHash, ENR ]` -This packet is the response to enrRequest. +This packet is the response to enrRequest. - `requestHash` is the hash of the entire enrRequest packet being replied to. - `ENR` is the node record. @@ -51,4 +51,3 @@ sent enrResponse. # Copyright Copyright and related rights waived via CC0. - From 937d80bcd145feabc40ce2a04e136e9f7e0cbe19 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Tue, 20 Mar 2018 15:11:35 +0000 Subject: [PATCH 0536/1085] First attempt at an autogenerated jekyll listing of EIPs --- .gitignore | 3 +++ 404.html | 24 ++++++++++++++++++++++++ Gemfile | 30 ++++++++++++++++++++++++++++++ _config.yml | 45 +++++++++++++++++++++++++++++++++++++++++++++ index.html | 23 +++++++++++++++++++++++ 5 files changed, 125 insertions(+) create mode 100644 .gitignore create mode 100644 404.html create mode 100644 Gemfile create mode 100644 _config.yml create mode 100644 index.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000..45c150536e5f3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +_site +.sass-cache +.jekyll-metadata diff --git a/404.html b/404.html new file mode 100644 index 0000000000000..c472b4ea0a781 --- /dev/null +++ b/404.html @@ -0,0 +1,24 @@ +--- +layout: default +--- + + + +
+

404

+ +

Page not found :(

+

The requested page could not be found.

+
diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000000000..6d3120f1ff776 --- /dev/null +++ b/Gemfile @@ -0,0 +1,30 @@ +source "https://rubygems.org" + +# Hello! This is where you manage which Jekyll version is used to run. +# When you want to use a different version, change it below, save the +# file and run `bundle install`. Run Jekyll with `bundle exec`, like so: +# +# bundle exec jekyll serve +# +# This will help ensure the proper Jekyll version is running. +# Happy Jekylling! +gem "jekyll", "~> 3.7.3" + +# This is the default theme for new Jekyll sites. You may change this to anything you like. +gem "minima", "~> 2.0" + +# If you want to use GitHub Pages, remove the "gem "jekyll"" above and +# uncomment the line below. To upgrade, run `bundle update github-pages`. +# gem "github-pages", group: :jekyll_plugins + +# If you have any plugins, put them here! +group :jekyll_plugins do + gem "jekyll-feed", "~> 0.6" +end + +# Windows does not include zoneinfo files, so bundle the tzinfo-data gem +gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby] + +# Performance-booster for watching directories on Windows +gem "wdm", "~> 0.1.0" if Gem.win_platform? + diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000000000..47ea44963ea09 --- /dev/null +++ b/_config.yml @@ -0,0 +1,45 @@ +# Welcome to Jekyll! +# +# This config file is meant for settings that affect your whole blog, values +# which you are expected to set up once and rarely edit after that. If you find +# yourself editing this file very often, consider using Jekyll's data files +# feature for the data you need to update frequently. +# +# For technical reasons, this file is *NOT* reloaded automatically when you use +# 'bundle exec jekyll serve'. If you change this file, please restart the server process. + +# Site settings +# These are used to personalize your new site. If you look in the HTML files, +# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on. +# You can create any custom variable you would like, and they will be accessible +# in the templates via {{ site.myvariable }}. +title: Ethereum EIPs by status +email: your-email@example.com +description: >- # this means to ignore newlines until "baseurl:" + Write an awesome description for your new site here. You can edit this + line in _config.yml. It will appear in your document head meta (for + Google search results) and in your feed.xml site description. +baseurl: "/EIPs" # the subpath of your site, e.g. /blog +url: "" # the base hostname & protocol for your site, e.g. http://example.com +twitter_username: jekyllrb +github_username: jekyll +header_pages: + - index.html + +# Build settings +markdown: kramdown +theme: minima +plugins: + - jekyll-feed + +# Exclude from processing. +# The following items will not be processed, by default. Create a custom list +# to override the default setting. +# exclude: +# - Gemfile +# - Gemfile.lock +# - node_modules +# - vendor/bundle/ +# - vendor/cache/ +# - vendor/gems/ +# - vendor/ruby/ diff --git a/index.html b/index.html new file mode 100644 index 0000000000000..073b7d5c728a9 --- /dev/null +++ b/index.html @@ -0,0 +1,23 @@ +--- +# You don't need to edit this file, it's empty on purpose. +# Edit theme's home layout instead if you wanna make some changes +# See: https://jekyllrb.com/docs/themes/#overriding-theme-defaults +layout: home +--- + +{% assign statuses = site.pages|map:"Status"|uniq %} +{% for status in statuses %} + {% if status != undefined %} +

{{status}}

+ + + + + {% for page in site.pages %} + {% if page.Status == status %} + + {% endif %} + {% endfor %} +
NumberTitleAuthorLayer
{{page.EIP}}{{page.Title}}{{page.Author}}{{page.Layer}}
+ {% endif %} +{% endfor %} From 01feced23ec3dd63fb61706f921c230291c54332 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Tue, 20 Mar 2018 15:25:15 +0000 Subject: [PATCH 0537/1085] Added links to EIP pages --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 073b7d5c728a9..74ed3363c69b4 100644 --- a/index.html +++ b/index.html @@ -15,7 +15,7 @@

{{status}}

{% for page in site.pages %} {% if page.Status == status %} - {{page.EIP}}{{page.Title}}{{page.Author}}{{page.Layer}} +
{{page.EIP}}{{page.Title}}{{page.Author}}{{page.Layer}} {% endif %} {% endfor %} From a4e8b8643d2b5756b1550f78e2957ffc0cfd8a5f Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Tue, 20 Mar 2018 15:54:04 +0000 Subject: [PATCH 0538/1085] Fix typos in EIPs --- EIPS/eip-211.md | 4 ++-- EIPS/eip-606.md | 2 +- EIPS/eip-607.md | 2 +- EIPS/eip-608.md | 2 +- EIPS/eip-609.md | 2 +- EIPS/eip-658.md | 2 +- EIPS/eip-695.md | 2 +- EIPS/eip-721.md | 2 +- EIPS/eip-779.md | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/EIPS/eip-211.md b/EIPS/eip-211.md index 9fa4c7f2ee83d..64f08ac140bc6 100644 --- a/EIPS/eip-211.md +++ b/EIPS/eip-211.md @@ -1,9 +1,9 @@ --- EIP: 211 -Title: New opcodes: RETURNDATASIZE and RETURNDATACOPY +Title: "New opcodes: RETURNDATASIZE and RETURNDATACOPY" Author: Christian Reitwiessner Type: Standard Track -Category Core +Category: Core Status: Final Created: 2017-02-13 Requires: diff --git a/EIPS/eip-606.md b/EIPS/eip-606.md index 71f17e844b0c1..d4b241487e42a 100644 --- a/EIPS/eip-606.md +++ b/EIPS/eip-606.md @@ -1,6 +1,6 @@ --- EIP: 606 -Title: Hardfork Meta: Homestead +Title: "Hardfork Meta: Homestead" Author: Alex Beregszaszi Type: Meta Status: Final diff --git a/EIPS/eip-607.md b/EIPS/eip-607.md index 3247bd260a1be..0459e36d0c4ea 100644 --- a/EIPS/eip-607.md +++ b/EIPS/eip-607.md @@ -1,6 +1,6 @@ --- EIP: 607 -Title: Hardfork Meta: Spurious Dragon +Title: "Hardfork Meta: Spurious Dragon" Author: Alex Beregszaszi Type: Meta Status: Final diff --git a/EIPS/eip-608.md b/EIPS/eip-608.md index 9cf88d993a922..9dc39965c22d0 100644 --- a/EIPS/eip-608.md +++ b/EIPS/eip-608.md @@ -1,6 +1,6 @@ --- EIP: 608 -Title: Hardfork Meta: Tangerine Whistle +Title: "Hardfork Meta: Tangerine Whistle" Author: Alex Beregszaszi Type: Meta Status: Final diff --git a/EIPS/eip-609.md b/EIPS/eip-609.md index d805dc596634b..8e8f7ea93815d 100644 --- a/EIPS/eip-609.md +++ b/EIPS/eip-609.md @@ -1,6 +1,6 @@ --- EIP: 609 -Title: Hardfork Meta: Byzantium +Title: "Hardfork Meta: Byzantium" Author: Alex Beregszaszi Type: Standard Track Category: Core diff --git a/EIPS/eip-658.md b/EIPS/eip-658.md index 782832dc4eaea..c48878540c142 100644 --- a/EIPS/eip-658.md +++ b/EIPS/eip-658.md @@ -3,7 +3,7 @@ EIP: 658 Title: Embedding transaction status code in receipts Author: Nick Johnson Type: Standard Track -Category Core +Category: Core Status: Final Created: 2017-06-30 Requires: 140 diff --git a/EIPS/eip-695.md b/EIPS/eip-695.md index 02ace809474d7..170fd3fd1d85b 100644 --- a/EIPS/eip-695.md +++ b/EIPS/eip-695.md @@ -1,7 +1,7 @@ --- EIP: 695 Title: Create `eth_chainId` method for JSON-RPC -Author: Isaac Ardis: isaac.ardis@gmail.com, Wei Tang: hi@that.world, [@tcz001](https://github.com/tcz001) +Author: Isaac Ardis Wei Tang , @tcz001 Type: Standard Track Category: Interface Status: Draft diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 55626a1f986a4..3c416381cf1ef 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -3,7 +3,7 @@ EIP: 721 Title: ERC-721 Non-Fungible Token Standard Author: William Entriken , Dieter Shirley , Jacob Evans , Nastassia Sachs Type: Standard -Category ERC +Category: ERC Status: Draft Created: 2018-01-24 Requires: ERC-165 diff --git a/EIPS/eip-779.md b/EIPS/eip-779.md index 0b90a5213603b..e5a62093763c7 100644 --- a/EIPS/eip-779.md +++ b/EIPS/eip-779.md @@ -1,6 +1,6 @@ --- EIP: 779 -Title: Hardfork Info: DAO Fork +Title: "Hardfork Info: DAO Fork" Author: Casey Detrio Type: Informational Status: Final From b5f78310492e86860b77825acf3e1ea9ef59352a Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Tue, 20 Mar 2018 16:08:01 +0000 Subject: [PATCH 0539/1085] Sort EIPs by number --- index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 74ed3363c69b4..04985fa397017 100644 --- a/index.html +++ b/index.html @@ -6,6 +6,7 @@ --- {% assign statuses = site.pages|map:"Status"|uniq %} +{% assign pages = site.pages|sort:"EIP" %} {% for status in statuses %} {% if status != undefined %}

{{status}}

@@ -13,7 +14,7 @@

{{status}}

NumberTitleAuthorLayer - {% for page in site.pages %} + {% for page in pages %} {% if page.Status == status %} {{page.EIP}}{{page.Title}}{{page.Author}}{{page.Layer}} {% endif %} From 806ccbd6a3f05aae4e9d6715bd2079145d91d0ca Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Tue, 20 Mar 2018 16:10:22 +0000 Subject: [PATCH 0540/1085] Escape table entries correctly --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 04985fa397017..d168acd02e716 100644 --- a/index.html +++ b/index.html @@ -16,7 +16,7 @@

{{status}}

{% for page in pages %} {% if page.Status == status %} - {{page.EIP}}{{page.Title}}{{page.Author}}{{page.Layer}} + {{page.EIP}}{{page.Title|xml_escape}}{{page.Author|xml_escape}}{{page.Layer|xml_escape}} {% endif %} {% endfor %} From 73c538d2552aab999c348b4a9b83b5d4294d3cac Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 12:37:47 +0000 Subject: [PATCH 0541/1085] Use github pages gem --- Gemfile | 4 +- Gemfile.lock | 247 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 249 insertions(+), 2 deletions(-) create mode 100644 Gemfile.lock diff --git a/Gemfile b/Gemfile index 6d3120f1ff776..b566d37debead 100644 --- a/Gemfile +++ b/Gemfile @@ -8,7 +8,7 @@ source "https://rubygems.org" # # This will help ensure the proper Jekyll version is running. # Happy Jekylling! -gem "jekyll", "~> 3.7.3" +gem "jekyll", "~> 3.6.2" # This is the default theme for new Jekyll sites. You may change this to anything you like. gem "minima", "~> 2.0" @@ -20,6 +20,7 @@ gem "minima", "~> 2.0" # If you have any plugins, put them here! group :jekyll_plugins do gem "jekyll-feed", "~> 0.6" + gem "github-pages" end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem @@ -27,4 +28,3 @@ gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby] # Performance-booster for watching directories on Windows gem "wdm", "~> 0.1.0" if Gem.win_platform? - diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000000000..3461dd09e17ab --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,247 @@ +GEM + remote: https://rubygems.org/ + specs: + activesupport (4.2.9) + i18n (~> 0.7) + minitest (~> 5.1) + thread_safe (~> 0.3, >= 0.3.4) + tzinfo (~> 1.1) + addressable (2.5.2) + public_suffix (>= 2.0.2, < 4.0) + coffee-script (2.4.1) + coffee-script-source + execjs + coffee-script-source (1.11.1) + colorator (1.1.0) + commonmarker (0.17.9) + ruby-enum (~> 0.5) + concurrent-ruby (1.0.5) + ethon (0.11.0) + ffi (>= 1.3.0) + execjs (2.7.0) + faraday (0.14.0) + multipart-post (>= 1.2, < 3) + ffi (1.9.23) + forwardable-extended (2.6.0) + gemoji (3.0.0) + github-pages (179) + activesupport (= 4.2.9) + github-pages-health-check (= 1.4.0) + jekyll (= 3.6.2) + jekyll-avatar (= 0.5.0) + jekyll-coffeescript (= 1.1.1) + jekyll-commonmark-ghpages (= 0.1.5) + jekyll-default-layout (= 0.1.4) + jekyll-feed (= 0.9.3) + jekyll-gist (= 1.5.0) + jekyll-github-metadata (= 2.9.4) + jekyll-mentions (= 1.3.0) + jekyll-optional-front-matter (= 0.3.0) + jekyll-paginate (= 1.1.0) + jekyll-readme-index (= 0.2.0) + jekyll-redirect-from (= 0.13.0) + jekyll-relative-links (= 0.5.3) + jekyll-remote-theme (= 0.2.3) + jekyll-sass-converter (= 1.5.2) + jekyll-seo-tag (= 2.4.0) + jekyll-sitemap (= 1.2.0) + jekyll-swiss (= 0.4.0) + jekyll-theme-architect (= 0.1.0) + jekyll-theme-cayman (= 0.1.0) + jekyll-theme-dinky (= 0.1.0) + jekyll-theme-hacker (= 0.1.0) + jekyll-theme-leap-day (= 0.1.0) + jekyll-theme-merlot (= 0.1.0) + jekyll-theme-midnight (= 0.1.0) + jekyll-theme-minimal (= 0.1.0) + jekyll-theme-modernist (= 0.1.0) + jekyll-theme-primer (= 0.5.2) + jekyll-theme-slate (= 0.1.0) + jekyll-theme-tactile (= 0.1.0) + jekyll-theme-time-machine (= 0.1.0) + jekyll-titles-from-headings (= 0.5.1) + jemoji (= 0.9.0) + kramdown (= 1.16.2) + liquid (= 4.0.0) + listen (= 3.1.5) + mercenary (~> 0.3) + minima (= 2.4.0) + nokogiri (>= 1.8.1, < 2.0) + rouge (= 2.2.1) + terminal-table (~> 1.4) + github-pages-health-check (1.4.0) + addressable (~> 2.3) + net-dns (~> 0.8) + octokit (~> 4.0) + public_suffix (~> 2.0) + typhoeus (~> 1.3) + html-pipeline (2.7.1) + activesupport (>= 2) + nokogiri (>= 1.4) + i18n (0.9.5) + concurrent-ruby (~> 1.0) + jekyll (3.6.2) + addressable (~> 2.4) + colorator (~> 1.0) + jekyll-sass-converter (~> 1.0) + jekyll-watch (~> 1.1) + kramdown (~> 1.14) + liquid (~> 4.0) + mercenary (~> 0.3.3) + pathutil (~> 0.9) + rouge (>= 1.7, < 3) + safe_yaml (~> 1.0) + jekyll-avatar (0.5.0) + jekyll (~> 3.0) + jekyll-coffeescript (1.1.1) + coffee-script (~> 2.2) + coffee-script-source (~> 1.11.1) + jekyll-commonmark (1.1.0) + commonmarker (~> 0.14) + jekyll (>= 3.0, < 4.0) + jekyll-commonmark-ghpages (0.1.5) + commonmarker (~> 0.17.6) + jekyll-commonmark (~> 1) + rouge (~> 2) + jekyll-default-layout (0.1.4) + jekyll (~> 3.0) + jekyll-feed (0.9.3) + jekyll (~> 3.3) + jekyll-gist (1.5.0) + octokit (~> 4.2) + jekyll-github-metadata (2.9.4) + jekyll (~> 3.1) + octokit (~> 4.0, != 4.4.0) + jekyll-mentions (1.3.0) + activesupport (~> 4.0) + html-pipeline (~> 2.3) + jekyll (~> 3.0) + jekyll-optional-front-matter (0.3.0) + jekyll (~> 3.0) + jekyll-paginate (1.1.0) + jekyll-readme-index (0.2.0) + jekyll (~> 3.0) + jekyll-redirect-from (0.13.0) + jekyll (~> 3.3) + jekyll-relative-links (0.5.3) + jekyll (~> 3.3) + jekyll-remote-theme (0.2.3) + jekyll (~> 3.5) + rubyzip (>= 1.2.1, < 3.0) + typhoeus (>= 0.7, < 2.0) + jekyll-sass-converter (1.5.2) + sass (~> 3.4) + jekyll-seo-tag (2.4.0) + jekyll (~> 3.3) + jekyll-sitemap (1.2.0) + jekyll (~> 3.3) + jekyll-swiss (0.4.0) + jekyll-theme-architect (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-cayman (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-dinky (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-hacker (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-leap-day (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-merlot (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-midnight (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-minimal (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-modernist (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-primer (0.5.2) + jekyll (~> 3.5) + jekyll-github-metadata (~> 2.9) + jekyll-seo-tag (~> 2.2) + jekyll-theme-slate (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-tactile (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-theme-time-machine (0.1.0) + jekyll (~> 3.5) + jekyll-seo-tag (~> 2.0) + jekyll-titles-from-headings (0.5.1) + jekyll (~> 3.3) + jekyll-watch (1.5.1) + listen (~> 3.0) + jemoji (0.9.0) + activesupport (~> 4.0, >= 4.2.9) + gemoji (~> 3.0) + html-pipeline (~> 2.2) + jekyll (~> 3.0) + kramdown (1.16.2) + liquid (4.0.0) + listen (3.1.5) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + ruby_dep (~> 1.2) + mercenary (0.3.6) + mini_portile2 (2.3.0) + minima (2.4.0) + jekyll (~> 3.5) + jekyll-feed (~> 0.9) + jekyll-seo-tag (~> 2.1) + minitest (5.11.3) + multipart-post (2.0.0) + net-dns (0.8.0) + nokogiri (1.8.2) + mini_portile2 (~> 2.3.0) + octokit (4.8.0) + sawyer (~> 0.8.0, >= 0.5.3) + pathutil (0.16.1) + forwardable-extended (~> 2.6) + public_suffix (2.0.5) + rb-fsevent (0.10.3) + rb-inotify (0.9.10) + ffi (>= 0.5.0, < 2) + rouge (2.2.1) + ruby-enum (0.7.2) + i18n + ruby_dep (1.5.0) + rubyzip (1.2.1) + safe_yaml (1.0.4) + sass (3.5.5) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + sawyer (0.8.1) + addressable (>= 2.3.5, < 2.6) + faraday (~> 0.8, < 1.0) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + thread_safe (0.3.6) + typhoeus (1.3.0) + ethon (>= 0.9.0) + tzinfo (1.2.5) + thread_safe (~> 0.1) + unicode-display_width (1.3.0) + +PLATFORMS + ruby + +DEPENDENCIES + github-pages + jekyll (~> 3.6.2) + jekyll-feed (~> 0.6) + minima (~> 2.0) + tzinfo-data + +BUNDLED WITH + 1.16.1 From 04e50bfcf5a1bbbe548f1849728dcbbc1c6fa308 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 12:39:25 +0000 Subject: [PATCH 0542/1085] Experiment with resetting base path --- _config.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/_config.yml b/_config.yml index 47ea44963ea09..3f0fd40c9b5eb 100644 --- a/_config.yml +++ b/_config.yml @@ -14,15 +14,14 @@ # You can create any custom variable you would like, and they will be accessible # in the templates via {{ site.myvariable }}. title: Ethereum EIPs by status -email: your-email@example.com +email: nick@ethereum.org description: >- # this means to ignore newlines until "baseurl:" Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description. -baseurl: "/EIPs" # the subpath of your site, e.g. /blog url: "" # the base hostname & protocol for your site, e.g. http://example.com -twitter_username: jekyllrb -github_username: jekyll +twitter_username: ethereum +github_username: ethereum header_pages: - index.html From e3e2797901e4f3a9e744916c8d97d910a321d26f Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 12:46:05 +0000 Subject: [PATCH 0543/1085] Use default template for EIPs --- _config.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/_config.yml b/_config.yml index 3f0fd40c9b5eb..0ad1ea75ec16f 100644 --- a/_config.yml +++ b/_config.yml @@ -31,6 +31,13 @@ theme: minima plugins: - jekyll-feed +defaults: + - + scope: + path: "EIPS" + values: + layout: "default" + # Exclude from processing. # The following items will not be processed, by default. Create a custom list # to override the default setting. From 4938bcbf911f1175ccf0a28aaaf7154b7b796105 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 12:51:05 +0000 Subject: [PATCH 0544/1085] Lowercase all frontmatter keys --- EIPS/eip-1.md | 12 ++++++------ EIPS/eip-100.md | 14 +++++++------- EIPS/eip-101.md | 12 ++++++------ EIPS/eip-107.md | 14 +++++++------- EIPS/eip-137.md | 14 +++++++------- EIPS/eip-140.md | 14 +++++++------- EIPS/eip-141.md | 14 +++++++------- EIPS/eip-145.md | 14 +++++++------- EIPS/eip-150.md | 14 +++++++------- EIPS/eip-155.md | 14 +++++++------- EIPS/eip-158.md | 14 +++++++------- EIPS/eip-160.md | 14 +++++++------- EIPS/eip-161.md | 14 +++++++------- EIPS/eip-162.md | 14 +++++++------- EIPS/eip-165.md | 14 +++++++------- EIPS/eip-170.md | 14 +++++++------- EIPS/eip-181.md | 14 +++++++------- EIPS/eip-190.md | 12 ++++++------ EIPS/eip-196.md | 14 +++++++------- EIPS/eip-197.md | 14 +++++++------- EIPS/eip-2.md | 14 +++++++------- EIPS/eip-20.md | 14 +++++++------- EIPS/eip-211.md | 14 +++++++------- EIPS/eip-214.md | 14 +++++++------- EIPS/eip-234.md | 14 +++++++------- EIPS/eip-3.md | 14 +++++++------- EIPS/eip-4.md | 14 +++++++------- EIPS/eip-5.md | 14 +++++++------- EIPS/eip-55.md | 14 +++++++------- EIPS/eip-6.md | 14 +++++++------- EIPS/eip-606.md | 12 ++++++------ EIPS/eip-607.md | 12 ++++++------ EIPS/eip-608.md | 12 ++++++------ EIPS/eip-609.md | 14 +++++++------- EIPS/eip-615.md | 12 ++++++------ EIPS/eip-616.md | 14 +++++++------- EIPS/eip-649.md | 12 ++++++------ EIPS/eip-658.md | 14 +++++++------- EIPS/eip-681.md | 14 +++++++------- EIPS/eip-695.md | 14 +++++++------- EIPS/eip-7.md | 12 ++++++------ EIPS/eip-706.md | 14 +++++++------- EIPS/eip-721.md | 14 +++++++------- EIPS/eip-758.md | 14 +++++++------- EIPS/eip-779.md | 12 ++++++------ EIPS/eip-8.md | 14 +++++++------- EIPS/eip-801.md | 14 +++++++------- EIPS/eip-831.md | 14 +++++++------- EIPS/eip-858.md | 14 +++++++------- EIPS/eip-868.md | 14 +++++++------- index.html | 8 ++++---- 51 files changed, 344 insertions(+), 344 deletions(-) diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index 8b2fd892e4170..b997aec1b48cc 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -1,10 +1,10 @@ --- -EIP: 1 -Title: EIP Purpose and Guidelines -Status: Active -Type: Meta -Author: Martin Becze , Hudson Jameson -Created: 2015-10-27, 2017-02-01 +eip: 1 +title: EIP Purpose and Guidelines +status: Active +type: Meta +author: Martin Becze , Hudson Jameson +created: 2015-10-27, 2017-02-01 --- What is an EIP? diff --git a/EIPS/eip-100.md b/EIPS/eip-100.md index 61961def0a6cd..3ea24a7f62ee5 100644 --- a/EIPS/eip-100.md +++ b/EIPS/eip-100.md @@ -1,11 +1,11 @@ --- -EIP: 100 -Title: Change difficulty adjustment to target mean block time including uncles -Author: Vitalik Buterin -Type: Standard Track -Category: Core -Status: Final -Created: 2016-04-28 +eip: 100 +title: Change difficulty adjustment to target mean block time including uncles +author: Vitalik Buterin +type: Standard Track +category: Core +status: Final +created: 2016-04-28 --- ### Specification diff --git a/EIPS/eip-101.md b/EIPS/eip-101.md index 4ad6cff4bb746..47aa1591da111 100644 --- a/EIPS/eip-101.md +++ b/EIPS/eip-101.md @@ -1,10 +1,10 @@ --- -EIP: 101 -Title: Serenity Currency and Crypto Abstraction -Author: Vitalik Buterin -Status: Active -Type: Serenity feature -Created: 2015-11-15 +eip: 101 +title: Serenity Currency and Crypto Abstraction +author: Vitalik Buterin +status: Active +type: Serenity feature +created: 2015-11-15 --- ### Specification diff --git a/EIPS/eip-107.md b/EIPS/eip-107.md index 5e3ab179297a3..d9a1beff3dc90 100644 --- a/EIPS/eip-107.md +++ b/EIPS/eip-107.md @@ -1,11 +1,11 @@ --- -EIP: 107 -Title: safe "eth_sendTransaction" authorization via html popup -Author: Ronan Sandford -Created: 2016-06-05 -Status: Draft -Type: Standard -Category: Interface +eip: 107 +title: safe "eth_sendTransaction" authorization via html popup +author: Ronan Sandford +created: 2016-06-05 +status: Draft +type: Standard +category: Interface --- Abstract diff --git a/EIPS/eip-137.md b/EIPS/eip-137.md index e81ab076504d1..0dec034013173 100644 --- a/EIPS/eip-137.md +++ b/EIPS/eip-137.md @@ -1,11 +1,11 @@ --- -EIP: 137 -Title: Ethereum Domain Name Service - Specification -Author: Nick Johnson -Status: Final -Type: Standards Track -Category: ERC -Created: 2016-04-04 +eip: 137 +title: Ethereum Domain Name Service - Specification +author: Nick Johnson +status: Final +type: Standards Track +category: ERC +created: 2016-04-04 --- # Abstract diff --git a/EIPS/eip-140.md b/EIPS/eip-140.md index 964870323d1ff..7c2af3952e13a 100644 --- a/EIPS/eip-140.md +++ b/EIPS/eip-140.md @@ -1,11 +1,11 @@ --- -EIP: 140 -Title: REVERT instruction -Author: Alex Beregszaszi, Nikolai Mushegian (nikolai@nexusdev.us) -Type: Standard Track -Category: Core -Status: Final -Created: 2017-02-06 +eip: 140 +title: REVERT instruction +author: Alex Beregszaszi, Nikolai Mushegian (nikolai@nexusdev.us) +type: Standard Track +category: Core +status: Final +created: 2017-02-06 --- ## Simple Summary diff --git a/EIPS/eip-141.md b/EIPS/eip-141.md index 7794ff3e9a253..2cc57d11bf4d4 100644 --- a/EIPS/eip-141.md +++ b/EIPS/eip-141.md @@ -1,11 +1,11 @@ --- -EIP: 141 -Title: Designated invalid EVM instruction -Author: Alex Beregszaszi -Type: Standard Track -Category: Core -Status: Final -Created: 2017-02-09 +eip: 141 +title: Designated invalid EVM instruction +author: Alex Beregszaszi +type: Standard Track +category: Core +status: Final +created: 2017-02-09 --- ## Abstract diff --git a/EIPS/eip-145.md b/EIPS/eip-145.md index 20849c3e2d28f..15e41ebc33047 100644 --- a/EIPS/eip-145.md +++ b/EIPS/eip-145.md @@ -1,11 +1,11 @@ --- -EIP: 145 -Title: Bitwise shifting instructions in EVM -Author: Alex Beregszaszi, Paweł Bylica -Type: Standard Track -Category: Core -Status: Final -Created: 2017-02-13 +eip: 145 +title: Bitwise shifting instructions in EVM +author: Alex Beregszaszi, Paweł Bylica +type: Standard Track +category: Core +status: Final +created: 2017-02-13 --- ## Simple Summary diff --git a/EIPS/eip-150.md b/EIPS/eip-150.md index a6414f29e0f42..dfac0de091bcc 100644 --- a/EIPS/eip-150.md +++ b/EIPS/eip-150.md @@ -1,11 +1,11 @@ --- -EIP: 150 -Title: Gas cost changes for IO-heavy operations -Author: Vitalik Buterin -Type: Standard Track -Category: Core -Status: Final -Created: 2016-09-24 +eip: 150 +title: Gas cost changes for IO-heavy operations +author: Vitalik Buterin +type: Standard Track +category: Core +status: Final +created: 2016-09-24 --- ### Meta reference diff --git a/EIPS/eip-155.md b/EIPS/eip-155.md index 28bfa32268efb..e2195cb9d14fd 100644 --- a/EIPS/eip-155.md +++ b/EIPS/eip-155.md @@ -1,11 +1,11 @@ --- -EIP: 155 -Title: Simple replay attack protection -Author: Vitalik Buterin -Type: Standard Track -Category: Core -Status: Final -Created: 2016-10-14 +eip: 155 +title: Simple replay attack protection +author: Vitalik Buterin +type: Standard Track +category: Core +status: Final +created: 2016-10-14 --- ### Hard fork diff --git a/EIPS/eip-158.md b/EIPS/eip-158.md index a7bd99a7db324..5b1f13c3829eb 100644 --- a/EIPS/eip-158.md +++ b/EIPS/eip-158.md @@ -1,11 +1,11 @@ --- -EIP: 158 -Title: State clearing -Author: Vitalik Buterin -Type: Standard Track -Category: Core -Status: Superseded -Created: 2016-10-16 +eip: 158 +title: State clearing +author: Vitalik Buterin +type: Standard Track +category: Core +status: Superseded +created: 2016-10-16 Superseded-By: 161 --- diff --git a/EIPS/eip-160.md b/EIPS/eip-160.md index 68892eb65dfbb..9fb35d71b2887 100644 --- a/EIPS/eip-160.md +++ b/EIPS/eip-160.md @@ -1,11 +1,11 @@ --- -EIP: 160 -Title: EXP cost increase -Author: Vitalik Buterin -Type: Standard Track -Category: Core -Status: Final -Created: 2016-10-20 +eip: 160 +title: EXP cost increase +author: Vitalik Buterin +type: Standard Track +category: Core +status: Final +created: 2016-10-20 --- ### Hard fork diff --git a/EIPS/eip-161.md b/EIPS/eip-161.md index d8f7ca959bb38..2be4c6658033f 100644 --- a/EIPS/eip-161.md +++ b/EIPS/eip-161.md @@ -1,11 +1,11 @@ --- -EIP: 161 -Title: State trie clearing (invariant-preserving alternative) -Author: Gavin Wood -Type: Standard Track -Category: Core -Status: Final -Created: 2016-10-24 +eip: 161 +title: State trie clearing (invariant-preserving alternative) +author: Gavin Wood +type: Standard Track +category: Core +status: Final +created: 2016-10-24 --- ### Hard fork diff --git a/EIPS/eip-162.md b/EIPS/eip-162.md index 03c57539f40d3..2edda6a9bcf6f 100644 --- a/EIPS/eip-162.md +++ b/EIPS/eip-162.md @@ -1,11 +1,11 @@ --- -EIP: 162 -Title: Initial ENS Hash Registrar -Author: Maurelian and Nick Johnson -Status: Final -Type: Standards Track -Category: ERC -Created: 2016-10-25 +eip: 162 +title: Initial ENS Hash Registrar +author: Maurelian and Nick Johnson +status: Final +type: Standards Track +category: ERC +created: 2016-10-25 --- ## Contents diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index 98b1962ebbea3..0b3f8574c09cd 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -1,11 +1,11 @@ --- -EIP: 165 -Title: ERC-165 Standard Interface Detection -Author: Christian Reitwießner , Nick Johnson , Fabian Vogelsteller , Jordi Baylina , Konrad Feldmeier , William Entriken -Type: Standard Track -Category: ERC -Status: Draft -Created: 2018-01-23 +eip: 165 +title: ERC-165 Standard Interface Detection +author: Christian Reitwießner , Nick Johnson , Fabian Vogelsteller , Jordi Baylina , Konrad Feldmeier , William Entriken +type: Standard Track +category: ERC +status: Draft +created: 2018-01-23 --- ## Simple Summary diff --git a/EIPS/eip-170.md b/EIPS/eip-170.md index 4ef64d012d204..feda849b23170 100644 --- a/EIPS/eip-170.md +++ b/EIPS/eip-170.md @@ -1,11 +1,11 @@ --- -EIP: 170 -Title: Contract code size limit -Author: Vitalik Buterin -Type: Standard Track -Category: Core -Status: Final -Created: 2016-11-04 +eip: 170 +title: Contract code size limit +author: Vitalik Buterin +type: Standard Track +category: Core +status: Final +created: 2016-11-04 --- ### Hard fork diff --git a/EIPS/eip-181.md b/EIPS/eip-181.md index 2615f6dbc3c7d..a68f8120f397b 100644 --- a/EIPS/eip-181.md +++ b/EIPS/eip-181.md @@ -1,11 +1,11 @@ --- -EIP: 181 -Title: ENS support for reverse resolution of Ethereum addresses -Author: Nick Johnson -Status: Final -Type: Standard Track -Category: ERC -Created: 2016-12-01 +eip: 181 +title: ENS support for reverse resolution of Ethereum addresses +author: Nick Johnson +status: Final +type: Standard Track +category: ERC +created: 2016-12-01 --- # Abstract diff --git a/EIPS/eip-190.md b/EIPS/eip-190.md index 07e51f97eedbf..dd0da07e812e8 100644 --- a/EIPS/eip-190.md +++ b/EIPS/eip-190.md @@ -1,11 +1,11 @@ --- -EIP: 190 -Title: Ethereum Smart Contract Packaging Standard +eip: 190 +title: Ethereum Smart Contract Packaging Standard Authors: Piper Merriam, Tim Coulter, Denis Erfurt (mhhf), RJ Catalano (VoR0220), Iuri Matias (iurimatias) -Status: Final -Type: Standards Track -Category: ERC -Created: 2017-01-10 +status: Final +type: Standards Track +category: ERC +created: 2017-01-10 --- # Abstract diff --git a/EIPS/eip-196.md b/EIPS/eip-196.md index f9e045d48b969..7feaf17261603 100644 --- a/EIPS/eip-196.md +++ b/EIPS/eip-196.md @@ -1,12 +1,12 @@ --- -EIP: 196 -Title: Precompiled contracts for addition and scalar multiplication +eip: 196 +title: Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 -Author: Christian Reitwiessner -Type: Standard Track -Category: Core -Status: Final -Created: 2017-02-02 +author: Christian Reitwiessner +type: Standard Track +category: Core +status: Final +created: 2017-02-02 --- ## Simple Summary diff --git a/EIPS/eip-197.md b/EIPS/eip-197.md index df993abe69d5e..827e5385d20a0 100644 --- a/EIPS/eip-197.md +++ b/EIPS/eip-197.md @@ -1,12 +1,12 @@ --- -EIP: 197 -Title: Precompiled contracts for optimal ate pairing check +eip: 197 +title: Precompiled contracts for optimal ate pairing check on the elliptic curve alt_bn128 -Author: Vitalik Buterin , Christian Reitwiessner -Type: Standard Track -Category: Core -Status: Final -Created: 2017-02-06 +author: Vitalik Buterin , Christian Reitwiessner +type: Standard Track +category: Core +status: Final +created: 2017-02-06 --- ## Simple Summary diff --git a/EIPS/eip-2.md b/EIPS/eip-2.md index 0db000e4eb4ab..673c8ab9415e4 100644 --- a/EIPS/eip-2.md +++ b/EIPS/eip-2.md @@ -1,11 +1,11 @@ --- -EIP: 2 -Title: Homestead Hard-fork Changes -Author: Vitalik Buterin -Status: Final -Type: Standard Track -Category: Core -Created: 2015-11-15 +eip: 2 +title: Homestead Hard-fork Changes +author: Vitalik Buterin +status: Final +type: Standard Track +category: Core +created: 2015-11-15 --- ### Meta reference diff --git a/EIPS/eip-20.md b/EIPS/eip-20.md index dba043f9223ed..494c1a437edde 100644 --- a/EIPS/eip-20.md +++ b/EIPS/eip-20.md @@ -1,11 +1,11 @@ --- -EIP: 20 -Title: ERC-20 Token Standard -Author: Fabian Vogelsteller , Vitalik Buterin -Type: Standard -Category: ERC -Status: Accepted -Created: 2015-11-19 +eip: 20 +title: ERC-20 Token Standard +author: Fabian Vogelsteller , Vitalik Buterin +type: Standard +category: ERC +status: Accepted +created: 2015-11-19 --- ## Simple Summary diff --git a/EIPS/eip-211.md b/EIPS/eip-211.md index 64f08ac140bc6..c2daee4b475b2 100644 --- a/EIPS/eip-211.md +++ b/EIPS/eip-211.md @@ -1,11 +1,11 @@ --- -EIP: 211 -Title: "New opcodes: RETURNDATASIZE and RETURNDATACOPY" -Author: Christian Reitwiessner -Type: Standard Track -Category: Core -Status: Final -Created: 2017-02-13 +eip: 211 +title: "New opcodes: RETURNDATASIZE and RETURNDATACOPY" +author: Christian Reitwiessner +type: Standard Track +category: Core +status: Final +created: 2017-02-13 Requires: Replaces: 5/8 --- diff --git a/EIPS/eip-214.md b/EIPS/eip-214.md index cbdf7a3094eef..9b20d39fdde64 100644 --- a/EIPS/eip-214.md +++ b/EIPS/eip-214.md @@ -1,11 +1,11 @@ --- -EIP: 214 -Title: New opcode STATICCALL -Author: Vitalik Buterin , Christian Reitwiessner ; -Type: Standard Track -Category: Core -Status: Final -Created: 2017-02-13 +eip: 214 +title: New opcode STATICCALL +author: Vitalik Buterin , Christian Reitwiessner ; +type: Standard Track +category: Core +status: Final +created: 2017-02-13 --- ## Simple Summary diff --git a/EIPS/eip-234.md b/EIPS/eip-234.md index de1752bbd466b..6753f700aae98 100644 --- a/EIPS/eip-234.md +++ b/EIPS/eip-234.md @@ -1,11 +1,11 @@ --- -EIP: 234 -Title: Add `blockHash` to JSON-RPC filter options. -Author: Micah Zoltu -Type: Standard Track -Category: Interface -Status: Draft -Created: 2017-03-24 +eip: 234 +title: Add `blockHash` to JSON-RPC filter options. +author: Micah Zoltu +type: Standard Track +category: Interface +status: Draft +created: 2017-03-24 --- ## Simple Summary diff --git a/EIPS/eip-3.md b/EIPS/eip-3.md index de9ae751d0bdb..5d405f09870eb 100644 --- a/EIPS/eip-3.md +++ b/EIPS/eip-3.md @@ -1,11 +1,11 @@ --- -EIP: 3 -Title: Addition of CALLDEPTH opcode -Author: Martin Holst Swende -Status: Draft -Type: Standards Track -Layer: Consensus (hard-fork) -Created: 2015-11-19 +eip: 3 +title: Addition of CALLDEPTH opcode +author: Martin Holst Swende +status: Draft +type: Standards Track +layer: Consensus (hard-fork) +created: 2015-11-19 --- # Abstract diff --git a/EIPS/eip-4.md b/EIPS/eip-4.md index 9793b26efb8f8..52e310dbcb7d6 100644 --- a/EIPS/eip-4.md +++ b/EIPS/eip-4.md @@ -1,11 +1,11 @@ --- -EIP: 4 -Layer: Process -Title: EIP Classification -Author: Joseph Chow -Status: Draft -Type: Process -Created: 2015-11-17 +eip: 4 +layer: Process +title: EIP Classification +author: Joseph Chow +status: Draft +type: Process +created: 2015-11-17 --- # Abstract diff --git a/EIPS/eip-5.md b/EIPS/eip-5.md index 9214572a82384..6ec9bff9f8c0b 100644 --- a/EIPS/eip-5.md +++ b/EIPS/eip-5.md @@ -1,11 +1,11 @@ --- -EIP: 5 -Title: Gas Usage for `RETURN` and `CALL*` -Author: Christian Reitwiessner -Status: Draft -Type: Standards Track -Layer: Consensus (hard-fork) -Created: 2015-11-22 +eip: 5 +title: Gas Usage for `RETURN` and `CALL*` +author: Christian Reitwiessner +status: Draft +type: Standards Track +layer: Consensus (hard-fork) +created: 2015-11-22 --- ### Abstract diff --git a/EIPS/eip-55.md b/EIPS/eip-55.md index 75cf21111e327..b610fc77421bc 100644 --- a/EIPS/eip-55.md +++ b/EIPS/eip-55.md @@ -1,11 +1,11 @@ --- -EIP: 55 -Title: Mixed-case checksum address encoding -Author: Vitalik Buterin -Type: Standard Track -Category: ERC -Status: Accepted -Created: 2016-01-14 +eip: 55 +title: Mixed-case checksum address encoding +author: Vitalik Buterin +type: Standard Track +category: ERC +status: Accepted +created: 2016-01-14 --- # Specification diff --git a/EIPS/eip-6.md b/EIPS/eip-6.md index d13bbc0f6e8e0..f42032b5b07b6 100644 --- a/EIPS/eip-6.md +++ b/EIPS/eip-6.md @@ -1,11 +1,11 @@ --- -EIP: 6 -Title: Renaming SUICIDE opcode -Author: Hudson Jameson -Status: Final -Type: Standards Track -Layer: Applications -Created: 2015-11-22 +eip: 6 +title: Renaming SUICIDE opcode +author: Hudson Jameson +status: Final +type: Standards Track +layer: Applications +created: 2015-11-22 --- ### Abstract diff --git a/EIPS/eip-606.md b/EIPS/eip-606.md index d4b241487e42a..1730738d45920 100644 --- a/EIPS/eip-606.md +++ b/EIPS/eip-606.md @@ -1,10 +1,10 @@ --- -EIP: 606 -Title: "Hardfork Meta: Homestead" -Author: Alex Beregszaszi -Type: Meta -Status: Final -Created: 2017-04-23 +eip: 606 +title: "Hardfork Meta: Homestead" +author: Alex Beregszaszi +type: Meta +status: Final +created: 2017-04-23 Requires: 2, 7 --- diff --git a/EIPS/eip-607.md b/EIPS/eip-607.md index 0459e36d0c4ea..9e713c0ff7f9a 100644 --- a/EIPS/eip-607.md +++ b/EIPS/eip-607.md @@ -1,10 +1,10 @@ --- -EIP: 607 -Title: "Hardfork Meta: Spurious Dragon" -Author: Alex Beregszaszi -Type: Meta -Status: Final -Created: 2017-04-23 +eip: 607 +title: "Hardfork Meta: Spurious Dragon" +author: Alex Beregszaszi +type: Meta +status: Final +created: 2017-04-23 Requires: 155, 160, 161, 170 --- diff --git a/EIPS/eip-608.md b/EIPS/eip-608.md index 9dc39965c22d0..8e5eb6218e452 100644 --- a/EIPS/eip-608.md +++ b/EIPS/eip-608.md @@ -1,10 +1,10 @@ --- -EIP: 608 -Title: "Hardfork Meta: Tangerine Whistle" -Author: Alex Beregszaszi -Type: Meta -Status: Final -Created: 2017-04-23 +eip: 608 +title: "Hardfork Meta: Tangerine Whistle" +author: Alex Beregszaszi +type: Meta +status: Final +created: 2017-04-23 Requires: 150 --- diff --git a/EIPS/eip-609.md b/EIPS/eip-609.md index 8e8f7ea93815d..23fa8ab3595d0 100644 --- a/EIPS/eip-609.md +++ b/EIPS/eip-609.md @@ -1,11 +1,11 @@ --- -EIP: 609 -Title: "Hardfork Meta: Byzantium" -Author: Alex Beregszaszi -Type: Standard Track -Category: Core -Status: Final -Created: 2017-04-23 +eip: 609 +title: "Hardfork Meta: Byzantium" +author: Alex Beregszaszi +type: Standard Track +category: Core +status: Final +created: 2017-04-23 Requires: 100, 140, 196, 197, 198, 211, 214, 649, 658 --- diff --git a/EIPS/eip-615.md b/EIPS/eip-615.md index 1a83014d34902..b57146af3b640 100644 --- a/EIPS/eip-615.md +++ b/EIPS/eip-615.md @@ -1,10 +1,10 @@ --- -EIP: 615 -Title: Subroutines and Static Jumps for the EVM -Status: Draft -Type: Core -Author: Greg Colvin , Paweł Bylica, Christian Reitwiessner -Created: 2016-12-10 +eip: 615 +title: Subroutines and Static Jumps for the EVM +status: Draft +type: Core +author: Greg Colvin , Paweł Bylica, Christian Reitwiessner +created: 2016-12-10 Edited: 2017-25-4 --- diff --git a/EIPS/eip-616.md b/EIPS/eip-616.md index 6237f8d862af9..f2f16e1657c22 100644 --- a/EIPS/eip-616.md +++ b/EIPS/eip-616.md @@ -1,11 +1,11 @@ --- -EIP: 616 -Title: SIMD Operations for the EVM -Author: Greg Colvin, greg@colvin.org -Type: Standard Track -Category: Core -Status: Draft -Created: 2017-04-25 +eip: 616 +title: SIMD Operations for the EVM +author: Greg Colvin, greg@colvin.org +type: Standard Track +category: Core +status: Draft +created: 2017-04-25 --- ## ABSTRACT diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index 33199f1103c75..4429610624ebf 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -1,11 +1,11 @@ --- -EIP: 649 -Title: Metropolis Difficulty Bomb Delay and Block Reward Reduction +eip: 649 +title: Metropolis Difficulty Bomb Delay and Block Reward Reduction Authors: Afri Schoedon, Vitalik Buterin -Type: Standard Track -Category: Core -Status: Final -Created: 2017-06-21 +type: Standard Track +category: Core +status: Final +created: 2017-06-21 Replaces: 186 --- diff --git a/EIPS/eip-658.md b/EIPS/eip-658.md index c48878540c142..6170436e874b4 100644 --- a/EIPS/eip-658.md +++ b/EIPS/eip-658.md @@ -1,11 +1,11 @@ --- -EIP: 658 -Title: Embedding transaction status code in receipts -Author: Nick Johnson -Type: Standard Track -Category: Core -Status: Final -Created: 2017-06-30 +eip: 658 +title: Embedding transaction status code in receipts +author: Nick Johnson +type: Standard Track +category: Core +status: Final +created: 2017-06-30 Requires: 140 Replaces: 98 --- diff --git a/EIPS/eip-681.md b/EIPS/eip-681.md index 57a83203d6366..3093ffc3810bf 100644 --- a/EIPS/eip-681.md +++ b/EIPS/eip-681.md @@ -1,11 +1,11 @@ --- -EIP: 681 -Title: URL Format for Transaction Requests -Author: Daniel A. Nagy -Type: Standard Track -Category: ERC -Status: Draft -Created: 2017-08-01 +eip: 681 +title: URL Format for Transaction Requests +author: Daniel A. Nagy +type: Standard Track +category: ERC +status: Draft +created: 2017-08-01 Requires: 20, 137, 831 --- diff --git a/EIPS/eip-695.md b/EIPS/eip-695.md index 170fd3fd1d85b..28503519da73f 100644 --- a/EIPS/eip-695.md +++ b/EIPS/eip-695.md @@ -1,11 +1,11 @@ --- -EIP: 695 -Title: Create `eth_chainId` method for JSON-RPC -Author: Isaac Ardis Wei Tang , @tcz001 -Type: Standard Track -Category: Interface -Status: Draft -Created: 2017-08-21 +eip: 695 +title: Create `eth_chainId` method for JSON-RPC +author: Isaac Ardis Wei Tang , @tcz001 +type: Standard Track +category: Interface +status: Draft +created: 2017-08-21 --- ## Simple Summary diff --git a/EIPS/eip-7.md b/EIPS/eip-7.md index 989d1f4085c2e..1a7c06ec04451 100644 --- a/EIPS/eip-7.md +++ b/EIPS/eip-7.md @@ -1,10 +1,10 @@ --- -EIP: 7 -Title: DELEGATECALL -Author: Vitalik Buterin -Status: Final -Type: Homestead feature -Created: 2015-11-15 +eip: 7 +title: DELEGATECALL +author: Vitalik Buterin +status: Final +type: Homestead feature +created: 2015-11-15 --- ### Hard Fork diff --git a/EIPS/eip-706.md b/EIPS/eip-706.md index 712b5f56eb03d..f522dbcb1be98 100644 --- a/EIPS/eip-706.md +++ b/EIPS/eip-706.md @@ -1,11 +1,11 @@ --- -EIP: 706 -Title: DEVp2p snappy compression -Author: Péter Szilágyi -Type: Standard Track -Category: Networking -Status: Final -Created: 2017-09-07 +eip: 706 +title: DEVp2p snappy compression +author: Péter Szilágyi +type: Standard Track +category: Networking +status: Final +created: 2017-09-07 --- ## Abstract diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 3c416381cf1ef..5a319e031659c 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -1,11 +1,11 @@ --- -EIP: 721 -Title: ERC-721 Non-Fungible Token Standard -Author: William Entriken , Dieter Shirley , Jacob Evans , Nastassia Sachs -Type: Standard -Category: ERC -Status: Draft -Created: 2018-01-24 +eip: 721 +title: ERC-721 Non-Fungible Token Standard +author: William Entriken , Dieter Shirley , Jacob Evans , Nastassia Sachs +type: Standard +category: ERC +status: Draft +created: 2018-01-24 Requires: ERC-165 --- diff --git a/EIPS/eip-758.md b/EIPS/eip-758.md index 4cdec48b36867..48c6510ec1745 100644 --- a/EIPS/eip-758.md +++ b/EIPS/eip-758.md @@ -1,11 +1,11 @@ --- -EIP: 758 -Title: Subscriptions and filters for transaction return data -Author: Jack Peterson -Type: Standard Track -Category: Interface -Status: Draft -Created: 2017-11-09 +eip: 758 +title: Subscriptions and filters for transaction return data +author: Jack Peterson +type: Standard Track +category: Interface +status: Draft +created: 2017-11-09 --- ## Simple Summary diff --git a/EIPS/eip-779.md b/EIPS/eip-779.md index e5a62093763c7..8d422ee04233d 100644 --- a/EIPS/eip-779.md +++ b/EIPS/eip-779.md @@ -1,10 +1,10 @@ --- -EIP: 779 -Title: "Hardfork Info: DAO Fork" -Author: Casey Detrio -Type: Informational -Status: Final -Created: 2017-11-26 +eip: 779 +title: "Hardfork Info: DAO Fork" +author: Casey Detrio +type: Informational +status: Final +created: 2017-11-26 --- ## Abstract diff --git a/EIPS/eip-8.md b/EIPS/eip-8.md index 58db0a0899f06..d00a2f40023dd 100644 --- a/EIPS/eip-8.md +++ b/EIPS/eip-8.md @@ -1,11 +1,11 @@ --- -EIP: 8 -Title: devp2p Forward Compatibility Requirements for Homestead -Author: Felix Lange -Status: Final -Type: Standards Track -Layer: Networking -Created: 2015-12-18 +eip: 8 +title: devp2p Forward Compatibility Requirements for Homestead +author: Felix Lange +status: Final +type: Standards Track +layer: Networking +created: 2015-12-18 --- ### Abstract diff --git a/EIPS/eip-801.md b/EIPS/eip-801.md index adf8e557e6563..2ddf716694df8 100644 --- a/EIPS/eip-801.md +++ b/EIPS/eip-801.md @@ -1,11 +1,11 @@ --- -EIP: 801 -Title: ERC-801 Canary Standard -Author: ligi -Type: Standard -Category: ERC -Status: Draft -Created: 2017-12-16 +eip: 801 +title: ERC-801 Canary Standard +author: ligi +type: Standard +category: ERC +status: Draft +created: 2017-12-16 --- ## Simple Summary diff --git a/EIPS/eip-831.md b/EIPS/eip-831.md index 7cc0dde11ea2c..1a1645dc0c83a 100644 --- a/EIPS/eip-831.md +++ b/EIPS/eip-831.md @@ -1,11 +1,11 @@ --- -EIP: 831 -Title: URL Format for Ethereum -Author: ligi -Type: Standard Track -Category: ERC -Status: Draft -Created: 2018-01-15 +eip: 831 +title: URL Format for Ethereum +author: ligi +type: Standard Track +category: ERC +status: Draft +created: 2018-01-15 --- ## Simple Summary diff --git a/EIPS/eip-858.md b/EIPS/eip-858.md index 4698879d9eaa9..1c5a88e830300 100644 --- a/EIPS/eip-858.md +++ b/EIPS/eip-858.md @@ -1,11 +1,11 @@ --- -EIP: 858 -Title: Reduce block reward -Author: Carl Larson -Type: Standard Track -Category: Core -Status: Draft -Created: 2018-01-29 +eip: 858 +title: Reduce block reward +author: Carl Larson +type: Standard Track +category: Core +status: Draft +created: 2018-01-29 --- ## Simple Summary diff --git a/EIPS/eip-868.md b/EIPS/eip-868.md index e3f3ce08c726c..d5158a034b325 100644 --- a/EIPS/eip-868.md +++ b/EIPS/eip-868.md @@ -1,11 +1,11 @@ --- -EIP: 868 -Title: Node Discovery v4 ENR Extension -Author: Felix Lange -Type: Standard Track -Category: Networking -Status: Draft -Created: 2018-02-02 +eip: 868 +title: Node Discovery v4 ENR Extension +author: Felix Lange +type: Standard Track +category: Networking +status: Draft +created: 2018-02-02 Requires: EIP-8, EIP-778 --- diff --git a/index.html b/index.html index d168acd02e716..0fa5dd46e041e 100644 --- a/index.html +++ b/index.html @@ -5,8 +5,8 @@ layout: home --- -{% assign statuses = site.pages|map:"Status"|uniq %} -{% assign pages = site.pages|sort:"EIP" %} +{% assign statuses = site.pages|map:"status"|uniq %} +{% assign pages = site.pages|sort:"eip" %} {% for status in statuses %} {% if status != undefined %}

{{status}}

@@ -15,8 +15,8 @@

{{status}}

NumberTitleAuthorLayer {% for page in pages %} - {% if page.Status == status %} - {{page.EIP}}{{page.Title|xml_escape}}{{page.Author|xml_escape}}{{page.Layer|xml_escape}} + {% if page.status == status %} + {{page.eip|xml_escape}}{{page.title|xml_escape}}{{page.author|xml_escape}}{{page.layer|xml_escape}} {% endif %} {% endfor %} From 8781574c9fd19e32a93e0304cd28d97a9e273001 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 12:54:41 +0000 Subject: [PATCH 0545/1085] Use EIP layout for EIPs --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index 0ad1ea75ec16f..518afe02f2d2a 100644 --- a/_config.yml +++ b/_config.yml @@ -36,7 +36,7 @@ defaults: scope: path: "EIPS" values: - layout: "default" + layout: "eip" # Exclude from processing. # The following items will not be processed, by default. Create a custom list From 3e91f85825f1197de7fd2ad25f2b3d929891c1f7 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 12:59:50 +0000 Subject: [PATCH 0546/1085] Add info table to top of EIPs --- _layouts/eip.html | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 _layouts/eip.html diff --git a/_layouts/eip.html b/_layouts/eip.html new file mode 100644 index 0000000000000..8e29fdcf87a5b --- /dev/null +++ b/_layouts/eip.html @@ -0,0 +1,19 @@ +--- +layout: default +--- + +
+

EIP {{ page.eip | xml_escape }}: {{ page.title | xml_escape }}

+ + + + + + + + +
Author{{ page.author | xml_escape }}
Status{{ page.status | xml_escape }}
Type{{ page.type | xml_escape }}
Layer{{ page.layer | xml_escape }}
Category{{ page.category | xml_escape }}
Created{{ page.created | xml_escape }}
+ + {{ content }} + +
From c231d1c9809e4ccd45375d98f6384bdde2e30525 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 13:10:08 +0000 Subject: [PATCH 0547/1085] Update EIP 1 with header format changes, fix a few other EIP header issues --- EIPS/eip-1.md | 40 ++++++++++++++++++++++------------------ EIPS/eip-158.md | 2 +- EIPS/eip-211.md | 3 +-- EIPS/eip-606.md | 2 +- EIPS/eip-607.md | 2 +- EIPS/eip-608.md | 2 +- EIPS/eip-609.md | 2 +- EIPS/eip-615.md | 2 +- EIPS/eip-649.md | 2 +- EIPS/eip-658.md | 4 ++-- EIPS/eip-681.md | 2 +- EIPS/eip-721.md | 2 +- EIPS/eip-868.md | 2 +- _layouts/eip.html | 17 +++++++++++++++-- 14 files changed, 50 insertions(+), 34 deletions(-) diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index b997aec1b48cc..c2374d98b2ab0 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -117,29 +117,31 @@ EIPs should be written in [markdown] format. Image files should be included in a EIP Header Preamble ------------------- -Each EIP must begin with an RFC 822 style header preamble. The headers must appear in the following order. Headers marked with "*" are optional and are described below. All other headers are required. +Each EIP must begin with an RFC 822 style header preamble, preceded and followed by three hyphens ('---'). The headers must appear in the following order. Headers marked with "*" are optional and are described below. All other headers are required. -` EIP: ` (this is determined by the EIP editor) +` eip: ` (this is determined by the EIP editor) -` Title: ` +` title: ` -` Author: ` +` author: ` -` * Discussions-To: ` +` * discussions-to: ` -` Status: ` +` status: ` -` Type: ` +` type: ` -` Created: ` +` created: ` -` * Replaces: ` +` * requires: ` -` * Superseded-By: ` +` * replaces: ` -` * Resolution: ` +` * superseded-by: ` -The Author header lists the names, and optionally the email addresses of all the authors/owners of the EIP. The format of the Author header value must be +` * resolution: ` + +The author header lists the names, and optionally the email addresses of all the authors/owners of the EIP. The format of the author header value must be Random J. User <address@dom.ain> @@ -149,17 +151,19 @@ Random J. User if the email address is not given. -Note: The Resolution header is required for Standards Track EIPs only. It contains a URL that should point to an email message or other web resource where the pronouncement about the EIP is made. +Note: The resolution header is required for Standards Track EIPs only. It contains a URL that should point to an email message or other web resource where the pronouncement about the EIP is made. + +While an EIP is in private discussions (usually during the initial Draft phase), a discussions-to header will indicate the mailing list or URL where the EIP is being discussed. No discussions-to header is necessary if the EIP is being discussed privately with the author. -While an EIP is in private discussions (usually during the initial Draft phase), a Discussions-To header will indicate the mailing list or URL where the EIP is being discussed. No Discussions-To header is necessary if the EIP is being discussed privately with the author. +The type header specifies the type of EIP: Standards Track, Meta, or Informational. If the track is Standards please include the subcategory (core, networking, interface, or ERC). -The Type header specifies the type of EIP: Standards Track, Meta, or Informational. If the track is Standards please include the subcategory (core, networking, interface, or ERC). +The created header records the date that the EIP was assigned a number. Both headers should be in yyyy-mm-dd format, e.g. 2001-08-14. -The Created header records the date that the EIP was assigned a number. Both headers should be in yyyy-mm-dd format, e.g. 2001-08-14. +EIPs may have a requires header, indicating the EIP numbers that this EIP depends on. -EIPs may have a Requires header, indicating the EIP numbers that this EIP depends on. +EIPs may also have a superseded-by header indicating that an EIP has been rendered obsolete by a later document; the value is the number of the EIP that replaces the current document. The newer EIP must have a Replaces header containing the number of the EIP that it rendered obsolete. -EIPs may also have a Superseded-By header indicating that an EIP has been rendered obsolete by a later document; the value is the number of the EIP that replaces the current document. The newer EIP must have a Replaces header containing the number of the EIP that it rendered obsolete. +Headers that permit lists must separate elements with commas. Auxiliary Files --------------- diff --git a/EIPS/eip-158.md b/EIPS/eip-158.md index 5b1f13c3829eb..443e3b392d81a 100644 --- a/EIPS/eip-158.md +++ b/EIPS/eip-158.md @@ -6,7 +6,7 @@ type: Standard Track category: Core status: Superseded created: 2016-10-16 -Superseded-By: 161 +superseded-by: 161 --- # Specification diff --git a/EIPS/eip-211.md b/EIPS/eip-211.md index c2daee4b475b2..b2026ca8880bc 100644 --- a/EIPS/eip-211.md +++ b/EIPS/eip-211.md @@ -6,8 +6,7 @@ type: Standard Track category: Core status: Final created: 2017-02-13 -Requires: -Replaces: 5/8 +replaces: 5,8 --- ## Simple Summary diff --git a/EIPS/eip-606.md b/EIPS/eip-606.md index 1730738d45920..d7935a8b7e56c 100644 --- a/EIPS/eip-606.md +++ b/EIPS/eip-606.md @@ -5,7 +5,7 @@ author: Alex Beregszaszi type: Meta status: Final created: 2017-04-23 -Requires: 2, 7 +requires: 2, 7 --- ## Abstract diff --git a/EIPS/eip-607.md b/EIPS/eip-607.md index 9e713c0ff7f9a..6d24572d8bbfb 100644 --- a/EIPS/eip-607.md +++ b/EIPS/eip-607.md @@ -5,7 +5,7 @@ author: Alex Beregszaszi type: Meta status: Final created: 2017-04-23 -Requires: 155, 160, 161, 170 +requires: 155, 160, 161, 170 --- ## Abstract diff --git a/EIPS/eip-608.md b/EIPS/eip-608.md index 8e5eb6218e452..9d056b0e51bbb 100644 --- a/EIPS/eip-608.md +++ b/EIPS/eip-608.md @@ -5,7 +5,7 @@ author: Alex Beregszaszi type: Meta status: Final created: 2017-04-23 -Requires: 150 +requires: 150 --- ## Abstract diff --git a/EIPS/eip-609.md b/EIPS/eip-609.md index 23fa8ab3595d0..c315c1d9337c2 100644 --- a/EIPS/eip-609.md +++ b/EIPS/eip-609.md @@ -6,7 +6,7 @@ type: Standard Track category: Core status: Final created: 2017-04-23 -Requires: 100, 140, 196, 197, 198, 211, 214, 649, 658 +requires: 100, 140, 196, 197, 198, 211, 214, 649, 658 --- ## Abstract diff --git a/EIPS/eip-615.md b/EIPS/eip-615.md index b57146af3b640..4ad9c74dc6297 100644 --- a/EIPS/eip-615.md +++ b/EIPS/eip-615.md @@ -5,7 +5,7 @@ status: Draft type: Core author: Greg Colvin , Paweł Bylica, Christian Reitwiessner created: 2016-12-10 -Edited: 2017-25-4 +edited: 2017-25-4 --- ## Abstract diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index 4429610624ebf..52f4e1a2b86d2 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -6,7 +6,7 @@ type: Standard Track category: Core status: Final created: 2017-06-21 -Replaces: 186 +replaces: 186 --- ## Simple Summary diff --git a/EIPS/eip-658.md b/EIPS/eip-658.md index 6170436e874b4..00656acd026d4 100644 --- a/EIPS/eip-658.md +++ b/EIPS/eip-658.md @@ -6,8 +6,8 @@ type: Standard Track category: Core status: Final created: 2017-06-30 -Requires: 140 -Replaces: 98 +requires: 140 +replaces: 98 --- ## Abstract diff --git a/EIPS/eip-681.md b/EIPS/eip-681.md index 3093ffc3810bf..6351f46a546d4 100644 --- a/EIPS/eip-681.md +++ b/EIPS/eip-681.md @@ -6,7 +6,7 @@ type: Standard Track category: ERC status: Draft created: 2017-08-01 -Requires: 20, 137, 831 +requires: 20, 137, 831 --- ## Simple Summary diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 5a319e031659c..73dfdd74e89f3 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -6,7 +6,7 @@ type: Standard category: ERC status: Draft created: 2018-01-24 -Requires: ERC-165 +requires: ERC-165 --- ## Simple Summary diff --git a/EIPS/eip-868.md b/EIPS/eip-868.md index d5158a034b325..3ac28fa0dfb34 100644 --- a/EIPS/eip-868.md +++ b/EIPS/eip-868.md @@ -6,7 +6,7 @@ type: Standard Track category: Networking status: Draft created: 2018-02-02 -Requires: EIP-8, EIP-778 +requires: 8, 778 --- # Abstract diff --git a/_layouts/eip.html b/_layouts/eip.html index 8e29fdcf87a5b..d55a709c8584b 100644 --- a/_layouts/eip.html +++ b/_layouts/eip.html @@ -7,11 +7,24 @@

EIP {{ page.eip | xml_escape }}: {{ page.title | xml_es + {% if page["discussions-to"] != undefined %} + + {% endif %} - - + {% if page.requires != undefined %} + + {% endif %} + {% if page.replaces != undefined %} + + {% endif %} + {% if page["superseded-by"] != undefined %} + + {% endif %} + {% if page.resolution != undefined %} + + {% endif %}
Author{{ page.author | xml_escape }}
Discussions-To{{ page["discussions-to"] | xml_escape }}
Status{{ page.status | xml_escape }}
Type{{ page.type | xml_escape }}
Layer{{ page.layer | xml_escape }}
Category{{ page.category | xml_escape }}
Created{{ page.created | xml_escape }}
Requires{{ page.requires | xml_escape }}
Replaces{{ page.replaces | xml_escape }}
Superseded by{{ page["superseded-by"] | xml_escape }}
Resolution{{ page.resolution | xml_escape }}
{{ content }} From aea7bfceb5551395d0ca1a9faeab65eb19c6410a Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 13:14:02 +0000 Subject: [PATCH 0548/1085] Update eip-X template, more tweaks to EIP 1 and jekyll template. --- EIPS/eip-1.md | 4 ++++ _layouts/eip.html | 3 +++ eip-X.md | 27 ++++++++++++++------------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index c2374d98b2ab0..ae65291d1e94b 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -131,6 +131,8 @@ Each EIP must begin with an RFC 822 style header preamble, preceded and followed ` type: ` +` * category `: + ` created: ` ` * requires: ` @@ -157,6 +159,8 @@ While an EIP is in private discussions (usually during the initial Draft phase), The type header specifies the type of EIP: Standards Track, Meta, or Informational. If the track is Standards please include the subcategory (core, networking, interface, or ERC). +The category header specifies the EIP's category. This is required for standards-track EIPs only. + The created header records the date that the EIP was assigned a number. Both headers should be in yyyy-mm-dd format, e.g. 2001-08-14. EIPs may have a requires header, indicating the EIP numbers that this EIP depends on. diff --git a/_layouts/eip.html b/_layouts/eip.html index d55a709c8584b..bb274d6723431 100644 --- a/_layouts/eip.html +++ b/_layouts/eip.html @@ -12,6 +12,9 @@

EIP {{ page.eip | xml_escape }}: {{ page.title | xml_es {% endif %} Status{{ page.status | xml_escape }} Type{{ page.type | xml_escape }} + {% if page.category != undefined %} + Category{{ page.category | xml_escape }} + {% endif %} Created{{ page.created | xml_escape }} {% if page.requires != undefined %} Requires{{ page.requires | xml_escape }} diff --git a/eip-X.md b/eip-X.md index 99de918876cd8..5536a2e4cbe6c 100644 --- a/eip-X.md +++ b/eip-X.md @@ -1,19 +1,20 @@ +--- +eip: +title: +author: +discussions-to: +status: Draft +type: +category (*only required for Standard Track): +created: +requires (*optional): +replaces (*optional): +--- + This is the suggested template for new EIPs. Note that an EIP number will be assigned by an editor. When opening a pull request to submit your EIP, please use an abbreviated title in the filename, `eip-draft_title_abbrev.md`. -## Preamble - - EIP: - Title: - Author: - Type: - Category (*only required for Standard Track): - Status: Draft - Created: - Requires (*optional): - Replaces (*optional): - The title should be 44 characters or less. ## Simple Summary @@ -26,7 +27,7 @@ A short (~200 word) description of the technical issue being addressed. The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright. ## Specification -The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (cpp-ethereum, go-ethereum, parity, ethereumj, ethereumjs, ...). +The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (cpp-ethereum, go-ethereum, parity, ethereumj, ethereumjs, ...). ## Rationale The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion. From aecc9b33dd3b7e08709b7187149ef8ccd8e9b5ea Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 13:16:39 +0000 Subject: [PATCH 0549/1085] Exclude eip-X from processing --- _config.yml | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/_config.yml b/_config.yml index 518afe02f2d2a..f9ee14a400999 100644 --- a/_config.yml +++ b/_config.yml @@ -38,14 +38,12 @@ defaults: values: layout: "eip" -# Exclude from processing. -# The following items will not be processed, by default. Create a custom list -# to override the default setting. -# exclude: -# - Gemfile -# - Gemfile.lock -# - node_modules -# - vendor/bundle/ -# - vendor/cache/ -# - vendor/gems/ -# - vendor/ruby/ +exclude: + - Gemfile + - Gemfile.lock + - node_modules + - vendor/bundle/ + - vendor/cache/ + - vendor/gems/ + - vendor/ruby/ + - eip-X.md From 264e8be5ed04dfe7a10fe6d021337f2301feafa8 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 13:36:46 +0000 Subject: [PATCH 0550/1085] Use pretty URLs --- EIPS/eip-1.md | 2 +- EIPS/eip-107.md | 6 +++--- EIPS/eip-858.md | 2 +- _config.yml | 2 ++ _layouts/eip.html | 1 - 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index ae65291d1e94b..082382aa2d509 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -62,7 +62,7 @@ EIPs can also be superseded by a different EIP, rendering the original obsolete. The possible paths of the status of EIPs are as follows: - +![](process.png) Some Informational and Process EIPs may also have a status of “Active” if they are never meant to be completed. E.g. EIP 1 (this EIP). diff --git a/EIPS/eip-107.md b/EIPS/eip-107.md index d9a1beff3dc90..33fbee6bbfcd9 100644 --- a/EIPS/eip-107.md +++ b/EIPS/eip-107.md @@ -29,19 +29,19 @@ Account unlocked : ----------------- When the account is already unlocked, the user is presented with the following popup for every transaction that the dapp attempts to make: - +![](authorization.png) Account locked and no "personal" api exposed via rpc: ----------------- When the account is locked, and the node does not provide access to account unlocking via its rpc interface, the following popup will be presented. This is not ideal since this requires the user to know how to unlock an account: - +![](authorization-locked.png) Account locked but node exposing the "personal" api via rpc : ----------------- A better option is to ask the user for their password, but this is only possible if the node allows access to the "personal" api via rpc. In such case, the following dialog will be presented to the user so he/she can accept the transaction by providing the password required to unlock the account: - +![](authorization-password.png") Specification diff --git a/EIPS/eip-858.md b/EIPS/eip-858.md index 1c5a88e830300..045eaa5ce33c1 100644 --- a/EIPS/eip-858.md +++ b/EIPS/eip-858.md @@ -15,7 +15,7 @@ Reduce the block reward to 1 ETH. The current public Ethereum network has a hashrate that corresponds to a tremendous level of energy consumption. As this energy consumption has a correlated environmental cost the network participants have an ethical obligation to ensure this cost is not higher than necessary. At this time, the most direct way to reduce this cost is to lower the block reward in order to limit the appeal of ETH mining. Unchecked growth in hashrate is also counterproductive from a security standpoint. ## Motivation -The current public Ethereum network has a hashrate of 232 TH/s). This hashrate corresponds to a **lower bound** for power usage of roughly [821 MW](eip-858/calculations.md) and yearly energy consumption of 7.2 TWh (roughly 0.033% of [total](https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption) global electricity consumption). A future switch to full Proof of Stake will solve this issue entirely. Yet that switch remains enough in the future that action should be taken in the interim to limit excess harmful side affects of the present network. +The current public Ethereum network has a hashrate of 232 TH/s). This hashrate corresponds to a **lower bound** for power usage of roughly [821 MW](calculations.md) and yearly energy consumption of 7.2 TWh (roughly 0.033% of [total](https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption) global electricity consumption). A future switch to full Proof of Stake will solve this issue entirely. Yet that switch remains enough in the future that action should be taken in the interim to limit excess harmful side affects of the present network. ## Specification Block reward to be changed to 1 ETH / block. diff --git a/_config.yml b/_config.yml index f9ee14a400999..2a7d120ca9f0b 100644 --- a/_config.yml +++ b/_config.yml @@ -31,6 +31,8 @@ theme: minima plugins: - jekyll-feed +permalink: slug + defaults: - scope: diff --git a/_layouts/eip.html b/_layouts/eip.html index bb274d6723431..af6f580ff0d0e 100644 --- a/_layouts/eip.html +++ b/_layouts/eip.html @@ -4,7 +4,6 @@

EIP {{ page.eip | xml_escape }}: {{ page.title | xml_escape }}

- {% if page["discussions-to"] != undefined %} From c80a142e8f4c9c807d11425a9a823380cfc87072 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 13:37:40 +0000 Subject: [PATCH 0551/1085] Fix title --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index 2a7d120ca9f0b..803cbda350412 100644 --- a/_config.yml +++ b/_config.yml @@ -13,7 +13,7 @@ # you will see them accessed via {{ site.title }}, {{ site.email }}, and so on. # You can create any custom variable you would like, and they will be accessible # in the templates via {{ site.myvariable }}. -title: Ethereum EIPs by status +title: Ethereum Improvement Proposals email: nick@ethereum.org description: >- # this means to ignore newlines until "baseurl:" Write an awesome description for your new site here. You can edit this From f0289472d45eae676563473287209716e50edd35 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 13:43:23 +0000 Subject: [PATCH 0552/1085] Update site description --- _config.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/_config.yml b/_config.yml index 803cbda350412..7a73749a0a5b3 100644 --- a/_config.yml +++ b/_config.yml @@ -14,11 +14,10 @@ # You can create any custom variable you would like, and they will be accessible # in the templates via {{ site.myvariable }}. title: Ethereum Improvement Proposals -email: nick@ethereum.org -description: >- # this means to ignore newlines until "baseurl:" - Write an awesome description for your new site here. You can edit this - line in _config.yml. It will appear in your document head meta (for - Google search results) and in your feed.xml site description. +description: >- + Ethereum Improvement Proposals (EIPs) describe standards for the Ethereum + platform, including core protocol specifications, client APIs, and contract + standards. url: "" # the base hostname & protocol for your site, e.g. http://example.com twitter_username: ethereum github_username: ethereum From 7038c5f9b9a4845ee1bf5301c2b0ee800ec181e1 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 15:55:18 +0000 Subject: [PATCH 0553/1085] Add pages for each EIP type, improve listing tables with links --- EIPS/eip-1.md | 2 +- EIPS/eip-100.md | 2 +- EIPS/eip-101.md | 3 ++- EIPS/eip-107.md | 2 +- EIPS/eip-140.md | 2 +- EIPS/eip-141.md | 2 +- EIPS/eip-145.md | 2 +- EIPS/eip-150.md | 2 +- EIPS/eip-155.md | 2 +- EIPS/eip-158.md | 2 +- EIPS/eip-160.md | 2 +- EIPS/eip-161.md | 2 +- EIPS/eip-165.md | 2 +- EIPS/eip-170.md | 2 +- EIPS/eip-181.md | 2 +- EIPS/eip-196.md | 2 +- EIPS/eip-197.md | 2 +- EIPS/eip-2.md | 2 +- EIPS/eip-20.md | 2 +- EIPS/eip-211.md | 2 +- EIPS/eip-214.md | 2 +- EIPS/eip-234.md | 2 +- EIPS/eip-3.md | 2 +- EIPS/eip-5.md | 2 +- EIPS/eip-55.md | 2 +- EIPS/eip-6.md | 1 + EIPS/eip-609.md | 2 +- EIPS/eip-615.md | 3 ++- EIPS/eip-616.md | 2 +- EIPS/eip-649.md | 2 +- EIPS/eip-658.md | 2 +- EIPS/eip-681.md | 2 +- EIPS/eip-695.md | 2 +- EIPS/eip-7.md | 3 ++- EIPS/eip-706.md | 2 +- EIPS/eip-721.md | 2 +- EIPS/eip-758.md | 2 +- EIPS/eip-801.md | 2 +- EIPS/eip-831.md | 2 +- EIPS/eip-858.md | 2 +- EIPS/eip-868.md | 2 +- _config.yml | 6 ++++++ _includes/eipnums.html | 4 ++++ _includes/eiptable.html | 18 ++++++++++++++++++ _layouts/eip.html | 10 +++++----- core.html | 7 +++++++ eip-X.md | 2 +- erc.html | 7 +++++++ index.html | 20 ++++++++++++++++---- informational.html | 7 +++++++ interface.html | 7 +++++++ meta.html | 7 +++++++ networking.html | 7 +++++++ 53 files changed, 136 insertions(+), 50 deletions(-) create mode 100644 _includes/eipnums.html create mode 100644 _includes/eiptable.html create mode 100644 core.html create mode 100644 erc.html create mode 100644 informational.html create mode 100644 interface.html create mode 100644 meta.html create mode 100644 networking.html diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index 082382aa2d509..8f811514bfc39 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -129,7 +129,7 @@ Each EIP must begin with an RFC 822 style header preamble, preceded and followed ` status: ` -` type: ` +` type: ` ` * category `: diff --git a/EIPS/eip-100.md b/EIPS/eip-100.md index 3ea24a7f62ee5..f1ded40d3d19f 100644 --- a/EIPS/eip-100.md +++ b/EIPS/eip-100.md @@ -2,7 +2,7 @@ eip: 100 title: Change difficulty adjustment to target mean block time including uncles author: Vitalik Buterin -type: Standard Track +type: Standards Track category: Core status: Final created: 2016-04-28 diff --git a/EIPS/eip-101.md b/EIPS/eip-101.md index 47aa1591da111..ed457b0812339 100644 --- a/EIPS/eip-101.md +++ b/EIPS/eip-101.md @@ -3,7 +3,8 @@ eip: 101 title: Serenity Currency and Crypto Abstraction author: Vitalik Buterin status: Active -type: Serenity feature +type: Standards Track +category: Core created: 2015-11-15 --- diff --git a/EIPS/eip-107.md b/EIPS/eip-107.md index 33fbee6bbfcd9..b39458416adb9 100644 --- a/EIPS/eip-107.md +++ b/EIPS/eip-107.md @@ -4,7 +4,7 @@ title: safe "eth_sendTransaction" authorization via html popup author: Ronan Sandford created: 2016-06-05 status: Draft -type: Standard +type: Standards Track category: Interface --- diff --git a/EIPS/eip-140.md b/EIPS/eip-140.md index 7c2af3952e13a..f2c896e90f242 100644 --- a/EIPS/eip-140.md +++ b/EIPS/eip-140.md @@ -2,7 +2,7 @@ eip: 140 title: REVERT instruction author: Alex Beregszaszi, Nikolai Mushegian (nikolai@nexusdev.us) -type: Standard Track +type: Standards Track category: Core status: Final created: 2017-02-06 diff --git a/EIPS/eip-141.md b/EIPS/eip-141.md index 2cc57d11bf4d4..64b6734fb7262 100644 --- a/EIPS/eip-141.md +++ b/EIPS/eip-141.md @@ -2,7 +2,7 @@ eip: 141 title: Designated invalid EVM instruction author: Alex Beregszaszi -type: Standard Track +type: Standards Track category: Core status: Final created: 2017-02-09 diff --git a/EIPS/eip-145.md b/EIPS/eip-145.md index 15e41ebc33047..68d701363d4e0 100644 --- a/EIPS/eip-145.md +++ b/EIPS/eip-145.md @@ -2,7 +2,7 @@ eip: 145 title: Bitwise shifting instructions in EVM author: Alex Beregszaszi, Paweł Bylica -type: Standard Track +type: Standards Track category: Core status: Final created: 2017-02-13 diff --git a/EIPS/eip-150.md b/EIPS/eip-150.md index dfac0de091bcc..a6c7c8db134e3 100644 --- a/EIPS/eip-150.md +++ b/EIPS/eip-150.md @@ -2,7 +2,7 @@ eip: 150 title: Gas cost changes for IO-heavy operations author: Vitalik Buterin -type: Standard Track +type: Standards Track category: Core status: Final created: 2016-09-24 diff --git a/EIPS/eip-155.md b/EIPS/eip-155.md index e2195cb9d14fd..7716b6ab8a634 100644 --- a/EIPS/eip-155.md +++ b/EIPS/eip-155.md @@ -2,7 +2,7 @@ eip: 155 title: Simple replay attack protection author: Vitalik Buterin -type: Standard Track +type: Standards Track category: Core status: Final created: 2016-10-14 diff --git a/EIPS/eip-158.md b/EIPS/eip-158.md index 443e3b392d81a..c5dbef191eaf8 100644 --- a/EIPS/eip-158.md +++ b/EIPS/eip-158.md @@ -2,7 +2,7 @@ eip: 158 title: State clearing author: Vitalik Buterin -type: Standard Track +type: Standards Track category: Core status: Superseded created: 2016-10-16 diff --git a/EIPS/eip-160.md b/EIPS/eip-160.md index 9fb35d71b2887..4749d89f45985 100644 --- a/EIPS/eip-160.md +++ b/EIPS/eip-160.md @@ -2,7 +2,7 @@ eip: 160 title: EXP cost increase author: Vitalik Buterin -type: Standard Track +type: Standards Track category: Core status: Final created: 2016-10-20 diff --git a/EIPS/eip-161.md b/EIPS/eip-161.md index 2be4c6658033f..fa61e602ca84d 100644 --- a/EIPS/eip-161.md +++ b/EIPS/eip-161.md @@ -2,7 +2,7 @@ eip: 161 title: State trie clearing (invariant-preserving alternative) author: Gavin Wood -type: Standard Track +type: Standards Track category: Core status: Final created: 2016-10-24 diff --git a/EIPS/eip-165.md b/EIPS/eip-165.md index 0b3f8574c09cd..eb1f9a2349414 100644 --- a/EIPS/eip-165.md +++ b/EIPS/eip-165.md @@ -2,7 +2,7 @@ eip: 165 title: ERC-165 Standard Interface Detection author: Christian Reitwießner , Nick Johnson , Fabian Vogelsteller , Jordi Baylina , Konrad Feldmeier , William Entriken -type: Standard Track +type: Standards Track category: ERC status: Draft created: 2018-01-23 diff --git a/EIPS/eip-170.md b/EIPS/eip-170.md index feda849b23170..5fd1b3d99397f 100644 --- a/EIPS/eip-170.md +++ b/EIPS/eip-170.md @@ -2,7 +2,7 @@ eip: 170 title: Contract code size limit author: Vitalik Buterin -type: Standard Track +type: Standards Track category: Core status: Final created: 2016-11-04 diff --git a/EIPS/eip-181.md b/EIPS/eip-181.md index a68f8120f397b..99f64c6b09837 100644 --- a/EIPS/eip-181.md +++ b/EIPS/eip-181.md @@ -3,7 +3,7 @@ eip: 181 title: ENS support for reverse resolution of Ethereum addresses author: Nick Johnson status: Final -type: Standard Track +type: Standards Track category: ERC created: 2016-12-01 --- diff --git a/EIPS/eip-196.md b/EIPS/eip-196.md index 7feaf17261603..70170741e0579 100644 --- a/EIPS/eip-196.md +++ b/EIPS/eip-196.md @@ -3,7 +3,7 @@ eip: 196 title: Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 author: Christian Reitwiessner -type: Standard Track +type: Standards Track category: Core status: Final created: 2017-02-02 diff --git a/EIPS/eip-197.md b/EIPS/eip-197.md index 827e5385d20a0..e4355058fcfc3 100644 --- a/EIPS/eip-197.md +++ b/EIPS/eip-197.md @@ -3,7 +3,7 @@ eip: 197 title: Precompiled contracts for optimal ate pairing check on the elliptic curve alt_bn128 author: Vitalik Buterin , Christian Reitwiessner -type: Standard Track +type: Standards Track category: Core status: Final created: 2017-02-06 diff --git a/EIPS/eip-2.md b/EIPS/eip-2.md index 673c8ab9415e4..bbdf97deae53d 100644 --- a/EIPS/eip-2.md +++ b/EIPS/eip-2.md @@ -3,7 +3,7 @@ eip: 2 title: Homestead Hard-fork Changes author: Vitalik Buterin status: Final -type: Standard Track +type: Standards Track category: Core created: 2015-11-15 --- diff --git a/EIPS/eip-20.md b/EIPS/eip-20.md index 494c1a437edde..174bf0f9bc588 100644 --- a/EIPS/eip-20.md +++ b/EIPS/eip-20.md @@ -2,7 +2,7 @@ eip: 20 title: ERC-20 Token Standard author: Fabian Vogelsteller , Vitalik Buterin -type: Standard +type: Standards Track category: ERC status: Accepted created: 2015-11-19 diff --git a/EIPS/eip-211.md b/EIPS/eip-211.md index b2026ca8880bc..af0a20c93f10d 100644 --- a/EIPS/eip-211.md +++ b/EIPS/eip-211.md @@ -2,7 +2,7 @@ eip: 211 title: "New opcodes: RETURNDATASIZE and RETURNDATACOPY" author: Christian Reitwiessner -type: Standard Track +type: Standards Track category: Core status: Final created: 2017-02-13 diff --git a/EIPS/eip-214.md b/EIPS/eip-214.md index 9b20d39fdde64..9a91ccc43fe76 100644 --- a/EIPS/eip-214.md +++ b/EIPS/eip-214.md @@ -2,7 +2,7 @@ eip: 214 title: New opcode STATICCALL author: Vitalik Buterin , Christian Reitwiessner ; -type: Standard Track +type: Standards Track category: Core status: Final created: 2017-02-13 diff --git a/EIPS/eip-234.md b/EIPS/eip-234.md index 6753f700aae98..99583142e334e 100644 --- a/EIPS/eip-234.md +++ b/EIPS/eip-234.md @@ -2,7 +2,7 @@ eip: 234 title: Add `blockHash` to JSON-RPC filter options. author: Micah Zoltu -type: Standard Track +type: Standards Track category: Interface status: Draft created: 2017-03-24 diff --git a/EIPS/eip-3.md b/EIPS/eip-3.md index 5d405f09870eb..2cf96c9707e42 100644 --- a/EIPS/eip-3.md +++ b/EIPS/eip-3.md @@ -4,7 +4,7 @@ title: Addition of CALLDEPTH opcode author: Martin Holst Swende status: Draft type: Standards Track -layer: Consensus (hard-fork) +category: Core created: 2015-11-19 --- diff --git a/EIPS/eip-5.md b/EIPS/eip-5.md index 6ec9bff9f8c0b..ae6ad1655e07e 100644 --- a/EIPS/eip-5.md +++ b/EIPS/eip-5.md @@ -4,7 +4,7 @@ title: Gas Usage for `RETURN` and `CALL*` author: Christian Reitwiessner status: Draft type: Standards Track -layer: Consensus (hard-fork) +category: Core created: 2015-11-22 --- diff --git a/EIPS/eip-55.md b/EIPS/eip-55.md index b610fc77421bc..caab54a64acd3 100644 --- a/EIPS/eip-55.md +++ b/EIPS/eip-55.md @@ -2,7 +2,7 @@ eip: 55 title: Mixed-case checksum address encoding author: Vitalik Buterin -type: Standard Track +type: Standards Track category: ERC status: Accepted created: 2016-01-14 diff --git a/EIPS/eip-6.md b/EIPS/eip-6.md index f42032b5b07b6..ea1b1032d5946 100644 --- a/EIPS/eip-6.md +++ b/EIPS/eip-6.md @@ -4,6 +4,7 @@ title: Renaming SUICIDE opcode author: Hudson Jameson status: Final type: Standards Track +category: Interface layer: Applications created: 2015-11-22 --- diff --git a/EIPS/eip-609.md b/EIPS/eip-609.md index c315c1d9337c2..fce499ad34e79 100644 --- a/EIPS/eip-609.md +++ b/EIPS/eip-609.md @@ -2,7 +2,7 @@ eip: 609 title: "Hardfork Meta: Byzantium" author: Alex Beregszaszi -type: Standard Track +type: Standards Track category: Core status: Final created: 2017-04-23 diff --git a/EIPS/eip-615.md b/EIPS/eip-615.md index 4ad9c74dc6297..ad9d94fcf93da 100644 --- a/EIPS/eip-615.md +++ b/EIPS/eip-615.md @@ -2,7 +2,8 @@ eip: 615 title: Subroutines and Static Jumps for the EVM status: Draft -type: Core +type: Standards Track +category: Core author: Greg Colvin , Paweł Bylica, Christian Reitwiessner created: 2016-12-10 edited: 2017-25-4 diff --git a/EIPS/eip-616.md b/EIPS/eip-616.md index f2f16e1657c22..76b5dc22af5eb 100644 --- a/EIPS/eip-616.md +++ b/EIPS/eip-616.md @@ -2,7 +2,7 @@ eip: 616 title: SIMD Operations for the EVM author: Greg Colvin, greg@colvin.org -type: Standard Track +type: Standards Track category: Core status: Draft created: 2017-04-25 diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index 52f4e1a2b86d2..f679b2248e126 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -2,7 +2,7 @@ eip: 649 title: Metropolis Difficulty Bomb Delay and Block Reward Reduction Authors: Afri Schoedon, Vitalik Buterin -type: Standard Track +type: Standards Track category: Core status: Final created: 2017-06-21 diff --git a/EIPS/eip-658.md b/EIPS/eip-658.md index 00656acd026d4..e5a7cf5d0bb46 100644 --- a/EIPS/eip-658.md +++ b/EIPS/eip-658.md @@ -2,7 +2,7 @@ eip: 658 title: Embedding transaction status code in receipts author: Nick Johnson -type: Standard Track +type: Standards Track category: Core status: Final created: 2017-06-30 diff --git a/EIPS/eip-681.md b/EIPS/eip-681.md index 6351f46a546d4..4133fdfeec806 100644 --- a/EIPS/eip-681.md +++ b/EIPS/eip-681.md @@ -2,7 +2,7 @@ eip: 681 title: URL Format for Transaction Requests author: Daniel A. Nagy -type: Standard Track +type: Standards Track category: ERC status: Draft created: 2017-08-01 diff --git a/EIPS/eip-695.md b/EIPS/eip-695.md index 28503519da73f..6da6bc60588f2 100644 --- a/EIPS/eip-695.md +++ b/EIPS/eip-695.md @@ -2,7 +2,7 @@ eip: 695 title: Create `eth_chainId` method for JSON-RPC author: Isaac Ardis Wei Tang , @tcz001 -type: Standard Track +type: Standards Track category: Interface status: Draft created: 2017-08-21 diff --git a/EIPS/eip-7.md b/EIPS/eip-7.md index 1a7c06ec04451..31baa64384ff9 100644 --- a/EIPS/eip-7.md +++ b/EIPS/eip-7.md @@ -3,7 +3,8 @@ eip: 7 title: DELEGATECALL author: Vitalik Buterin status: Final -type: Homestead feature +type: Standards Track +category: Core created: 2015-11-15 --- diff --git a/EIPS/eip-706.md b/EIPS/eip-706.md index f522dbcb1be98..e1f601250f0ea 100644 --- a/EIPS/eip-706.md +++ b/EIPS/eip-706.md @@ -2,7 +2,7 @@ eip: 706 title: DEVp2p snappy compression author: Péter Szilágyi -type: Standard Track +type: Standards Track category: Networking status: Final created: 2017-09-07 diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 73dfdd74e89f3..975c97dedee39 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -2,7 +2,7 @@ eip: 721 title: ERC-721 Non-Fungible Token Standard author: William Entriken , Dieter Shirley , Jacob Evans , Nastassia Sachs -type: Standard +type: Standards Track category: ERC status: Draft created: 2018-01-24 diff --git a/EIPS/eip-758.md b/EIPS/eip-758.md index 48c6510ec1745..61195fb3c431e 100644 --- a/EIPS/eip-758.md +++ b/EIPS/eip-758.md @@ -2,7 +2,7 @@ eip: 758 title: Subscriptions and filters for transaction return data author: Jack Peterson -type: Standard Track +type: Standards Track category: Interface status: Draft created: 2017-11-09 diff --git a/EIPS/eip-801.md b/EIPS/eip-801.md index 2ddf716694df8..72637b36baef6 100644 --- a/EIPS/eip-801.md +++ b/EIPS/eip-801.md @@ -2,7 +2,7 @@ eip: 801 title: ERC-801 Canary Standard author: ligi -type: Standard +type: Standards Track category: ERC status: Draft created: 2017-12-16 diff --git a/EIPS/eip-831.md b/EIPS/eip-831.md index 1a1645dc0c83a..fe64e663eb959 100644 --- a/EIPS/eip-831.md +++ b/EIPS/eip-831.md @@ -2,7 +2,7 @@ eip: 831 title: URL Format for Ethereum author: ligi -type: Standard Track +type: Standards Track category: ERC status: Draft created: 2018-01-15 diff --git a/EIPS/eip-858.md b/EIPS/eip-858.md index 045eaa5ce33c1..391e1703b6fda 100644 --- a/EIPS/eip-858.md +++ b/EIPS/eip-858.md @@ -2,7 +2,7 @@ eip: 858 title: Reduce block reward author: Carl Larson -type: Standard Track +type: Standards Track category: Core status: Draft created: 2018-01-29 diff --git a/EIPS/eip-868.md b/EIPS/eip-868.md index 3ac28fa0dfb34..41732b42fe4a8 100644 --- a/EIPS/eip-868.md +++ b/EIPS/eip-868.md @@ -2,7 +2,7 @@ eip: 868 title: Node Discovery v4 ENR Extension author: Felix Lange -type: Standard Track +type: Standards Track category: Networking status: Draft created: 2018-02-02 diff --git a/_config.yml b/_config.yml index 7a73749a0a5b3..79506bcb8cca6 100644 --- a/_config.yml +++ b/_config.yml @@ -23,6 +23,12 @@ twitter_username: ethereum github_username: ethereum header_pages: - index.html + - core.html + - networking.html + - interface.html + - erc.html + - informational.html + - meta.html # Build settings markdown: kramdown diff --git a/_includes/eipnums.html b/_includes/eipnums.html new file mode 100644 index 0000000000000..1c4238b63001a --- /dev/null +++ b/_includes/eipnums.html @@ -0,0 +1,4 @@ +{% assign eips=include.eips|split:"," %} +{% for eipnum in eips %} + {{eipnum}}{% if forloop.last == false %}, {% endif %} +{% endfor %} diff --git a/_includes/eiptable.html b/_includes/eiptable.html new file mode 100644 index 0000000000000..409ae05c755e1 --- /dev/null +++ b/_includes/eiptable.html @@ -0,0 +1,18 @@ +{% assign bystatus = include.eips|sort:"eip"|group_by:"status" %} +{% for group in bystatus %} + {% if group.name != undefined %} +

{{group.name}}

+
Author{{ page.author | xml_escape }}
+ + + + {% for page in group.items %} + + + + + + {% endfor %} +
NumberTitleAuthor
{{page.eip|xml_escape}}{{page.title|xml_escape}}{{page.author|xml_escape}}
+ {% endif %} +{% endfor %} diff --git a/_layouts/eip.html b/_layouts/eip.html index af6f580ff0d0e..ba4cf00516cc2 100644 --- a/_layouts/eip.html +++ b/_layouts/eip.html @@ -7,7 +7,7 @@

EIP {{ page.eip | xml_escape }}: {{ page.title | xml_es {% if page["discussions-to"] != undefined %} - + {% endif %} @@ -16,16 +16,16 @@

EIP {{ page.eip | xml_escape }}: {{ page.title | xml_es {% endif %}

{% if page.requires != undefined %} - + {% endif %} {% if page.replaces != undefined %} - + {% endif %} {% if page["superseded-by"] != undefined %} - + {% endif %} {% if page.resolution != undefined %} - + {% endif %}
Author{{ page.author | xml_escape }}
Discussions-To{{ page["discussions-to"] | xml_escape }}
Discussions-To{{ page["discussions-to"] | xml_escape }}
Status{{ page.status | xml_escape }}
Type{{ page.type | xml_escape }}
Created{{ page.created | xml_escape }}
Requires{{ page.requires | xml_escape }}
Requires{% include eipnums.html eips=page.requires %}
Replaces{{ page.replaces | xml_escape }}
Replaces{{% include eipnums.html eips=page.replaces %}
Superseded by{{ page["superseded-by"] | xml_escape }}
Superseded by{% include eipnums.html eips=page['superseded-by'] %}
Resolution{{ page.resolution | xml_escape }}
Resolution{{ page.resolution | xml_escape }}
diff --git a/core.html b/core.html new file mode 100644 index 0000000000000..29cceb2e7ccaa --- /dev/null +++ b/core.html @@ -0,0 +1,7 @@ +--- +layout: page +title: Core +--- + +{% assign eips=site.pages|where:"type","Standards Track"|where:"category","Core" %} +{% include eiptable.html eips=eips %} diff --git a/eip-X.md b/eip-X.md index 5536a2e4cbe6c..e9460c690b0ac 100644 --- a/eip-X.md +++ b/eip-X.md @@ -4,7 +4,7 @@ title: author: discussions-to: status: Draft -type: +type: category (*only required for Standard Track): created: requires (*optional): diff --git a/erc.html b/erc.html new file mode 100644 index 0000000000000..bc3ba28ce5436 --- /dev/null +++ b/erc.html @@ -0,0 +1,7 @@ +--- +layout: page +title: ERC +--- + +{% assign eips=site.pages|where:"type","Standards Track"|where:"category","ERC" %} +{% include eiptable.html eips=eips %} diff --git a/index.html b/index.html index 0fa5dd46e041e..653eccfd55df3 100644 --- a/index.html +++ b/index.html @@ -1,10 +1,22 @@ --- -# You don't need to edit this file, it's empty on purpose. -# Edit theme's home layout instead if you wanna make some changes -# See: https://jekyllrb.com/docs/themes/#overriding-theme-defaults -layout: home +layout: default +title: Home --- +

EIPs Gitter

+

Ethereum Improvement Proposals (EIPs) describe standards for the Ethereum platform, including core protocol specifications, client APIs, and contract standards.

+ +

Contributing

+

First review EIP-1. Then clone the repository and add your EIP to it. There is a template EIP here. Then submit a Pull Request to Ethereum's EIPs repository.

+ +

EIP status terms

+
    +
  • Draft - an EIP that is open for consideration.
  • +
  • Accepted - an EIP that is planned for immediate adoption, i.e. expected to be included in the next hard fork (for Core/Consensus layer EIPs).
  • +
  • Final - an EIP that has been adopted in a previous hard fork (for Core/Consensus layer EIPs).
  • +
  • Deferred an EIP that is not being considered for immediate adoption. May be reconsidered in the future for a subsequent hard fork.
  • +
+ {% assign statuses = site.pages|map:"status"|uniq %} {% assign pages = site.pages|sort:"eip" %} {% for status in statuses %} diff --git a/informational.html b/informational.html new file mode 100644 index 0000000000000..6c322a19c0410 --- /dev/null +++ b/informational.html @@ -0,0 +1,7 @@ +--- +layout: page +title: Core +--- + +{% assign eips=site.pages|where:"type","Informational" %} +{% include eiptable.html eips=eips %} diff --git a/interface.html b/interface.html new file mode 100644 index 0000000000000..aba214600957d --- /dev/null +++ b/interface.html @@ -0,0 +1,7 @@ +--- +layout: page +title: Interface +--- + +{% assign eips=site.pages|where:"type","Standards Track"|where:"category","Interface" %} +{% include eiptable.html eips=eips %} diff --git a/meta.html b/meta.html new file mode 100644 index 0000000000000..d9ff658586c8c --- /dev/null +++ b/meta.html @@ -0,0 +1,7 @@ +--- +layout: page +title: Meta +--- + +{% assign eips=site.pages|where:"type","Meta" %} +{% include eiptable.html eips=eips %} diff --git a/networking.html b/networking.html new file mode 100644 index 0000000000000..0c62b7fc3067f --- /dev/null +++ b/networking.html @@ -0,0 +1,7 @@ +--- +layout: page +title: Networking +--- + +{% assign eips=site.pages|where:"type","Standards Track"|where:"category","Networking" %} +{% include eiptable.html eips=eips %} From 4486c636b8f6e10a412a83e9c3dfe3e1aee00541 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 16:04:37 +0000 Subject: [PATCH 0554/1085] Neatly format author lists --- _includes/authorlist.html | 10 ++++++++++ _includes/eiptable.html | 2 +- _layouts/eip.html | 6 +++--- 3 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 _includes/authorlist.html diff --git a/_includes/authorlist.html b/_includes/authorlist.html new file mode 100644 index 0000000000000..e32a48c49ccd2 --- /dev/null +++ b/_includes/authorlist.html @@ -0,0 +1,10 @@ +{%- assign authors=include.authors|split:"," -%} +{%- for author in authors -%} + {%- if author contains "<" -%} + {%- assign authorparts=author|split:"<" -%} + "}}">{{authorparts[0]|strip}} + {%- else -%} + {{author}} + {%- endif -%} + {% if forloop.last == false %}, {% endif %} +{%- endfor -%} diff --git a/_includes/eiptable.html b/_includes/eiptable.html index 409ae05c755e1..db2bcfa4806f3 100644 --- a/_includes/eiptable.html +++ b/_includes/eiptable.html @@ -10,7 +10,7 @@

{{group.name}}

{{page.eip|xml_escape}} {{page.title|xml_escape}} - {{page.author|xml_escape}} + {% include authorlist.html authors=page.author %} {% endfor %} diff --git a/_layouts/eip.html b/_layouts/eip.html index ba4cf00516cc2..f1a226e08591c 100644 --- a/_layouts/eip.html +++ b/_layouts/eip.html @@ -5,7 +5,7 @@

EIP {{ page.eip | xml_escape }}: {{ page.title | xml_escape }}

- + {% if page["discussions-to"] != undefined %} {% endif %} @@ -19,10 +19,10 @@

EIP {{ page.eip | xml_escape }}: {{ page.title | xml_es

{% endif %} {% if page.replaces != undefined %} - + {% endif %} {% if page["superseded-by"] != undefined %} - + {% endif %} {% if page.resolution != undefined %} From 747c296d271b3691cf926cde373c3a6c9cd37335 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 16:15:26 +0000 Subject: [PATCH 0555/1085] Rewrite home page and add more information and links --- _config.yml | 1 - index.html | 41 ++++++++++++++++++++++++----------------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/_config.yml b/_config.yml index 79506bcb8cca6..4c9a80d54e1f5 100644 --- a/_config.yml +++ b/_config.yml @@ -22,7 +22,6 @@ url: "" # the base hostname & protocol for your site, e.g. http://example.com twitter_username: ethereum github_username: ethereum header_pages: - - index.html - core.html - networking.html - interface.html diff --git a/index.html b/index.html index 653eccfd55df3..531c53639a2ce 100644 --- a/index.html +++ b/index.html @@ -17,20 +17,27 @@

EIP status terms

  • Deferred an EIP that is not being considered for immediate adoption. May be reconsidered in the future for a subsequent hard fork.
  • -{% assign statuses = site.pages|map:"status"|uniq %} -{% assign pages = site.pages|sort:"eip" %} -{% for status in statuses %} - {% if status != undefined %} -

    {{status}}

    -
    Author{{ page.author | xml_escape }}
    Author{% include authorlist.html authors=page.author %}
    Discussions-To{{ page["discussions-to"] | xml_escape }}
    Requires{% include eipnums.html eips=page.requires %}
    Replaces{{% include eipnums.html eips=page.replaces %}
    Replaces{% include eipnums.html eips=page.replaces %}
    Superseded by{% include eipnums.html eips=page['superseded-by'] %}
    Superseded by{% include eipnums.html eips=page.superseded-by %}
    Resolution{{ page.resolution | xml_escape }}
    - - - - {% for page in pages %} - {% if page.status == status %} - - {% endif %} - {% endfor %} -
    NumberTitleAuthorLayer
    {{page.eip|xml_escape}}{{page.title|xml_escape}}{{page.author|xml_escape}}{{page.layer|xml_escape}}
    - {% endif %} -{% endfor %} +

    EIP Types

    + +

    EIPs are separated into a number of types, and each has its own list of EIPs.

    + +

    Standard Track

    +

    A Standard Track EIP describes any change that affects most or all Ethereum implementations, such as a change to the the network protocol, a change in block or transaction validity rules, proposed application standards/conventions, or any change or addition that affects the interoperability of applications using Ethereum. Furthermore Standard EIPs can be broken down into the following categories.

    + +

    Core

    +

    Improvements requiring a consensus fork (e.g. EIP5, EIP101), as well as changes that are not necessarily consensus critical but may be relevant to “core dev” discussions (for example, EIP90, and the miner/node strategy changes 2, 3, and 4 of EIP86).

    + +

    Networking

    +

    Includes improvements around devp2p (EIP8) and Light Ethereum Subprotocol, as well as proposed improvements to network protocol specifications of whisper and swarm.

    + +

    Interface

    +

    Includes improvements around client API/RPC specifications and standards, and also certain language-level standards like method names (EIP59, EIP6) and contract ABIs. The label “interface” aligns with the interfaces repo and discussion should primarily occur in that repository before an EIP is submitted to the EIPs repository.

    + +

    ERC

    +

    Application-level standards and conventions, including contract standards such as token standards (ERC20), name registries (ERC26, ERC137), URI schemes (ERC67), library/package formats (EIP82), and wallet formats (EIP75, EIP85).

    + +

    Informational

    +

    Describes a Ethereum design issue, or provides general guidelines or information to the Ethereum community, but does not propose a new feature. Informational EIPs do not necessarily represent Ethereum community consensus or a recommendation, so users and implementers are free to ignore Informational EIPs or follow their advice.

    + +

    Meta

    +

    Describes a process surrounding Ethereum or proposes a change to (or an event in) a process. Process EIPs are like Standards Track EIPs but apply to areas other than the Ethereum protocol itself. They may propose an implementation, but not to Ethereum's codebase; they often require community consensus; unlike Informational EIPs, they are more than recommendations, and users are typically not free to ignore them. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in Ethereum development. Any meta-EIP is also considered a Process EIP.

    From 3c19c59e858a6b17f4f00ee639f407dcf88fa3f9 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 16:18:43 +0000 Subject: [PATCH 0556/1085] Add counts for each type of EIP --- index.html | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/index.html b/index.html index 531c53639a2ce..e920bde9ccd34 100644 --- a/index.html +++ b/index.html @@ -21,23 +21,23 @@

    EIP Types

    EIPs are separated into a number of types, and each has its own list of EIPs.

    -

    Standard Track

    -

    A Standard Track EIP describes any change that affects most or all Ethereum implementations, such as a change to the the network protocol, a change in block or transaction validity rules, proposed application standards/conventions, or any change or addition that affects the interoperability of applications using Ethereum. Furthermore Standard EIPs can be broken down into the following categories.

    +

    Standard Track ({{site.pages|where:"type","Standards Track"|size}})

    +

    Describes any change that affects most or all Ethereum implementations, such as a change to the the network protocol, a change in block or transaction validity rules, proposed application standards/conventions, or any change or addition that affects the interoperability of applications using Ethereum. Furthermore Standard EIPs can be broken down into the following categories.

    -

    Core

    +

    Core ({{site.pages|where:"type","Standards Track"|where:"category","Core"|size}})

    Improvements requiring a consensus fork (e.g. EIP5, EIP101), as well as changes that are not necessarily consensus critical but may be relevant to “core dev” discussions (for example, EIP90, and the miner/node strategy changes 2, 3, and 4 of EIP86).

    -

    Networking

    +

    Networking ({{site.pages|where:"type","Standards Track"|where:"category","Networking"|size}})

    Includes improvements around devp2p (EIP8) and Light Ethereum Subprotocol, as well as proposed improvements to network protocol specifications of whisper and swarm.

    -

    Interface

    +

    Interface ({{site.pages|where:"type","Standards Track"|where:"category","Interface"|size}})

    Includes improvements around client API/RPC specifications and standards, and also certain language-level standards like method names (EIP59, EIP6) and contract ABIs. The label “interface” aligns with the interfaces repo and discussion should primarily occur in that repository before an EIP is submitted to the EIPs repository.

    -

    ERC

    +

    ERC ({{site.pages|where:"type","Standards Track"|where:"category","ERC"|size}})

    Application-level standards and conventions, including contract standards such as token standards (ERC20), name registries (ERC26, ERC137), URI schemes (ERC67), library/package formats (EIP82), and wallet formats (EIP75, EIP85).

    -

    Informational

    +

    Informational ({{site.pages|where:"type","Informational"|size}})

    Describes a Ethereum design issue, or provides general guidelines or information to the Ethereum community, but does not propose a new feature. Informational EIPs do not necessarily represent Ethereum community consensus or a recommendation, so users and implementers are free to ignore Informational EIPs or follow their advice.

    -

    Meta

    +

    Meta ({{site.pages|where:"type","Meta"|size}})

    Describes a process surrounding Ethereum or proposes a change to (or an event in) a process. Process EIPs are like Standards Track EIPs but apply to areas other than the Ethereum protocol itself. They may propose an implementation, but not to Ethereum's codebase; they often require community consensus; unlike Informational EIPs, they are more than recommendations, and users are typically not free to ignore them. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in Ethereum development. Any meta-EIP is also considered a Process EIP.

    From d6c6b341c7c2e2ffc28b2af035bad195b4e778b1 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 16:29:32 +0000 Subject: [PATCH 0557/1085] Add 'all' page --- _config.yml | 1 + _includes/eiptable.html | 2 +- all.html | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 all.html diff --git a/_config.yml b/_config.yml index 4c9a80d54e1f5..6287c5a17f64d 100644 --- a/_config.yml +++ b/_config.yml @@ -22,6 +22,7 @@ url: "" # the base hostname & protocol for your site, e.g. http://example.com twitter_username: ethereum github_username: ethereum header_pages: + - all.html - core.html - networking.html - interface.html diff --git a/_includes/eiptable.html b/_includes/eiptable.html index db2bcfa4806f3..ee746a4069582 100644 --- a/_includes/eiptable.html +++ b/_includes/eiptable.html @@ -1,6 +1,6 @@ {% assign bystatus = include.eips|sort:"eip"|group_by:"status" %} {% for group in bystatus %} - {% if group.name != undefined %} + {% if group.name != "" %}

    {{group.name}}

    diff --git a/all.html b/all.html new file mode 100644 index 0000000000000..d57a5a94c7fc1 --- /dev/null +++ b/all.html @@ -0,0 +1,6 @@ +--- +layout: page +title: All +--- + +{% include eiptable.html eips=site.pages %} From fce8e67161f38837debf22ce25107ee6931ff389 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 16:32:13 +0000 Subject: [PATCH 0558/1085] EIP 779 is meta, not info --- EIPS/eip-779.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-779.md b/EIPS/eip-779.md index 8d422ee04233d..a8669b2aec798 100644 --- a/EIPS/eip-779.md +++ b/EIPS/eip-779.md @@ -1,8 +1,8 @@ --- eip: 779 -title: "Hardfork Info: DAO Fork" +title: "Hardfork Meta: DAO Fork" author: Casey Detrio -type: Informational +type: Meta status: Final created: 2017-11-26 --- From 68729bd541858e37c515fae75f4c9ca800a491c6 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 16:33:20 +0000 Subject: [PATCH 0559/1085] Fix title for informational EIPs listing page --- informational.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/informational.html b/informational.html index 6c322a19c0410..bfe27671758df 100644 --- a/informational.html +++ b/informational.html @@ -1,6 +1,6 @@ --- layout: page -title: Core +title: Informational --- {% assign eips=site.pages|where:"type","Informational" %} From 3933e540912270a48d3f490ffc54e11708735882 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 16:45:09 +0000 Subject: [PATCH 0560/1085] Add link to source on EIP pages --- _layouts/eip.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/_layouts/eip.html b/_layouts/eip.html index f1a226e08591c..23211fa104643 100644 --- a/_layouts/eip.html +++ b/_layouts/eip.html @@ -3,7 +3,10 @@ ---
    -

    EIP {{ page.eip | xml_escape }}: {{ page.title | xml_escape }}

    +

    + EIP {{ page.eip | xml_escape }}: {{ page.title | xml_escape }} + Source +

    {% if page["discussions-to"] != undefined %} From 74aa58c7a56f01b41d4e733674654aa8e391c38c Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 16:47:06 +0000 Subject: [PATCH 0561/1085] Add 'fork on github' banner --- index.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/index.html b/index.html index e920bde9ccd34..9c3c40c210564 100644 --- a/index.html +++ b/index.html @@ -3,6 +3,8 @@ title: Home --- +Fork me on GitHub +

    EIPs Gitter

    Ethereum Improvement Proposals (EIPs) describe standards for the Ethereum platform, including core protocol specifications, client APIs, and contract standards.

    From db62ab204e9143822e9d556250c131e554111352 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 18:15:35 +0000 Subject: [PATCH 0562/1085] Use github metadata for links to github --- _layouts/eip.html | 2 +- index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_layouts/eip.html b/_layouts/eip.html index 23211fa104643..78b1d22d9807f 100644 --- a/_layouts/eip.html +++ b/_layouts/eip.html @@ -5,7 +5,7 @@

    EIP {{ page.eip | xml_escape }}: {{ page.title | xml_escape }} - Source + Source

    Author{% include authorlist.html authors=page.author %}
    diff --git a/index.html b/index.html index 9c3c40c210564..1b2c14e00ab6e 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ title: Home --- -Fork me on GitHub +Fork me on GitHub

    EIPs Gitter

    Ethereum Improvement Proposals (EIPs) describe standards for the Ethereum platform, including core protocol specifications, client APIs, and contract standards.

    From 91397ec3dba41ed7f2b3896830a4bf92c447d246 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Thu, 22 Mar 2018 11:19:51 +0000 Subject: [PATCH 0563/1085] Create CNAME --- CNAME | 1 + 1 file changed, 1 insertion(+) create mode 100644 CNAME diff --git a/CNAME b/CNAME new file mode 100644 index 0000000000000..8739ba436829f --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +eips.ethereum.org \ No newline at end of file From f6a0ec6c37b878b8f063b54a44c60013007f5b99 Mon Sep 17 00:00:00 2001 From: winsvega Date: Thu, 22 Mar 2018 21:51:52 +0300 Subject: [PATCH 0564/1085] Update eip-145.md --- EIPS/eip-145.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/EIPS/eip-145.md b/EIPS/eip-145.md index 68d701363d4e0..03a7ab5890d56 100644 --- a/EIPS/eip-145.md +++ b/EIPS/eip-145.md @@ -363,6 +363,15 @@ Client support: Compiler support: - Solidity/LLL: https://github.com/ethereum/solidity/pull/2541 +## Tests + +Sources: +- https://github.com/ethereum/tests/tree/develop/src/GeneralStateTestsFiller/stShift + +Filled Tests: +- https://github.com/ethereum/tests/tree/develop/GeneralStateTests/stShift +- https://github.com/ethereum/tests/tree/develop/BlockchainTests/GeneralStateTests/stShift + ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 22fdb9aa7a1445bddc37b0a49ed180a0a3551a2c Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Fri, 23 Mar 2018 15:36:33 +0000 Subject: [PATCH 0565/1085] Update EIP-778 header to match the new format. --- EIPS/eip-778.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/EIPS/eip-778.md b/EIPS/eip-778.md index 3b3708c77a962..3931df6c6c2be 100644 --- a/EIPS/eip-778.md +++ b/EIPS/eip-778.md @@ -1,12 +1,12 @@ -# Preamble - - EIP: 778 - Title: Ethereum Node Records (ENR) - Author: Felix Lange - Type: Standard Track - Category Networking - Status: Draft - Created: 2017-11-23 +--- +eip: 778 +title: Ethereum Node Records (ENR) +author: Felix Lange +type: Standard Track +category Networking +status: Draft +created: 2017-11-23 +--- # Abstract From 6bc36d9b435dd0ced9d8aaf640b34a96c455943a Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 21 Mar 2018 18:59:12 +0000 Subject: [PATCH 0566/1085] Add travis configuration --- .travis-ci.sh | 16 ++++++++++++++++ .travis.yml | 28 ++++++++++++++++++++++++++++ Gemfile | 2 ++ Gemfile.lock | 13 +++++++++++++ _config.yml | 2 +- 5 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 .travis-ci.sh create mode 100644 .travis.yml diff --git a/.travis-ci.sh b/.travis-ci.sh new file mode 100644 index 0000000000000..6520091a0757b --- /dev/null +++ b/.travis-ci.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -e # halt script on error + +HTMLPROOFER_OPTIONS="./_site --internal-domains=eips.ethereum.org --check-html --check-opengraph --report-missing-names --log-level=:debug" + +bundle exec jekyll doctor +bundle exec jekyll build + +if [[ $TASK = 'htmlproofer' ]]; then + bundle exec htmlproofer $HTMLPROOFER_OPTIONS --disable-external +elif [[ $TASK = 'htmlproofer-external' ]]; then + bundle exec htmlproofer $HTMLPROOFER_OPTIONS +fi + +# Validate GH Pages DNS setup +bundle exec github-pages health-check diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000000..0584cfda87d9e --- /dev/null +++ b/.travis.yml @@ -0,0 +1,28 @@ +sudo: false # route your build to the container-based infrastructure for a faster build + +language: ruby + +# Cache Ruby bundles +cache: bundler + +before_script: + - bundle exec github-pages versions + +# Assume bundler is being used, therefore +# the `install` step will run `bundle install` by default. +script: "bash -ex .travis-ci.sh" + +env: + global: + - NOKOGIRI_USE_SYSTEM_LIBRARIES=true # speeds up installation of html-proofer + +matrix: + fast_finish: true + include: + - rvm: 2.2.5 + env: TASK='htmlproofer' + - rvm: 2.2.5 + env: TASK='htmlproofer-external' + allow_failures: + - rvm: 2.2.5 + env: TASK='htmlproofer-external' diff --git a/Gemfile b/Gemfile index b566d37debead..b4506e19528be 100644 --- a/Gemfile +++ b/Gemfile @@ -28,3 +28,5 @@ gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby] # Performance-booster for watching directories on Windows gem "wdm", "~> 0.1.0" if Gem.win_platform? + +gem "html-proofer", '>=3.3.1' diff --git a/Gemfile.lock b/Gemfile.lock index 3461dd09e17ab..deffda106763b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,6 +13,7 @@ GEM execjs coffee-script-source (1.11.1) colorator (1.1.0) + colorize (0.8.1) commonmarker (0.17.9) ruby-enum (~> 0.5) concurrent-ruby (1.0.5) @@ -78,6 +79,15 @@ GEM html-pipeline (2.7.1) activesupport (>= 2) nokogiri (>= 1.4) + html-proofer (3.8.0) + activesupport (>= 4.2, < 6.0) + addressable (~> 2.3) + colorize (~> 0.8) + mercenary (~> 0.3.2) + nokogiri (~> 1.8.1) + parallel (~> 1.3) + typhoeus (~> 1.3) + yell (~> 2.0) i18n (0.9.5) concurrent-ruby (~> 1.0) jekyll (3.6.2) @@ -204,6 +214,7 @@ GEM mini_portile2 (~> 2.3.0) octokit (4.8.0) sawyer (~> 0.8.0, >= 0.5.3) + parallel (1.12.1) pathutil (0.16.1) forwardable-extended (~> 2.6) public_suffix (2.0.5) @@ -232,12 +243,14 @@ GEM tzinfo (1.2.5) thread_safe (~> 0.1) unicode-display_width (1.3.0) + yell (2.0.7) PLATFORMS ruby DEPENDENCIES github-pages + html-proofer (>= 3.3.1) jekyll (~> 3.6.2) jekyll-feed (~> 0.6) minima (~> 2.0) diff --git a/_config.yml b/_config.yml index 6287c5a17f64d..0be0816808fd3 100644 --- a/_config.yml +++ b/_config.yml @@ -18,7 +18,7 @@ description: >- Ethereum Improvement Proposals (EIPs) describe standards for the Ethereum platform, including core protocol specifications, client APIs, and contract standards. -url: "" # the base hostname & protocol for your site, e.g. http://example.com +url: "http://eips.ethereum.org" twitter_username: ethereum github_username: ethereum header_pages: From e2232f380ee2c74ee1beb26e1d1056ff3c98e4d3 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Thu, 22 Mar 2018 00:15:05 +0000 Subject: [PATCH 0567/1085] Fix travis build script, and more typos identified by it --- .travis-ci.sh | 4 ++-- EIPS/eip-1.md | 9 +++------ EIPS/eip-107.md | 6 +++--- EIPS/eip-695.md | 2 +- EIPS/eip-721.md | 2 +- EIPS/eip-858.md | 2 +- _config.yml | 2 +- _includes/eipnums.html | 2 +- index.html | 2 +- 9 files changed, 14 insertions(+), 17 deletions(-) mode change 100644 => 100755 .travis-ci.sh diff --git a/.travis-ci.sh b/.travis-ci.sh old mode 100644 new mode 100755 index 6520091a0757b..e58479251b35e --- a/.travis-ci.sh +++ b/.travis-ci.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e # halt script on error -HTMLPROOFER_OPTIONS="./_site --internal-domains=eips.ethereum.org --check-html --check-opengraph --report-missing-names --log-level=:debug" +HTMLPROOFER_OPTIONS="./_site --internal-domains=eips.ethereum.org --check-html --check-opengraph --report-missing-names --log-level=:debug --assume-extension --empty-alt-ignore --url-ignore=/EIPS/eip-1,EIPS/eip-1,/EIPS/eip-107,/EIPS/eip-858" bundle exec jekyll doctor bundle exec jekyll build @@ -9,7 +9,7 @@ bundle exec jekyll build if [[ $TASK = 'htmlproofer' ]]; then bundle exec htmlproofer $HTMLPROOFER_OPTIONS --disable-external elif [[ $TASK = 'htmlproofer-external' ]]; then - bundle exec htmlproofer $HTMLPROOFER_OPTIONS + bundle exec htmlproofer $HTMLPROOFER_OPTIONS --external_only fi # Validate GH Pages DNS setup diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index 8f811514bfc39..6c8b250bcfbed 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -62,7 +62,7 @@ EIPs can also be superseded by a different EIP, rendering the original obsolete. The possible paths of the status of EIPs are as follows: -![](process.png) +![EIP Process](eip-1/process.png) Some Informational and Process EIPs may also have a status of “Active” if they are never meant to be completed. E.g. EIP 1 (this EIP). @@ -220,10 +220,6 @@ Once the EIP is ready for the repository, the EIP editor will: -- List the EIP in [README.md] - - - - Send a message back to the EIP author with next step. Many EIPs are written and maintained by developers with write access to the Ethereum codebase. The EIP editors monitor EIP changes, and correct any structure, grammar, spelling, or markup mistakes we see. @@ -239,6 +235,8 @@ December 7, 2016: EIP 1 has been improved and will be placed as a PR. February 1, 2016: EIP 1 has added editors, made draft improvements to process, and has merged with Master stream. +March 21, 2018: Minor edits to accommodate new automatically-generated EIP directory on eips.ethereum.org. + [EIP5]: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-5.md [EIP101]: https://github.com/ethereum/EIPs/issues/28 [EIP90]: https://github.com/ethereum/EIPs/issues/90 @@ -266,7 +264,6 @@ February 1, 2016: EIP 1 has added editors, made draft improvements to process, a [formal specification]: https://github.com/ethereum/yellowpaper [the Issues section of this repository]: https://github.com/ethereum/EIPs/issues [markdown]: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet - [README.md]: README.md "wikilink" [Bitcoin's BIP-0001]: https://github.com/bitcoin/bips [Python's PEP-0001]: https://www.python.org/dev/peps/ diff --git a/EIPS/eip-107.md b/EIPS/eip-107.md index b39458416adb9..494fdca1279ac 100644 --- a/EIPS/eip-107.md +++ b/EIPS/eip-107.md @@ -29,19 +29,19 @@ Account unlocked : ----------------- When the account is already unlocked, the user is presented with the following popup for every transaction that the dapp attempts to make: -![](authorization.png) +![](eip-107/authorization.png) Account locked and no "personal" api exposed via rpc: ----------------- When the account is locked, and the node does not provide access to account unlocking via its rpc interface, the following popup will be presented. This is not ideal since this requires the user to know how to unlock an account: -![](authorization-locked.png) +![](eip-107/authorization-locked.png) Account locked but node exposing the "personal" api via rpc : ----------------- A better option is to ask the user for their password, but this is only possible if the node allows access to the "personal" api via rpc. In such case, the following dialog will be presented to the user so he/she can accept the transaction by providing the password required to unlock the account: -![](authorization-password.png") +![](eip-107/authorization-password.png) Specification diff --git a/EIPS/eip-695.md b/EIPS/eip-695.md index 6da6bc60588f2..58bb9e70fb50f 100644 --- a/EIPS/eip-695.md +++ b/EIPS/eip-695.md @@ -1,7 +1,7 @@ --- eip: 695 title: Create `eth_chainId` method for JSON-RPC -author: Isaac Ardis Wei Tang , @tcz001 +author: Isaac Ardis Wei Tang , @tcz001 type: Standards Track category: Interface status: Draft diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 975c97dedee39..5b67646925a7d 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -6,7 +6,7 @@ type: Standards Track category: ERC status: Draft created: 2018-01-24 -requires: ERC-165 +requires: 165 --- ## Simple Summary diff --git a/EIPS/eip-858.md b/EIPS/eip-858.md index 391e1703b6fda..b40ed5a4aa175 100644 --- a/EIPS/eip-858.md +++ b/EIPS/eip-858.md @@ -15,7 +15,7 @@ Reduce the block reward to 1 ETH. The current public Ethereum network has a hashrate that corresponds to a tremendous level of energy consumption. As this energy consumption has a correlated environmental cost the network participants have an ethical obligation to ensure this cost is not higher than necessary. At this time, the most direct way to reduce this cost is to lower the block reward in order to limit the appeal of ETH mining. Unchecked growth in hashrate is also counterproductive from a security standpoint. ## Motivation -The current public Ethereum network has a hashrate of 232 TH/s). This hashrate corresponds to a **lower bound** for power usage of roughly [821 MW](calculations.md) and yearly energy consumption of 7.2 TWh (roughly 0.033% of [total](https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption) global electricity consumption). A future switch to full Proof of Stake will solve this issue entirely. Yet that switch remains enough in the future that action should be taken in the interim to limit excess harmful side affects of the present network. +The current public Ethereum network has a hashrate of 232 TH/s). This hashrate corresponds to a **lower bound** for power usage of roughly [821 MW](eip-858/calculations.md) and yearly energy consumption of 7.2 TWh (roughly 0.033% of [total](https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption) global electricity consumption). A future switch to full Proof of Stake will solve this issue entirely. Yet that switch remains enough in the future that action should be taken in the interim to limit excess harmful side affects of the present network. ## Specification Block reward to be changed to 1 ETH / block. diff --git a/_config.yml b/_config.yml index 0be0816808fd3..b5b2020dfe66e 100644 --- a/_config.yml +++ b/_config.yml @@ -36,7 +36,7 @@ theme: minima plugins: - jekyll-feed -permalink: slug +permalink: /:slug defaults: - diff --git a/_includes/eipnums.html b/_includes/eipnums.html index 1c4238b63001a..cd823d545d16c 100644 --- a/_includes/eipnums.html +++ b/_includes/eipnums.html @@ -1,4 +1,4 @@ {% assign eips=include.eips|split:"," %} {% for eipnum in eips %} - {{eipnum}}{% if forloop.last == false %}, {% endif %} + {{eipnum|strip}}{% if forloop.last == false %}, {% endif %} {% endfor %} diff --git a/index.html b/index.html index 1b2c14e00ab6e..093f130bbd5c7 100644 --- a/index.html +++ b/index.html @@ -9,7 +9,7 @@

    EIPs EIP-1. Then clone the repository and add your EIP to it. There is a template EIP here. Then submit a Pull Request to Ethereum's EIPs repository.

    +

    First review EIP-1. Then clone the repository and add your EIP to it. There is a template EIP here. Then submit a Pull Request to Ethereum's EIPs repository.

    EIP status terms

      From 225c00764cc49d1b16b627b9a757e57f98ff6885 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Thu, 22 Mar 2018 14:17:20 +0000 Subject: [PATCH 0568/1085] Add checking for errors in frontmatter --- .travis.yml | 3 --- EIPS/eip-158.md | 2 +- EIPS/eip-190.md | 2 +- EIPS/eip-4.md | 2 +- EIPS/eip-649.md | 2 +- EIPS/eip-8.md | 2 +- 6 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0584cfda87d9e..cfefee4cb1b7f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,9 +5,6 @@ language: ruby # Cache Ruby bundles cache: bundler -before_script: - - bundle exec github-pages versions - # Assume bundler is being used, therefore # the `install` step will run `bundle install` by default. script: "bash -ex .travis-ci.sh" diff --git a/EIPS/eip-158.md b/EIPS/eip-158.md index c5dbef191eaf8..70dcb4c356404 100644 --- a/EIPS/eip-158.md +++ b/EIPS/eip-158.md @@ -4,7 +4,7 @@ title: State clearing author: Vitalik Buterin type: Standards Track category: Core -status: Superseded +status: Replaced created: 2016-10-16 superseded-by: 161 --- diff --git a/EIPS/eip-190.md b/EIPS/eip-190.md index dd0da07e812e8..e256b02c3d02c 100644 --- a/EIPS/eip-190.md +++ b/EIPS/eip-190.md @@ -1,7 +1,7 @@ --- eip: 190 title: Ethereum Smart Contract Packaging Standard -Authors: Piper Merriam, Tim Coulter, Denis Erfurt (mhhf), RJ Catalano (VoR0220), Iuri Matias (iurimatias) +author: Piper Merriam, Tim Coulter, Denis Erfurt (mhhf), RJ Catalano (VoR0220), Iuri Matias (iurimatias) status: Final type: Standards Track category: ERC diff --git a/EIPS/eip-4.md b/EIPS/eip-4.md index 52e310dbcb7d6..7527271265a52 100644 --- a/EIPS/eip-4.md +++ b/EIPS/eip-4.md @@ -4,7 +4,7 @@ layer: Process title: EIP Classification author: Joseph Chow status: Draft -type: Process +type: Meta created: 2015-11-17 --- diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index f679b2248e126..28194bbe67c31 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -1,7 +1,7 @@ --- eip: 649 title: Metropolis Difficulty Bomb Delay and Block Reward Reduction -Authors: Afri Schoedon, Vitalik Buterin +author: Afri Schoedon, Vitalik Buterin type: Standards Track category: Core status: Final diff --git a/EIPS/eip-8.md b/EIPS/eip-8.md index d00a2f40023dd..006e85c1f433d 100644 --- a/EIPS/eip-8.md +++ b/EIPS/eip-8.md @@ -4,7 +4,7 @@ title: devp2p Forward Compatibility Requirements for Homestead author: Felix Lange status: Final type: Standards Track -layer: Networking +category: Networking created: 2015-12-18 --- From 8f40e3414ae61052fe68ed6ae56b0d626decfc72 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Fri, 23 Mar 2018 14:59:29 +0000 Subject: [PATCH 0569/1085] Fix depends field on eip-211 --- EIPS/eip-211.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-211.md b/EIPS/eip-211.md index af0a20c93f10d..6e05501759231 100644 --- a/EIPS/eip-211.md +++ b/EIPS/eip-211.md @@ -6,7 +6,7 @@ type: Standards Track category: Core status: Final created: 2017-02-13 -replaces: 5,8 +replaces: 5 --- ## Simple Summary From 8b379f1e607fe37d8bdaa03714781e3131f156e4 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Fri, 23 Mar 2018 15:00:59 +0000 Subject: [PATCH 0570/1085] Fix link to eip-x in index.html --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 093f130bbd5c7..1b2c14e00ab6e 100644 --- a/index.html +++ b/index.html @@ -9,7 +9,7 @@

      EIPs EIP-1. Then clone the repository and add your EIP to it. There is a template EIP here. Then submit a Pull Request to Ethereum's EIPs repository.

      +

      First review EIP-1. Then clone the repository and add your EIP to it. There is a template EIP here. Then submit a Pull Request to Ethereum's EIPs repository.

      EIP status terms

        From 7c9c6c6eee8ac8b7658c6f72282621123b8bd6d1 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Fri, 23 Mar 2018 15:03:48 +0000 Subject: [PATCH 0571/1085] Remove EIP 75 from index.html --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 1b2c14e00ab6e..32544469a8bd8 100644 --- a/index.html +++ b/index.html @@ -36,7 +36,7 @@

        Interface ({{site.pages|where:"ty

        Includes improvements around client API/RPC specifications and standards, and also certain language-level standards like method names (EIP59, EIP6) and contract ABIs. The label “interface” aligns with the interfaces repo and discussion should primarily occur in that repository before an EIP is submitted to the EIPs repository.

        ERC ({{site.pages|where:"type","Standards Track"|where:"category","ERC"|size}})

        -

        Application-level standards and conventions, including contract standards such as token standards (ERC20), name registries (ERC26, ERC137), URI schemes (ERC67), library/package formats (EIP82), and wallet formats (EIP75, EIP85).

        +

        Application-level standards and conventions, including contract standards such as token standards (ERC20), name registries (ERC26, ERC137), URI schemes (ERC67), library/package formats (EIP82), and wallet formats (EIP85).

        Informational ({{site.pages|where:"type","Informational"|size}})

        Describes a Ethereum design issue, or provides general guidelines or information to the Ethereum community, but does not propose a new feature. Informational EIPs do not necessarily represent Ethereum community consensus or a recommendation, so users and implementers are free to ignore Informational EIPs or follow their advice.

        From a217fc6ef15509b2b022d96202ce76b90a5e52a5 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Fri, 23 Mar 2018 15:05:28 +0000 Subject: [PATCH 0572/1085] Remove reference to EIP 85 from index.html --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 32544469a8bd8..acfb2324b7fa5 100644 --- a/index.html +++ b/index.html @@ -36,7 +36,7 @@

        Interface ({{site.pages|where:"ty

        Includes improvements around client API/RPC specifications and standards, and also certain language-level standards like method names (EIP59, EIP6) and contract ABIs. The label “interface” aligns with the interfaces repo and discussion should primarily occur in that repository before an EIP is submitted to the EIPs repository.

        ERC ({{site.pages|where:"type","Standards Track"|where:"category","ERC"|size}})

        -

        Application-level standards and conventions, including contract standards such as token standards (ERC20), name registries (ERC26, ERC137), URI schemes (ERC67), library/package formats (EIP82), and wallet formats (EIP85).

        +

        Application-level standards and conventions, including contract standards such as token standards (ERC20), name registries (ERC26, ERC137), URI schemes (ERC67), library/package formats (EIP82), and wallet formats (EIP85).

        Informational ({{site.pages|where:"type","Informational"|size}})

        Describes a Ethereum design issue, or provides general guidelines or information to the Ethereum community, but does not propose a new feature. Informational EIPs do not necessarily represent Ethereum community consensus or a recommendation, so users and implementers are free to ignore Informational EIPs or follow their advice.

        From 134eceae93c59c8b3033a7ef538c2cba4f83c967 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Fri, 23 Mar 2018 15:16:00 +0000 Subject: [PATCH 0573/1085] Remove reference to EIP98 from EIP658 --- EIPS/eip-658.md | 1 - 1 file changed, 1 deletion(-) diff --git a/EIPS/eip-658.md b/EIPS/eip-658.md index e5a7cf5d0bb46..d1850a162fd44 100644 --- a/EIPS/eip-658.md +++ b/EIPS/eip-658.md @@ -7,7 +7,6 @@ category: Core status: Final created: 2017-06-30 requires: 140 -replaces: 98 --- ## Abstract From 224c2e9eb5d8f23ca5a6a2b2578983f958af1f31 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Fri, 23 Mar 2018 15:20:00 +0000 Subject: [PATCH 0574/1085] Remove 186 from EIP 649 --- EIPS/eip-649.md | 1 - 1 file changed, 1 deletion(-) diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index 28194bbe67c31..22730f74e0d95 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -6,7 +6,6 @@ type: Standards Track category: Core status: Final created: 2017-06-21 -replaces: 186 --- ## Simple Summary From 3d5b99e4183bab05a22bfc7c0606781cea9c9f2a Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Fri, 23 Mar 2018 15:45:14 +0000 Subject: [PATCH 0575/1085] Remove EIP26 from index.html --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index acfb2324b7fa5..b22a42a92ccb2 100644 --- a/index.html +++ b/index.html @@ -36,7 +36,7 @@

        Interface ({{site.pages|where:"ty

        Includes improvements around client API/RPC specifications and standards, and also certain language-level standards like method names (EIP59, EIP6) and contract ABIs. The label “interface” aligns with the interfaces repo and discussion should primarily occur in that repository before an EIP is submitted to the EIPs repository.

        ERC ({{site.pages|where:"type","Standards Track"|where:"category","ERC"|size}})

        -

        Application-level standards and conventions, including contract standards such as token standards (ERC20), name registries (ERC26, ERC137), URI schemes (ERC67), library/package formats (EIP82), and wallet formats (EIP85).

        +

        Application-level standards and conventions, including contract standards such as token standards (ERC20), name registries (ERC137), URI schemes (ERC67), library/package formats (EIP82), and wallet formats (EIP85).

        Informational ({{site.pages|where:"type","Informational"|size}})

        Describes a Ethereum design issue, or provides general guidelines or information to the Ethereum community, but does not propose a new feature. Informational EIPs do not necessarily represent Ethereum community consensus or a recommendation, so users and implementers are free to ignore Informational EIPs or follow their advice.

        From b30484ad4451d191d589cf053e25cf97d75d67b9 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Fri, 23 Mar 2018 15:46:10 +0000 Subject: [PATCH 0576/1085] Remove EIP59 from index.html --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index b22a42a92ccb2..7f3d88302dc8c 100644 --- a/index.html +++ b/index.html @@ -33,7 +33,7 @@

        Networking ({{site.pages|where:"

        Includes improvements around devp2p (EIP8) and Light Ethereum Subprotocol, as well as proposed improvements to network protocol specifications of whisper and swarm.

        Interface ({{site.pages|where:"type","Standards Track"|where:"category","Interface"|size}})

        -

        Includes improvements around client API/RPC specifications and standards, and also certain language-level standards like method names (EIP59, EIP6) and contract ABIs. The label “interface” aligns with the interfaces repo and discussion should primarily occur in that repository before an EIP is submitted to the EIPs repository.

        +

        Includes improvements around client API/RPC specifications and standards, and also certain language-level standards like method names (EIP6) and contract ABIs. The label “interface” aligns with the interfaces repo and discussion should primarily occur in that repository before an EIP is submitted to the EIPs repository.

        ERC ({{site.pages|where:"type","Standards Track"|where:"category","ERC"|size}})

        Application-level standards and conventions, including contract standards such as token standards (ERC20), name registries (ERC137), URI schemes (ERC67), library/package formats (EIP82), and wallet formats (EIP85).

        From 83e7ff319995e76e34f23cd47a84787ac30074e4 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Fri, 23 Mar 2018 15:47:37 +0000 Subject: [PATCH 0577/1085] Replace EIP67 with EIP681 --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 7f3d88302dc8c..b1b47e9c275c9 100644 --- a/index.html +++ b/index.html @@ -36,7 +36,7 @@

        Interface ({{site.pages|where:"ty

        Includes improvements around client API/RPC specifications and standards, and also certain language-level standards like method names (EIP6) and contract ABIs. The label “interface” aligns with the interfaces repo and discussion should primarily occur in that repository before an EIP is submitted to the EIPs repository.

        ERC ({{site.pages|where:"type","Standards Track"|where:"category","ERC"|size}})

        -

        Application-level standards and conventions, including contract standards such as token standards (ERC20), name registries (ERC137), URI schemes (ERC67), library/package formats (EIP82), and wallet formats (EIP85).

        +

        Application-level standards and conventions, including contract standards such as token standards (ERC20), name registries (ERC137), URI schemes (ERC681), library/package formats (EIP82), and wallet formats (EIP85).

        Informational ({{site.pages|where:"type","Informational"|size}})

        Describes a Ethereum design issue, or provides general guidelines or information to the Ethereum community, but does not propose a new feature. Informational EIPs do not necessarily represent Ethereum community consensus or a recommendation, so users and implementers are free to ignore Informational EIPs or follow their advice.

        From df907bdea86d0189ed48568ad392c1a849c0bb59 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Fri, 23 Mar 2018 15:49:18 +0000 Subject: [PATCH 0578/1085] Replace reference to EIP82 with EIP190 for packaging standard example in index.html --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index b1b47e9c275c9..20b4de1ef6af6 100644 --- a/index.html +++ b/index.html @@ -36,7 +36,7 @@

        Interface ({{site.pages|where:"ty

        Includes improvements around client API/RPC specifications and standards, and also certain language-level standards like method names (EIP6) and contract ABIs. The label “interface” aligns with the interfaces repo and discussion should primarily occur in that repository before an EIP is submitted to the EIPs repository.

        ERC ({{site.pages|where:"type","Standards Track"|where:"category","ERC"|size}})

        -

        Application-level standards and conventions, including contract standards such as token standards (ERC20), name registries (ERC137), URI schemes (ERC681), library/package formats (EIP82), and wallet formats (EIP85).

        +

        Application-level standards and conventions, including contract standards such as token standards (ERC20), name registries (ERC137), URI schemes (ERC681), library/package formats (EIP190), and wallet formats (EIP85).

        Informational ({{site.pages|where:"type","Informational"|size}})

        Describes a Ethereum design issue, or provides general guidelines or information to the Ethereum community, but does not propose a new feature. Informational EIPs do not necessarily represent Ethereum community consensus or a recommendation, so users and implementers are free to ignore Informational EIPs or follow their advice.

        From d456ef0d083228c2b2e226b84c665f71052d8ccf Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Fri, 23 Mar 2018 15:53:42 +0000 Subject: [PATCH 0579/1085] Remove reference to EIP90 in index.html --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 20b4de1ef6af6..08b04f14b1c46 100644 --- a/index.html +++ b/index.html @@ -27,7 +27,7 @@

        Standard Track ({{site.pages|where:"type","Standards Track"|size}})

        Describes any change that affects most or all Ethereum implementations, such as a change to the the network protocol, a change in block or transaction validity rules, proposed application standards/conventions, or any change or addition that affects the interoperability of applications using Ethereum. Furthermore Standard EIPs can be broken down into the following categories.

        Core ({{site.pages|where:"type","Standards Track"|where:"category","Core"|size}})

        -

        Improvements requiring a consensus fork (e.g. EIP5, EIP101), as well as changes that are not necessarily consensus critical but may be relevant to “core dev” discussions (for example, EIP90, and the miner/node strategy changes 2, 3, and 4 of EIP86).

        +

        Improvements requiring a consensus fork (e.g. EIP5, EIP101), as well as changes that are not necessarily consensus critical but may be relevant to “core dev” discussions (for example, the miner/node strategy changes 2, 3, and 4 of EIP86).

        Networking ({{site.pages|where:"type","Standards Track"|where:"category","Networking"|size}})

        Includes improvements around devp2p (EIP8) and Light Ethereum Subprotocol, as well as proposed improvements to network protocol specifications of whisper and swarm.

        From 20c80846149b8c21f5d288f6e6da68bf5bc77a40 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Fri, 23 Mar 2018 16:57:53 +0000 Subject: [PATCH 0580/1085] EIP 101 is draft, not active --- EIPS/eip-101.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-101.md b/EIPS/eip-101.md index ed457b0812339..91dd8d86c108c 100644 --- a/EIPS/eip-101.md +++ b/EIPS/eip-101.md @@ -2,7 +2,7 @@ eip: 101 title: Serenity Currency and Crypto Abstraction author: Vitalik Buterin -status: Active +status: Draft type: Standards Track category: Core created: 2015-11-15 From 1e0fa5bfdc2638a3e21875b24f94307b4962b375 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Fri, 23 Mar 2018 16:58:25 +0000 Subject: [PATCH 0581/1085] Fix email formatting in EIP 140 --- EIPS/eip-140.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-140.md b/EIPS/eip-140.md index f2c896e90f242..744db81490736 100644 --- a/EIPS/eip-140.md +++ b/EIPS/eip-140.md @@ -1,7 +1,7 @@ --- eip: 140 title: REVERT instruction -author: Alex Beregszaszi, Nikolai Mushegian (nikolai@nexusdev.us) +author: Alex Beregszaszi, Nikolai Mushegian type: Standards Track category: Core status: Final From 2fcf894832ba312c8516d8a1f39346fe0c3f6680 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Fri, 23 Mar 2018 22:09:20 +0000 Subject: [PATCH 0582/1085] Remove github banner, update footer link; fix typo in EIP-778 --- EIPS/eip-778.md | 3 +-- index.html | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/EIPS/eip-778.md b/EIPS/eip-778.md index 3931df6c6c2be..66ceb111035bc 100644 --- a/EIPS/eip-778.md +++ b/EIPS/eip-778.md @@ -3,7 +3,7 @@ eip: 778 title: Ethereum Node Records (ENR) author: Felix Lange type: Standard Track -category Networking +category: Networking status: Draft created: 2017-11-23 --- @@ -101,4 +101,3 @@ additional metadata. # Copyright Copyright and related rights waived via CC0. - diff --git a/index.html b/index.html index 08b04f14b1c46..1f88bdc1c65bb 100644 --- a/index.html +++ b/index.html @@ -3,8 +3,6 @@ title: Home --- -Fork me on GitHub -

        EIPs Gitter

        Ethereum Improvement Proposals (EIPs) describe standards for the Ethereum platform, including core protocol specifications, client APIs, and contract standards.

        From d5f1f9e10f7e1417ffa93fcb5f866fa1f2e95a37 Mon Sep 17 00:00:00 2001 From: Tobias Oberstein Date: Sun, 25 Mar 2018 19:24:41 +0200 Subject: [PATCH 0583/1085] copied EIP template to EIP 665 --- EIPS/eip-665.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 EIPS/eip-665.md diff --git a/EIPS/eip-665.md b/EIPS/eip-665.md new file mode 100644 index 0000000000000..e9460c690b0ac --- /dev/null +++ b/EIPS/eip-665.md @@ -0,0 +1,45 @@ +--- +eip: +title: +author: +discussions-to: +status: Draft +type: +category (*only required for Standard Track): +created: +requires (*optional): +replaces (*optional): +--- + +This is the suggested template for new EIPs. + +Note that an EIP number will be assigned by an editor. When opening a pull request to submit your EIP, please use an abbreviated title in the filename, `eip-draft_title_abbrev.md`. + +The title should be 44 characters or less. + +## Simple Summary +"If you can't explain it simply, you don't understand it well enough." Provide a simplified and layman-accessible explanation of the EIP. + +## Abstract +A short (~200 word) description of the technical issue being addressed. + +## Motivation +The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright. + +## Specification +The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (cpp-ethereum, go-ethereum, parity, ethereumj, ethereumjs, ...). + +## Rationale +The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion. + +## Backwards Compatibility +All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright. + +## Test Cases +Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable. + +## Implementation +The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details. + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From a70a025520292830a28e8755f05a71efd36f3e27 Mon Sep 17 00:00:00 2001 From: Tobias Oberstein Date: Sun, 25 Mar 2018 20:55:44 +0200 Subject: [PATCH 0584/1085] add proposal text --- EIPS/eip-665.md | 81 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 22 deletions(-) diff --git a/EIPS/eip-665.md b/EIPS/eip-665.md index e9460c690b0ac..e00f5b7f5a4c4 100644 --- a/EIPS/eip-665.md +++ b/EIPS/eip-665.md @@ -1,45 +1,82 @@ --- -eip: -title: -author: -discussions-to: +eip: 665 +title: Add precompiled contract for Ed25519 signature verification +author: Tobias Oberstein status: Draft -type: -category (*only required for Standard Track): -created: -requires (*optional): -replaces (*optional): +type: Standards Track +category: Core +created: 2018-03-25 --- -This is the suggested template for new EIPs. +## Simple Summary -Note that an EIP number will be assigned by an editor. When opening a pull request to submit your EIP, please use an abbreviated title in the filename, `eip-draft_title_abbrev.md`. +Support performant and cheap verification of Ed25519 cryptographic signatures in smart contracts in general by adding a precompiled contract for Ed25519 signature verification to the EVM. -The title should be 44 characters or less. +## Abstract -## Simple Summary -"If you can't explain it simply, you don't understand it well enough." Provide a simplified and layman-accessible explanation of the EIP. +Verification of Ed25519 cryptographic signatures is obviously possible in EVM bytecode. However, the gas cost will be very high, and computationally expensive, as such tight, wide word operations intensive code as required for Ed25519 is not a good fit for the EVM bytecode model. -## Abstract -A short (~200 word) description of the technical issue being addressed. +The addition of a native compiled function, in a precompiled contract, to the EVM solves both cost and performance problems. ## Motivation -The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright. + +One motivation for Ed25519 signature verification in smart contracts is to associate existing off-chain systems, records or accounts that use Ed25519 with blockchain transactions. + +Another motivation is the processing of external, Ed25519 proof-of-stake based blockchains within Ethereum smart contracts. + +When a transactions contains data that comes with an Ed25519 signature, that proves that the sender of the Ethereum transaction was also in control of the private key (and the data), and this allows the contract to establish an association between the blockchain and the external system or account, and the external system establish the reverse relation. + +For example, a contract might check a Ed25519 signed piece of data submitted to the Ethereum transaction like the current block number. That proves to the contract, that the sender is in possession of both the Ethereum private key and the Ed25518 private key, and hence the contract will accept an association between both. This again can be the root anchor for various powerful applications, as now a potentially crypto holding key owner has proven to be in control of some external off-chain system or account, like e.g. a DNS server, a DNS domain, a cluster node and so on. ## Specification -The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (cpp-ethereum, go-ethereum, parity, ethereumj, ethereumjs, ...). + +The proposal adds a new precompiled function with the following signature + +``` +ed25519verify(bytes32 m, bytes32 pk, bytes32 s1, bytes32 s2) returns (uint8) +``` + +The `ed25519verify` function takes as parameters: + +1. `m` (bytes32): The message that was signed. +2. `pk` (bytes32): The Ed25519 public key of the signer. +3. `s1` (bytes32): The first part of the 64-byte Ed25519 signature. +4. `s2` (bytes32): The second part of the 64-byte Ed25519 signature. + +The `ed25519verify` function returns zero if the signature was valid, and a non-zero value if the signature was invalid. ## Rationale -The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion. + +The proposed `ed25519verify` function takes the signer public key as a call parameter, as with Ed25519, I don't believe it is possible to derive the signers public key from the signature and message alone. + +The proposed `ed25519verify` function uses a zero return value to indicate success, since this allows for different errors to be distinguished by return value, as all non-zero return values signal a verification failure. ## Backwards Compatibility -All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright. + +The proposal is belived not to introduce any backward compatibility issues. ## Test Cases -Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable. + +Test vectors for Ed25519 can be found in this IETF ID https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-6. + +More test vectors can be found in the regression tests of NaCl (see references). ## Implementation -The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details. + +NaCl is a high-quality implementation of Ed25519, available from the same team that created the algorithms and cryptography behind Ed25519. + +The library should allow implementations of the proposed `ed25519verify` function with few lines of code in the hosting Ethereum implementation. + +## References + +* Definition of Ed25519: https://ed25519.cr.yp.to/ed25519-20110926.pdf +* Ed25519 - high-speed high-security signatures: https://ed25519.cr.yp.to/ +* NaCl - Networking and Cryptography library: https://nacl.cr.yp.to/sign.html +* NaCl Crypto Libraries (which contains Ed25519): https://ianix.com/pub/ed25519-deployment.html +* Test vectors for Ed25519: https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-6 +* NaCl regression tests: https://ed25519.cr.yp.to/python/sign.py and https://ed25519.cr.yp.to/python/sign.input +* On the recoverability of public keys from signature+message (alone): https://crypto.stackexchange.com/questions/9936/what-signature-schemes-allow-recovering-the-public-key-from-a-signature ## Copyright + Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 3e9e531fd92f3922a57546ebf029ae2d93c402fb Mon Sep 17 00:00:00 2001 From: Tobias Oberstein Date: Sun, 25 Mar 2018 21:46:11 +0200 Subject: [PATCH 0585/1085] don't use function selectors, but direct input/output encoding in spec --- EIPS/eip-665.md | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/EIPS/eip-665.md b/EIPS/eip-665.md index e00f5b7f5a4c4..9019c4c6ae2f2 100644 --- a/EIPS/eip-665.md +++ b/EIPS/eip-665.md @@ -30,20 +30,27 @@ For example, a contract might check a Ed25519 signed piece of data submitted to ## Specification -The proposal adds a new precompiled function with the following signature +If `block.number >= CONSTANTINOPLE_FORK_BLKNUM`, add a precompiled contract for Ed25519 signature verification (`ED25519VFY`). -``` -ed25519verify(bytes32 m, bytes32 pk, bytes32 s1, bytes32 s2) returns (uint8) -``` +The proposal adds a new precompiled function `ED25519VFY` with the following input and output. -The `ed25519verify` function takes as parameters: +`ED25519VFY` takes as input 128 bytes: -1. `m` (bytes32): The message that was signed. -2. `pk` (bytes32): The Ed25519 public key of the signer. -3. `s1` (bytes32): The first part of the 64-byte Ed25519 signature. -4. `s2` (bytes32): The second part of the 64-byte Ed25519 signature. +1. **message**: The 32-byte message that was signed +2. **public key**: The 32-byte Ed25519 public key of the signer +3. **signature**: The 64-byte Ed25519 signature -The `ed25519verify` function returns zero if the signature was valid, and a non-zero value if the signature was invalid. +`ED25519VFY` returns as output 1 byte: + +1. **result**: `0x00` if signature is valid, else invalid signature + +### Address + +The address of `ED25519VFY` is `0x08`. + +### Gas costs + +Gas cost for `ED25519VFY` is 2000. ## Rationale @@ -51,9 +58,11 @@ The proposed `ed25519verify` function takes the signer public key as a call para The proposed `ed25519verify` function uses a zero return value to indicate success, since this allows for different errors to be distinguished by return value, as all non-zero return values signal a verification failure. +`ECRECOVER` has a gas cost of 3000. Since Ed25519 is computationally cheaper, the gas price should be less. + ## Backwards Compatibility -The proposal is belived not to introduce any backward compatibility issues. +As the proposed precompiled contract is deployed at a reserved (<255) and previously unused address, an implementation of the proposal should not introduce any backward compatibility issues. ## Test Cases From b8b5f87015e4883ecce4aa6c4f6da39ab20db1c7 Mon Sep 17 00:00:00 2001 From: Tobias Oberstein Date: Sun, 25 Mar 2018 21:49:30 +0200 Subject: [PATCH 0586/1085] cosmetics --- EIPS/eip-665.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/EIPS/eip-665.md b/EIPS/eip-665.md index 9019c4c6ae2f2..7e65055b51b26 100644 --- a/EIPS/eip-665.md +++ b/EIPS/eip-665.md @@ -46,17 +46,17 @@ The proposal adds a new precompiled function `ED25519VFY` with the following inp ### Address -The address of `ED25519VFY` is `0x08`. +The address of `ED25519VFY` is **`0x8`.** ### Gas costs -Gas cost for `ED25519VFY` is 2000. +Gas cost for `ED25519VFY` is **2000**. ## Rationale -The proposed `ed25519verify` function takes the signer public key as a call parameter, as with Ed25519, I don't believe it is possible to derive the signers public key from the signature and message alone. +The proposed `ED25519VFY` function takes the signer public key as a call parameter, as with Ed25519, I don't believe it is possible to derive the signers public key from the signature and message alone. -The proposed `ed25519verify` function uses a zero return value to indicate success, since this allows for different errors to be distinguished by return value, as all non-zero return values signal a verification failure. +The proposed `ED25519VFY` function uses a zero return value to indicate success, since this allows for different errors to be distinguished by return value, as all non-zero return values signal a verification failure. `ECRECOVER` has a gas cost of 3000. Since Ed25519 is computationally cheaper, the gas price should be less. From 421a106c79509f7f651cd0622d21c169facc6e67 Mon Sep 17 00:00:00 2001 From: Alex Van de Sande Date: Mon, 26 Mar 2018 10:02:55 -0300 Subject: [PATCH 0587/1085] Updating authors of ENS registrar I'm adding myself as an co-author of this EIP. Nick and Maurelian can vouch that I wrote a large part of this text and helped design the initial mechanisms --- EIPS/eip-162.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-162.md b/EIPS/eip-162.md index 2edda6a9bcf6f..f1781073a7434 100644 --- a/EIPS/eip-162.md +++ b/EIPS/eip-162.md @@ -1,7 +1,7 @@ --- eip: 162 title: Initial ENS Hash Registrar -author: Maurelian and Nick Johnson +author: Maurelian, Nick Johnson , Alex Van de Sande status: Final type: Standards Track category: ERC From 1dd71ebaf8d1f594ac55ffc2dc6076f37d1be300 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Mon, 26 Mar 2018 19:30:59 +0200 Subject: [PATCH 0588/1085] EIP-868: add sequence number to ping and pong --- EIPS/eip-868.md | 61 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/EIPS/eip-868.md b/EIPS/eip-868.md index 41732b42fe4a8..5cfa2b48c6d97 100644 --- a/EIPS/eip-868.md +++ b/EIPS/eip-868.md @@ -18,35 +18,66 @@ resolution of Ethereum Node Records (ENR). To bridge current and future discovery networks and to aid the implementation of other relay mechanisms for ENR such as DNS, we need a way to request the most up-to-date version -of a node record. +of a node record. This EIP provides a way to request it using the existing discovery +protocol. # Specification -Implementations of Node Discovery Protocol v4 should support two new packet types, a request -and reply of the node record. The new packets are: +Implementations of Node Discovery Protocol v4 should support two new packet types, a +request and reply of the node record. The existing ping and pong packets are extended with +a new field containing the sequence number of the ENR. -### enrRequest (0x05) +### Ping Packet (0x01) -RLP: `[ expiration ]` +```text +packet-data = [version, from, to, expiration, enr-seq] +``` -When a packet of this type is received, the node should reply with an enrResponse packet +`enr-seq` is the current sequence number of the sending node's record. All other fields +retain their existing meaning. + +### Pong Packet (0x02) + +```text +packet-data = [to, ping-hash, expiration, enr-seq] +``` + +`enr-seq` is the current sequence number of the sending node's record. All other fields +retain their existing meaning. + +### ENRRequest Packet (0x05) + +```text +packet-data = [ expiration ] +``` + +When a packet of this type is received, the node should reply with an ENRResponse packet containing the current version of its record. -To guard against amplification attacks, the sender of enrRequest should have replied to a -ping packet recently. The expiration field, a UNIX timestamp, should be handled as for all -other existing packets, i.e. no reply should be sent if it refers to a time in the past. +To guard against amplification attacks, the sender of ENRRequest should have replied to a +ping packet recently (just like for FindNode). The `expiration` field, a UNIX timestamp, +should be handled as for all other existing packets i.e. no reply should be sent if it +refers to a time in the past. -### enrResponse (0x06) +### ENRResponse Packet (0x06) -RLP: `[ requestHash, ENR ]` +```text +packet-data = [ request-hash, ENR ] +``` -This packet is the response to enrRequest. +This packet is the response to ENRRequest. -- `requestHash` is the hash of the entire enrRequest packet being replied to. +- `request-hash` is the hash of the entire ENRRequest packet being replied to. - `ENR` is the node record. -The recipient of the packet should verify that the node record is signed by node who -sent enrResponse. +The recipient of the packet should verify that the node record is signed by node who sent +ENRResponse. + +## Resolving Records + +To resolve the current record of a node public key, perform a recursive Kademlia lookup +using the FindNode, Neighbors packets. When the node is found, send ENRRequest to it and +return the record from the response. # Copyright From d2b21d3dcca74c4f03fa2a4ce2fcefe126673296 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Tue, 27 Mar 2018 12:20:50 +0200 Subject: [PATCH 0589/1085] EIP-778: fix type field Use "Standards Track" instead of "Standard Track" to match all other EIPs. --- EIPS/eip-778.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-778.md b/EIPS/eip-778.md index 66ceb111035bc..0f3e3782dcd19 100644 --- a/EIPS/eip-778.md +++ b/EIPS/eip-778.md @@ -2,7 +2,7 @@ eip: 778 title: Ethereum Node Records (ENR) author: Felix Lange -type: Standard Track +type: Standards Track category: Networking status: Draft created: 2017-11-23 From a76a0a0cda032cd41665bf357033fe16d0276d6f Mon Sep 17 00:00:00 2001 From: vbuterin Date: Tue, 27 Mar 2018 10:33:40 -0400 Subject: [PATCH 0590/1085] Create bigint_modexp.md (#198) * Create bigint_modexp.md * Update bigint_modexp.md * Update bigint_modexp.md * Update bigint_modexp.md * Update bigint_modexp.md * Update bigint_modexp.md * Update bigint_modexp.md * Update bigint_modexp.md * Update bigint_modexp.md * Update bigint_modexp.md * Update bigint_modexp.md * Update bigint_modexp.md * Update bigint_modexp.md * Fixing an example after the specification change https://github.com/ethereum/EIPs/pull/198/files#r106236783 * Fix one example after a format change https://github.com/ethereum/EIPs/pull/198/files#r109660742 * Rename bigint_modexp.md to eip-198.md, add new prologue and copyright notice. --- EIPS/eip-198.md | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 EIPS/eip-198.md diff --git a/EIPS/eip-198.md b/EIPS/eip-198.md new file mode 100644 index 0000000000000..c0c053454ff14 --- /dev/null +++ b/EIPS/eip-198.md @@ -0,0 +1,104 @@ +--- +eip: 198 +title: Big integer modular exponentiation +author: Vitalik Buterin +status: Final +type: Standards Track +category: Core +created: 2017-01-30 +--- + +# Parameters + +* `GQUADDIVISOR: 20` + +# Specification + +At address 0x00......05, add a precompile that expects input in the following format: + + + +Where every length is a 32-byte left-padded integer representing the number of bytes to be taken up by the next value. Call data is assumed to be infinitely right-padded with zero bytes, and excess data is ignored. Consumes `floor(mult_complexity(max(length_of_MODULUS, length_of_BASE)) * max(ADJUSTED_EXPONENT_LENGTH, 1) / GQUADDIVISOR)` gas, and if there is enough gas, returns an output `(BASE**EXPONENT) % MODULUS` as a byte array with the same length as the modulus. + +`ADJUSTED_EXPONENT_LENGTH` is defined as follows. + +* If `length_of_EXPONENT <= 32`, and all bits in `EXPONENT` are 0, return 0 +* If `length_of_EXPONENT <= 32`, then return the index of the highest bit in `EXPONENT` (eg. 1 -> 0, 2 -> 1, 3 -> 1, 255 -> 7, 256 -> 8). +* If `length_of_EXPONENT > 32`, then return `8 * (length_of_EXPONENT - 32)` plus the index of the highest bit in the first 32 bytes of `EXPONENT` (eg. if `EXPONENT = \x00\x00\x01\x00.....\x00`, with one hundred bytes, then the result is 8 * (100 - 32) + 253 = 797). If all of the first 32 bytes of `EXPONENT` are zero, return exactly `8 * (length_of_EXPONENT - 32)`. + +`mult_complexity` is a function intended to approximate the difficulty of Karatsuba multiplication (used in all major bigint libraries) and is defined as follows. + +``` +def mult_complexity(x): + if x <= 64: return x ** 2 + elif x <= 1024: return x ** 2 // 4 + 96 * x - 3072 + else: return x ** 2 // 16 + 480 * x - 199680 +``` + +For example, the input data: + + 0000000000000000000000000000000000000000000000000000000000000001 + 0000000000000000000000000000000000000000000000000000000000000020 + 0000000000000000000000000000000000000000000000000000000000000020 + 03 + fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e + fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f + +Represents the exponent `3**(2**256 - 2**32 - 978) % (2**256 - 2**32 - 977)`. By Fermat's little theorem, this equals 1, so the result is: + + 0000000000000000000000000000000000000000000000000000000000000001 + +Returned as 32 bytes because the modulus length was 32 bytes. The `ADJUSTED_EXPONENT_LENGTH` would be 255, and the gas cost would be `mult_complexity(32) * 255 / 20 = 13056` gas (note that this is ~8 times the cost of using the EXP opcode to compute a 32-byte exponent). A 4096-bit RSA exponentiation would cost `mult_complexity(512) * 4095 / 100 = 22853376` gas in the worst case, though RSA verification in practice usually uses an exponent of 3 or 65537, which would reduce the gas consumption to 5580 or 89292, respectively. + +This input data: + + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000020 + 0000000000000000000000000000000000000000000000000000000000000020 + fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e + fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f + +Would be parsed as a base of 0, exponent of `2**256 - 2**32 - 978` and modulus of `2**256 - 2**32 - 977`, and so would return 0. Notice how if the length_of_BASE is 0, then it does not interpret _any_ data as the base, instead immediately interpreting the next 32 bytes as EXPONENT. + +This input data: + + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000020 + ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe + fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd + +Would parse a base length of 0, a exponent length of 32, and an exponent length of `2**256 - 1`, where the base is empty, the exponent is `2**256 - 2` and the modulus is `(2**256 - 3) * 256**(2**256 - 33)` (yes, that's a really big number). It would then immediately fail, as it's not possible to provide enough gas to make that computation. + +This input data: + + 0000000000000000000000000000000000000000000000000000000000000001 + 0000000000000000000000000000000000000000000000000000000000000002 + 0000000000000000000000000000000000000000000000000000000000000020 + 03 + ffff + 8000000000000000000000000000000000000000000000000000000000000000 + 07 + +Would parse as a base of 3, an exponent of 65535, and a modulus of `2**255`, and it would ignore the remaining 0x07 byte. + +This input data: + + 0000000000000000000000000000000000000000000000000000000000000001 + 0000000000000000000000000000000000000000000000000000000000000002 + 0000000000000000000000000000000000000000000000000000000000000020 + 03 + ffff + 80 + +Would also parse as a base of 3, an exponent of 65535 and a modulus of `2**255`, as it attempts to grab 32 bytes for the modulus starting from 0x80, but then there is no further data so it right pads it with 31 zeroes. + +# Rationale + +This allows for efficient RSA verification inside of the EVM, as well as other forms of number theory-based cryptography. Note that adding precompiles for addition and subtraction is not required, as the in-EVM algorithm is efficient enough, and multiplication can be done through this precompile via `a * b = ((a + b)**2 - (a - b)**2) / 4`. + +The bit-based exponent calculation is done specifically to fairly charge for the often-used exponents of 2 (for multiplication) and 3 and 65537 (for RSA verification). + +# Copyright + +Copyright and related rights waived via CC0. From 64f6248f433b4236b44c97a94165238e30510fe2 Mon Sep 17 00:00:00 2001 From: vbuterin Date: Tue, 27 Mar 2018 10:34:04 -0400 Subject: [PATCH 0591/1085] Abstraction of transaction origin and signature.md (#208) * Create abstraction.md Implements a set of changes that serve the combined purpose of "abstracting out" signature verification and nonce checking, allowing users to create "account contracts" that perform any desired signature/nonce checks instead of using the mechanism that is currently hard-coded into transaction processing. * Update abstraction.md * Update abstraction.md * Update abstraction.md * Update abstraction.md * Update abstraction.md * Update abstraction.md * Update abstraction.md * Rename abstraction.md to eip-86.md, add copyright clause, fix header. --- EIPS/eip-86.md | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 EIPS/eip-86.md diff --git a/EIPS/eip-86.md b/EIPS/eip-86.md new file mode 100644 index 0000000000000..0e5102d1ffbbb --- /dev/null +++ b/EIPS/eip-86.md @@ -0,0 +1,98 @@ +``` +eip: 86 +title: Abstraction of transaction origin and signature +author: Vitalik Buterin +type: Standards Track +category: Core +status: Draft +created: 2017-02-10 +``` + +# Summary + +Implements a set of changes that serve the combined purpose of "abstracting out" signature verification and nonce checking, allowing users to create "account contracts" that perform any desired signature/nonce checks instead of using the mechanism that is currently hard-coded into transaction processing. + +# Parameters + +* METROPOLIS_FORK_BLKNUM: TBD +* CHAIN_ID: same as used for EIP 155 (ie. 1 for mainnet, 3 for testnet) +* NULL_SENDER: 2**160 - 1 + +# Specification + +If `block.number >= METROPOLIS_FORK_BLKNUM`, then: +1. If the signature of a transaction is `(CHAIN_ID, 0, 0)` (ie. `r = s = 0`, `v = CHAIN_ID`), then treat it as valid and set the sender address to `NULL_SENDER` +2. Transactions of this form MUST have gasprice = 0, nonce = 0, value = 0, and do NOT increment the nonce of account NULL_SENDER. +3. Create a new opcode at `0xfb`, `CREATE2`, with 4 stack arguments (value, salt, mem_start, mem_size) which sets the creation address to `sha3(sender + salt + sha3(init code)) % 2**160`, where `salt` is always represented as a 32-byte value. +4. Add to _all_ contract creation operations, including transactions and opcodes, the rule that if a contract at that address already exists and has non-empty code OR non-empty nonce, the operation fails and returns 0 as if the init code had run out of gas. If an account has empty code and nonce but nonempty balance, the creation operation may still succeed. + +# Rationale + +The goal of these changes is to set the stage for abstraction of account security. Instead of having an in-protocol mechanism where ECDSA and the default nonce scheme are enshrined as the only "standard" way to secure an account, we take initial steps toward a model where in the long term all accounts are contracts, contracts can pay for gas, and users are free to define their own security model. + +Under EIP 86, we can expect users to store their ether in contracts, whose code might look like the following (example in Serpent): + +```python +# Get signature from tx data +sig_v = ~calldataload(0) +sig_r = ~calldataload(32) +sig_s = ~calldataload(64) +# Get tx arguments +tx_nonce = ~calldataload(96) +tx_to = ~calldataload(128) +tx_value = ~calldataload(160) +tx_gasprice = ~calldataload(192) +tx_data = string(~calldatasize() - 224) +~calldataload(tx_data, 224, ~calldatasize()) +# Get signing hash +signing_data = string(~calldatasize() - 64) +~mstore(signing_data, tx.startgas) +~calldataload(signing_data + 32, 96, ~calldatasize() - 96) +signing_hash = sha3(signing_data:str) +# Perform usual checks +prev_nonce = ~sload(-1) +assert tx_nonce == prev_nonce + 1 +assert self.balance >= tx_value + tx_gasprice * tx.startgas +assert ~ecrecover(signing_hash, sig_v, sig_r, sig_s) == +# Update nonce +~sstore(-1, prev_nonce + 1) +# Pay for gas +~send(MINER_CONTRACT, tx_gasprice * tx.startgas) +# Make the main call +~call(msg.gas - 50000, tx_to, tx_value, tx_data, len(tx_data), 0, 0) +# Get remaining gas payments back +~call(20000, MINER_CONTRACT, 0, [msg.gas], 32, 0, 0) +``` + +This can be thought of as a "forwarding contract". It accepts data from the "entry point" address 2**160 - 1 (an account that anyone can send transactions from), expecting that data to be in the format `[sig, nonce, to, value, gasprice, data]`. The forwarding contract verifies the signature, and if the signature is correct it sets up a payment to the miner and then sends a call to the desired address with the provided value and data. + +The benefits that this provides lie in the most interesting cases: + +- **Multisig wallets**: currently, sending from a multisig wallet requires each operation to be ratified by the participants, and each ratification is a transaction. This could be simplified by having one ratification transaction include signatures from the other participants, but even still it introduces complexity because the participants' accounts all need to be stocked up with ETH. With this EIP, it will be possible to just have the contract store the ETH, send a transaction containing all signatures to the contract directly, and the contract can pay the fees. +- **Ring signature mixers**: the way that ring signature mixers work is that N individuals send 1 coin into a contract, and then use a linkable ring signature to withdraw 1 coin later on. The linkable ring signature ensures that the withdrawal transaction cannot be linked to the deposit, but if someone attempts to withdraw twice then those two signatures can be linked and the second one prevented. However, currently there is a privacy risk: to withdraw, you need to have coins to pay for gas, and if these coins are not properly mixed then you risk compromising your privacy. With this EIP, you can pay for gas straight our of your withdrawn coins. +- **Custom cryptography**: users can upgrade to ed25519 signatures, Lamport hash ladder signatures or whatever other scheme they want on their own terms; they do not need to stick with ECDSA. +- **Non-cryptographic modifications**: users can require transactions to have expiry times (this being standard would allow old empty/dust accounts to be flushed from the state securely), use k-parallelizable nonces (a scheme that allows transactions to be confirmed slightly out-of-order, reducing inter-transaction dependence), or make other modifications. + +(2) and (3) introduce a feature similar to bitcoin's P2SH, allowing users to send funds to addresses that provably map to only one particular piece of code. Something like this is crucial in the long term because, in a world where all accounts are contracts, we need to preserve the ability to send to an account before that account exists on-chain, as that's a basic functionality that exists in all blockchain protocols today. + +# Miner and transaction replaying strategy + +Note that miners would need to have a strategy for accepting these transactions. This strategy would need to be very discriminating, because otherwise they run the risk of accepting transactions that do not pay them any fees, and possibly even transactions that have no effect (eg. because the transaction was already included and so the nonce is no longer current). + +One simple strategy is to have a set of regexps that the to address of an account would be checked against, each regexp corresponding to a "standard account type" which is known to be "safe" (in the sense that if an account has that code, and a particular check involving the account balances, account storage and transaction data passes, then if the transaction is included in a block the miner will get paid), and mine and relay transactions that pass these checks. + +One example would be to check as follows: + +1. Check that the to address has code which is the compiled version of the Serpent code above, with `` replaced with any public key hash. +2. Check that the signature in the transaction data verifies with that key hash. +3. Check that the gasprice in the transaction data is sufficiently high +4. Check that the nonce in the state matches the nonce in the transaction data +5. Check that there is enough ether in the account to pay for the fee + +If all five checks pass, relay and/or mine the transaction. + +A looser but still effective strategy would be to accept any code that fits the same general format as the above, consuming only a limited amount of gas to perform nonce and signature checks and having a guarantee that transaction fees will be paid to the miner. Another strategy is to, alongside other approaches, try to process any transaction that asks for less than 250,000 gas, and include it only if the miner's balance is appropriately higher after executing the transaction than before it. + +# Copyright + +Copyright and related rights waived via CC0. From 48bec76f5885098a571f21e545f7bba307972d25 Mon Sep 17 00:00:00 2001 From: John Forrest Date: Thu, 15 Mar 2018 17:09:22 -0500 Subject: [PATCH 0592/1085] Update operator language - Fixed typo (operator to operators) - Explicitly call out the implementation MUST support multiple operators per owner as implied by the comments - Removed unnecessary throw from the dev instructions on setApprovalForAll --- EIPS/eip-721.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 5b67646925a7d..50e530ccd6056 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -60,7 +60,8 @@ interface ERC721 /* is ERC165 */ { event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId); /// @dev This emits when an operator is enabled or disabled for an owner. - /// The operator can manage all NFTs of the owner. + /// The operator can manage all NFTs of the owner. The contract MUST allow + /// multiple operators per owner. event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); /// @notice Count all NFTs assigned to an owner @@ -123,7 +124,7 @@ interface ERC721 /* is ERC165 */ { /// all of `msg.sender`'s assets. /// @dev Emits the ApprovalForAll event /// @param _operator Address to add to the set of authorized operators. - /// @param _approved True if the operators is approved, false to revoke approval + /// @param _approved True if the operator is approved, false to revoke approval function setApprovalForAll(address _operator, bool _approved) external; /// @notice Get the approved address for a single NFT From 87f1091c0cb2df961fbd8085cc56de8a039b2af6 Mon Sep 17 00:00:00 2001 From: John Forrest Date: Tue, 27 Mar 2018 10:48:17 -0500 Subject: [PATCH 0593/1085] Moving operator language to function instead of event --- EIPS/eip-721.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-721.md b/EIPS/eip-721.md index 50e530ccd6056..33579a8237596 100644 --- a/EIPS/eip-721.md +++ b/EIPS/eip-721.md @@ -60,8 +60,7 @@ interface ERC721 /* is ERC165 */ { event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId); /// @dev This emits when an operator is enabled or disabled for an owner. - /// The operator can manage all NFTs of the owner. The contract MUST allow - /// multiple operators per owner. + /// The operator can manage all NFTs of the owner. event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); /// @notice Count all NFTs assigned to an owner @@ -122,7 +121,8 @@ interface ERC721 /* is ERC165 */ { /// @notice Enable or disable approval for a third party ("operator") to manage /// all of `msg.sender`'s assets. - /// @dev Emits the ApprovalForAll event + /// @dev Emits the ApprovalForAll event. The contract MUST allow + /// multiple operators per owner. /// @param _operator Address to add to the set of authorized operators. /// @param _approved True if the operator is approved, false to revoke approval function setApprovalForAll(address _operator, bool _approved) external; From abcf1153ae3939fab9dd30fae8a94c26c9d18db6 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Tue, 27 Mar 2018 17:24:00 +0100 Subject: [PATCH 0594/1085] Add EIP validation check, and fix issues identified by it. (#954) * Update social includes to link to repo, not org * Add support for eip_validator by Makoto Inoue * Fix external links in EIPs * Change eip_validator to 0.3.0 * Fix dependency issues * Update eip_validator to 0.3.4 * Add more condition on EIP input files * Bump eip_validator to ignore invalid eip file format * Fix EIP 86 --- .travis-ci.sh | 9 ++++++--- .travis.yml | 2 ++ EIPS/eip-162.md | 4 ++-- EIPS/eip-190.md | 2 +- EIPS/eip-55.md | 2 +- EIPS/eip-616.md | 4 ++-- EIPS/eip-649.md | 2 +- EIPS/eip-86.md | 4 ++-- Gemfile | 2 ++ Gemfile.lock | 9 +++++++++ _includes/social.html | 14 ++++++++++++++ 11 files changed, 42 insertions(+), 12 deletions(-) create mode 100644 _includes/social.html diff --git a/.travis-ci.sh b/.travis-ci.sh index e58479251b35e..e355a484c461d 100755 --- a/.travis-ci.sh +++ b/.travis-ci.sh @@ -3,13 +3,16 @@ set -e # halt script on error HTMLPROOFER_OPTIONS="./_site --internal-domains=eips.ethereum.org --check-html --check-opengraph --report-missing-names --log-level=:debug --assume-extension --empty-alt-ignore --url-ignore=/EIPS/eip-1,EIPS/eip-1,/EIPS/eip-107,/EIPS/eip-858" -bundle exec jekyll doctor -bundle exec jekyll build - if [[ $TASK = 'htmlproofer' ]]; then + bundle exec jekyll doctor + bundle exec jekyll build bundle exec htmlproofer $HTMLPROOFER_OPTIONS --disable-external elif [[ $TASK = 'htmlproofer-external' ]]; then + bundle exec jekyll doctor + bundle exec jekyll build bundle exec htmlproofer $HTMLPROOFER_OPTIONS --external_only +elif [[ $TASK = 'eip-validator' ]]; then + bundle exec eip_validator EIPS/*.md fi # Validate GH Pages DNS setup diff --git a/.travis.yml b/.travis.yml index cfefee4cb1b7f..6823fc5fe2ee1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,8 @@ matrix: env: TASK='htmlproofer' - rvm: 2.2.5 env: TASK='htmlproofer-external' + - rvm: 2.2.5 + env: TASK='eip-validator' allow_failures: - rvm: 2.2.5 env: TASK='htmlproofer-external' diff --git a/EIPS/eip-162.md b/EIPS/eip-162.md index f1781073a7434..02f6b13f4aade 100644 --- a/EIPS/eip-162.md +++ b/EIPS/eip-162.md @@ -39,7 +39,7 @@ For more background, refer to [EIP 137](https://github.com/ethereum/EIPs/issues/ A well designed and governed registrar is essential to the success of the ENS described in EIP 137, but is described separately in this document as it is external to the core ENS protocol. -In order to maximize utility and adoption of a new namespace, the registrar should mitigate speculation and "name squatting", however the best approach for mitigation is unclear. Thus an "initial" registrar is proposed, which implements a simple approach to name allocation. During the initial period, the available namespace will be significantly restricted to the `.eth` top level domain, and subdomain shorter than 7 characters in length disallowed. This specification largely describes @alexvandesande and @arachnid's [hash registrar implementation](https://github.com/Arachnid/ens/blob/master/HashRegistrarSimplified.sol) in order to facilitate discussion. +In order to maximize utility and adoption of a new namespace, the registrar should mitigate speculation and "name squatting", however the best approach for mitigation is unclear. Thus an "initial" registrar is proposed, which implements a simple approach to name allocation. During the initial period, the available namespace will be significantly restricted to the `.eth` top level domain, and subdomain shorter than 7 characters in length disallowed. This specification largely describes @alexvandesande and @arachnid's [hash registrar implementation](https://github.com/ethereum/ens/blob/mainnet/contracts/HashRegistrarSimplified.sol) in order to facilitate discussion. The intent is to replace the Initial Registrar contract with a permanent registrar contract. The Permanent Registrar will increase the available namespace, and incorporate lessons learned from the performance of the Initial Registrar. This upgrade is expected to take place within approximately 2 years of initial deployment. @@ -237,7 +237,7 @@ This approach is simpler than the familiar model of requiring owners to make rec This document borrows heavily from several sources: - [EIP 137](https://github.com/ethereum/EIPs/issues/137) outlines the initial implementation of the Registry Contract (ENS.sol) and associated Resolver contracts. - [ERC 26](https://github.com/ethereum/EIPs/issues/26) was the first ERC to propose a name service at the contract layer -- @alexvandesande's current implementation of the [HashRegistrar](https://github.com/Arachnid/ens/blob/master/HashRegistrarSimplified.sol) +- @alexvandesande's current implementation of the [HashRegistrar](https://github.com/ethereum/ens/blob/mainnet/contracts/HashRegistrarSimplified.sol) ### Edits: - 2016-10-26 Added link Alex's design in abstract diff --git a/EIPS/eip-190.md b/EIPS/eip-190.md index e256b02c3d02c..4ef242fc57d7a 100644 --- a/EIPS/eip-190.md +++ b/EIPS/eip-190.md @@ -93,4 +93,4 @@ Support for ERC190 is either implemented or in progress for the following: * [Dapple](http://dapple.readthedocs.io/en/master/) * [Eris PM](https://github.com/eris-ltd/eris-cli) * [Embark](https://github.com/iurimatias/embark-framework) -* [Browser Solidity](https://github.com/ethereum/browser-solidity/issues/386) +* [Browser Solidity](https://github.com/ethereum/remix-ide/issues/386) diff --git a/EIPS/eip-55.md b/EIPS/eip-55.md index caab54a64acd3..6d85ea211a1b1 100644 --- a/EIPS/eip-55.md +++ b/EIPS/eip-55.md @@ -123,4 +123,4 @@ Note that the input to the Keccak256 hash is the lowercase hexadecimal string (i 2. Python example by @Recmo https://github.com/ethereum/eips/issues/55#issuecomment-261521584 3. Python implementation in [`ethereum-utils`](https://github.com/pipermerriam/ethereum-utils#to_checksum_addressvalue---text) 4. Ethereumjs-util implementation https://github.com/ethereumjs/ethereumjs-util/blob/75f529458bc7dc84f85fd0446d0fac92d991c262/index.js#L452-L466 -5. Swift implementation in [`EthereumKit`](https://github.com/yuzushioh/EthereumKit/blob/master/EthereumKit/EIP55.swift) +5. Swift implementation in [`EthereumKit`](https://github.com/yuzushioh/EthereumKit/blob/master/EthereumKit/Helper/EIP55.swift) diff --git a/EIPS/eip-616.md b/EIPS/eip-616.md index 76b5dc22af5eb..6de3977e4b8de 100644 --- a/EIPS/eip-616.md +++ b/EIPS/eip-616.md @@ -103,7 +103,7 @@ Extended operations other than XSHUFFLE and XCAST are only valid on vectors of t ### Subroutines -If [EIP 187](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-187.md) is accepted a typpe-safe syntax for declaring subroutines taking vector arguments will be needed. +If [EIP 187](https://github.com/ethereum/EIPs/pull/187) is accepted a type-safe syntax for declaring subroutines taking vector arguments will be needed. * `BEGINSUBX n_args, arg_types... n_results, result_types...` marks the **single** entry to a subroutine. `n_args` items are taken off of the stack at entry to, and `n_results` items are placed on the stack at return from the subroutine. `n_args` and `n_results` are given as one immediate byte each. The `arg_types` and `result_types` are given in the same encoding as second byte of the SIMD opcodes, and must match the values on the stack. The bytecode for a subroutine ends at the next `BEGINSUB`, `BEGINSUBX` or `BEGINDATA` instruction or at the end of the bytecode. @@ -129,7 +129,7 @@ divide | 15 _N_**2 + 119 _N_ + 111 | 409 | 827 | 2023 The remaining operations are of about the same complexity as addition and subtraction, or less. Given that JUMPDEST is a no-op, and is assigned a gas price of 1, this can be taken as the overhead of the interpreter. All of the arithmetic operations are assigned the same gas price of 5, for a remaining runtime of 4. The interpreter loop itself takes about 6 to 8 C instructions, so ADD and SUB are reasonably priced, but MUL is some 5 to 21 times slower than ADD or SUB, and DIV is some 15 to 23 times slower, so they are clearly mispriced. -By comparison, on most [Intel](https://software.intel.com/sites/landingpage/IntrinsicsGuide) and [ARM](https://developer.arm.com/docs/100166_0001/latest/programmers-model/instruction-set-summary/table-of-processor-instructions) SIMD units instructions take approximately the following cycle counts, independent of register width. +By comparison, on most [Intel](https://software.intel.com/sites/landingpage/IntrinsicsGuide) and [ARM](https://developer.arm.com/docs/100166/latest/programmers-model/instruction-set-summary/table-of-processor-instructions) SIMD units instructions take approximately the following cycle counts, independent of register width. operation | Intel cycles | ARM cycles | gas -|-|-|- diff --git a/EIPS/eip-649.md b/EIPS/eip-649.md index 22730f74e0d95..1156ecf64a4d4 100644 --- a/EIPS/eip-649.md +++ b/EIPS/eip-649.md @@ -67,7 +67,7 @@ The Yellow Paper implements EIP-649 in [#333](https://github.com/ethereum/yellow Other notable implementations: - Eth-Isabelle [#459](https://github.com/pirapira/eth-isabelle/issues/459) -- Py-EVM [#123](https://github.com/pipermerriam/py-evm/pull/123) +- Py-EVM [#123](https://github.com/ethereum/py-evm/pull/123) ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/EIPS/eip-86.md b/EIPS/eip-86.md index 0e5102d1ffbbb..6b9494b9ecd8c 100644 --- a/EIPS/eip-86.md +++ b/EIPS/eip-86.md @@ -1,4 +1,4 @@ -``` +--- eip: 86 title: Abstraction of transaction origin and signature author: Vitalik Buterin @@ -6,7 +6,7 @@ type: Standards Track category: Core status: Draft created: 2017-02-10 -``` +--- # Summary diff --git a/Gemfile b/Gemfile index b4506e19528be..8d925e1ff2eee 100644 --- a/Gemfile +++ b/Gemfile @@ -30,3 +30,5 @@ gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby] gem "wdm", "~> 0.1.0" if Gem.win_platform? gem "html-proofer", '>=3.3.1' + +gem "eip_validator", ">=0.4.0" diff --git a/Gemfile.lock b/Gemfile.lock index deffda106763b..75cee1396fe6b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,9 @@ GEM remote: https://rubygems.org/ specs: + activemodel (4.2.9) + activesupport (= 4.2.9) + builder (~> 3.1) activesupport (4.2.9) i18n (~> 0.7) minitest (~> 5.1) @@ -8,6 +11,7 @@ GEM tzinfo (~> 1.1) addressable (2.5.2) public_suffix (>= 2.0.2, < 4.0) + builder (3.2.3) coffee-script (2.4.1) coffee-script-source execjs @@ -17,6 +21,9 @@ GEM commonmarker (0.17.9) ruby-enum (~> 0.5) concurrent-ruby (1.0.5) + eip_validator (0.4.0) + activemodel + front_matter_parser (~> 0.1.1) ethon (0.11.0) ffi (>= 1.3.0) execjs (2.7.0) @@ -24,6 +31,7 @@ GEM multipart-post (>= 1.2, < 3) ffi (1.9.23) forwardable-extended (2.6.0) + front_matter_parser (0.1.1) gemoji (3.0.0) github-pages (179) activesupport (= 4.2.9) @@ -249,6 +257,7 @@ PLATFORMS ruby DEPENDENCIES + eip_validator (>= 0.4.0) github-pages html-proofer (>= 3.3.1) jekyll (~> 3.6.2) diff --git a/_includes/social.html b/_includes/social.html new file mode 100644 index 0000000000000..9783b84a2e269 --- /dev/null +++ b/_includes/social.html @@ -0,0 +1,14 @@ + From 3ba7271546f44e2a707f921b24b2de4c89feae4b Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Tue, 27 Mar 2018 19:49:09 +0100 Subject: [PATCH 0595/1085] Discussions-to is not necessarily an email address --- _layouts/eip.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_layouts/eip.html b/_layouts/eip.html index 78b1d22d9807f..41980eee48a22 100644 --- a/_layouts/eip.html +++ b/_layouts/eip.html @@ -10,7 +10,7 @@

    Author{% include authorlist.html authors=page.author %}
    {% if page["discussions-to"] != undefined %} - + {% endif %} From 5331b3942c4bd2230fd4499f0531b5844e8600d9 Mon Sep 17 00:00:00 2001 From: Dean Eigenmann Date: Tue, 27 Mar 2018 22:15:23 +0200 Subject: [PATCH 0596/1085] ERC900: Simple Staking Interface (#910) * Create eip-900.md * Update eip-900.md * Update eip-900.md * Update eip-900.md * Update eip-900.md * Update eip-900.md * Update eip-900.md * Update eip-900.md --- EIPS/eip-900.md | 108 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 EIPS/eip-900.md diff --git a/EIPS/eip-900.md b/EIPS/eip-900.md new file mode 100644 index 0000000000000..9d2afa21eb9e7 --- /dev/null +++ b/EIPS/eip-900.md @@ -0,0 +1,108 @@ +--- +eip: 900 +title: Simple Staking Interface +author: Dean Eigenmann , Jorge Izquierdo +type: Standards Track +category: ERC +status: Final +created: 2018-02-22 +discussions-to: https://github.com/ethereum/EIPs/issues/900 +--- + +## Abstract + +The following standard describes a common staking interface allowing for easy to use staking systems. The interface is kept simple allowing for various use cases to be implemented. This standard describes the common functionality for staking as well as providing information on stakes. + +## Motivation + +As we move to more token models, having a common staking interface which is familiar to users can be useful. The common interface can be used by a variety of applications, this common interface could be beneficial especially to things like Token curated registries which have recently gained popularity. + +## Specification + +```solidity +interface Staking { + + event Staked(address indexed user, uint256 amount, uint256 total, bytes data); + event Unstaked(address indexed user, uint256 amount, uint256 total, bytes data); + + function stake(uint256 amount, bytes data) public; + function stakeFor(address user, uint256 amount, bytes data) public; + function unstake(uint256 amount, bytes data) public; + function totalStakedFor(address addr) public view returns (uint256); + function totalStaked() public view returns (uint256); + function token() public view returns (address); + function supportsHistory() public pure returns (bool); + + // optional + function lastStakedFor(address addr) public view returns (uint256); + function totalStakedForAt(address addr, uint256 blockNumber) public view returns (uint256); + function totalStakedAt(uint256 blockNumber) public view returns (uint256); +} +``` + +### stake + +Stakes a certain amount of tokens, this MUST transfer the given amount from the user. + +*The data field can be used to add signalling information in more complex staking applications* + +MUST trigger ```Staked``` event. + +### stakeFor + +Stakes a certain amount of tokens, this MUST transfer the given amount from the caller. + +*The data field can be used to add signalling information in more complex staking applications* + +MUST trigger ```Staked``` event. + +### unstake + +Unstakes a certain amount of tokens, this SHOULD return the given amount of tokens to the user, if unstaking is currently not possible the function MUST revert. + +*The data field can be used to remove signalling information in more complex staking applications* + +MUST trigger ```Unstaked``` event. + +### totalStakedFor + +Returns the current total of tokens staked for an address. + +### totalStaked + +Returns the current total of tokens staked. + +### token + +Address of the token being used by the staking interface. + +### supportsHistory + +MUST return true if the optional history functions are implemented, otherwise false. + +### lastStakedFor + +***OPTIONAL:** As not all staking systems require a complete history, this function is optional.* + +Returns last block address staked at. + +### totalStakedForAt + +***OPTIONAL:** As not all staking systems require a complete history, this function is optional.* + +Returns total amount of tokens staked at block for address. + +### totalStakedAt + +***OPTIONAL:** As not all staking systems require a complete history, this function is optional.* + +Returns the total tokens staked at block. + +## Implementation + +- [Stakebank](https://github.com/HarbourProject/stakebank) +- [Aragon](https://github.com/aragon/aragon-apps/pull/101) +- [PoS Staking](https://github.com/maticnetwork/contracts/blob/master/contracts/StakeManager.sol) + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 3a3f22427229a2679d3ac2f6e1ea96367bdd753e Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Tue, 27 Mar 2018 21:47:37 +0100 Subject: [PATCH 0597/1085] Retcon: EIP 900 is still draft, not final. --- EIPS/eip-900.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-900.md b/EIPS/eip-900.md index 9d2afa21eb9e7..e7ff4c954795e 100644 --- a/EIPS/eip-900.md +++ b/EIPS/eip-900.md @@ -4,7 +4,7 @@ title: Simple Staking Interface author: Dean Eigenmann , Jorge Izquierdo type: Standards Track category: ERC -status: Final +status: Draft created: 2018-02-22 discussions-to: https://github.com/ethereum/EIPs/issues/900 --- From f066264f45daafc7eb8b7a771a217c53020d9d48 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Wed, 28 Mar 2018 13:37:04 +0100 Subject: [PATCH 0598/1085] Update README, make table widths consistent (#955) * Update README, make table widths consistent * Add list of EIP statuses to set deterministic order --- README.md | 70 ++--------------------------------------- _data/statuses.yaml | 5 +++ _includes/eiptable.html | 30 ++++++++++++------ 3 files changed, 27 insertions(+), 78 deletions(-) create mode 100644 _data/statuses.yaml diff --git a/README.md b/README.md index e54d2b9acadbd..01c4be09c4a7b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # EIPs [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ethereum/EIPs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) Ethereum Improvement Proposals (EIPs) describe standards for the Ethereum platform, including core protocol specifications, client APIs, and contract standards. +A browsable version of all current and draft EIPs can be found on [the official EIP site](http://eips.ethereum.org/). + # Contributing First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP to it. There is a [template EIP here](eip-X.md). Then submit a Pull Request to Ethereum's [EIPs repository](https://github.com/ethereum/EIPs). @@ -9,71 +11,3 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP * **Accepted** - an EIP that is planned for immediate adoption, i.e. expected to be included in the next hard fork (for Core/Consensus layer EIPs). * **Final** - an EIP that has been adopted in a previous hard fork (for Core/Consensus layer EIPs). * **Deferred** - an EIP that is not being considered for immediate adoption. May be reconsidered in the future for a subsequent hard fork. - -# Non-final EIPs -| Number | Title | Author | Layer | Status | -| ------------------------- | ------------------------------------------------------- | ----------------------------- | --------- | ---------- | -| [3](EIPS/eip-3.md) | Addition of CALLDEPTH opcode | Martin Holst Swende | Core | Draft | -| [4](EIPS/eip-4.md) | EIP Classification | Joseph Chow | Meta | Draft | -| [5](EIPS/eip-5.md) | Gas Usage for `RETURN` and `CALL*` | Christian Reitwiessner | Core | Draft | -| [101](EIPS/eip-101.md) | Serenity Currency and Crypto Abstraction | Vitalik Buterin | | Active | -| [158](EIPS/eip-158.md) | State clearing | Vitalik Buterin | Core | Superseded | -| [165](EIPS/eip-165.md) | ERC-165 Standard Interface Detection | Christian Reitwiessner | Interface | Draft | -| [234](EIPS/eip-234.md) | Add `blockHash` to JSON-RPC filter options | Micah Zoltu | Interface | Draft | -| [615](EIPS/eip-615.md) | Subroutines and Static Jumps for the EVM | Greg Colvin | Core | Draft | -| [616](EIPS/eip-616.md) | SIMD Operations for the EVM | Greg Colvin | Core | Draft | -| [681](EIPS/eip-681.md) | ERC-681 URL Format for Transaction Requests | Daniel A. Nagy | Interface | Draft | -| [758](EIPS/eip-758.md) | Subscriptions and filters for transaction return data | Jack Peterson | Interface | Draft | -| [801](EIPS/eip-801.md) | ERC-801 Canary Standard | ligi | Interface | Draft | - -# Deferred EIPs -| Number | Title | Author | Layer | Status | -| -------------------------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------ | ---------- | -------- | -| [86](https://github.com/ethereum/EIPs/pull/208) | Abstraction of transaction origin and signature | Vitalik Buterin | Core | Deferred (to be replaced) | -| [96](https://github.com/ethereum/EIPs/pull/210) | Blockhash refactoring | Vitalik Buterin | Core | Deferred | -| [145](EIPS/eip-145.md) | Bitwise shifting instructions in EVM | Alex Beregszaszi, Paweł Bylica | Core | Deferred | - -# Finalized EIPs (standards that have been adopted) -| Number | Title | Author | Layer | Status | -| -------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------| ---------- | -------- | -| [2](EIPS/eip-2.md) | Homestead Hard-fork Changes | Vitalik Buterin | Core | Final | -| [6](EIPS/eip-6.md) | Renaming Suicide Opcode | Hudson Jameson | Interface | Final | -| [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Core | Final | -| [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Networking | Final | -| [20](EIPS/eip-20-token-standard.md) | ERC-20 Token Standard | Fabian Vogelsteller, Vitalik Buterin | ERC | Final | -| [55](EIPS/eip-55.md) | ERC-55 Mixed-case checksum address encoding | Vitalik Buterin | ERC | Final | -| [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Core | Final | -| [137](EIPS/eip-137.md) | Ethereum Domain Name Service - Specification | Nick Johnson | ERC | Final | -| [140](https://github.com/ethereum/EIPs/pull/206) | REVERT instruction | Alex Beregszaszi, Nikolai Mushegian | Core | Final | -| [141](EIPS/eip-141.md) | Designated invalid EVM instruction | Alex Beregszaszi | Core | Final | -| [150](EIPS/eip-150.md) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Core | Final | -| [155](EIPS/eip-155.md) | Simple replay attack protection | Vitalik Buterin | Core | Final | -| [160](EIPS/eip-160.md) | EXP cost increase | Vitalik Buterin | Core | Final | -| [161](EIPS/eip-161.md) | State trie clearing (invariant-preserving alternative) | Gavin Wood | Core | Final | -| [162](EIPS/eip-162.md) | ERC-162 Initial ENS Hash Registrar | Maurelian, Nick Johnson | ERC | Final | -| [170](EIPS/eip-170.md) | Contract code size limit | Vitalik Buterin | Core | Final | -| [181](EIPS/eip-181.md) | ERC-181 ENS support for reverse resolution of Ethereum addresses | Nick Johnson | ERC | Final | -| [190](EIPS/eip-190.md) | ERC-190 Ethereum Smart Contract Packaging Standard | Merriam, Coulter, Erfurt, Catalano, Matias | ERC | Final | -| [196](https://github.com/ethereum/EIPs/pull/213) | Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 | Christian Reitwiessner | Core | Final | -| [197](https://github.com/ethereum/EIPs/pull/212) | Precompiled contracts for optimal Ate pairing check on the elliptic curve alt_bn128 | Vitalik Buterin, Christian Reitwiessner | Core | Final | -| [198](https://github.com/ethereum/EIPs/pull/198) | Precompiled contract for bigint modular exponentiation | Vitalik Buterin | Core | Final | -| [211](https://github.com/ethereum/EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner | Core | Final | -| [214](https://github.com/ethereum/EIPs/pull/214) | New opcode STATICCALL | Vitalik Buterin, Christian Reitwiessner | Core | Final | -| [649](https://github.com/ethereum/EIPs/pull/669) | Metropolis Difficulty Bomb Delay and Block Reward Reduction | Afri Schoedon, Vitalik Buterin | Core | Final | -| [658](https://github.com/ethereum/EIPs/pull/658) | Embedding transaction status code in receipts | Nick Johnson | Core | Final | -| [706](EIPS/eip-706.md) | DEVp2p snappy compression | Péter Szilágyi | Networking | Final | - -# Active EIPs (standards that have been adopted but never meant to be completed) - -| Number | Title | Author | Layer | Status | -| -------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------| ---------- | -------- | -| [1](EIPS/eip-1.md) | EIP Purpose and Guidelines | Martin Becze, Hudson Jameson | Meta | Active | - -# Past Hard Forks -| Codename | Aliases | Block number | Date (UTC) | -|-------------------------------------- |---------------------------- |----------------|------------| -| [Homestead](EIPS/eip-606.md) | | 1,150,000 | 2016-03-14 | -| [DAO Fork](EIPS/eip-779.md) | | 1,920,000 | 2016-07-20 | -| [Tangerine Whistle](EIPS/eip-608.md) | Anti-DoS, EIP 150 | 2,463,000 | 2016-10-18 | -| [Spurious Dragon](EIPS/eip-607.md) | State-clearing, EIP 158/161 | 2,675,000 | 2016-11-22 | -| [Byzantium](EIPS/eip-609.md) | Metropolis: Part 1 | 4,730,000 | 2017-10-16 | diff --git a/_data/statuses.yaml b/_data/statuses.yaml new file mode 100644 index 0000000000000..c8b18a8730ffc --- /dev/null +++ b/_data/statuses.yaml @@ -0,0 +1,5 @@ +- Draft +- Accepted +- Final +- Active +- Deferred diff --git a/_includes/eiptable.html b/_includes/eiptable.html index ee746a4069582..ec5e53876c396 100644 --- a/_includes/eiptable.html +++ b/_includes/eiptable.html @@ -1,16 +1,26 @@ -{% assign bystatus = include.eips|sort:"eip"|group_by:"status" %} -{% for group in bystatus %} - {% if group.name != "" %} -

    {{group.name}}

    -
    Author{% include authorlist.html authors=page.author %}
    Discussions-To{{ page["discussions-to"] | xml_escape }}
    Discussions-To{{ page["discussions-to"] | xml_escape }}
    Status{{ page.status | xml_escape }}
    Type{{ page.type | xml_escape }}
    + +{% for status in site.data.statuses %} + {% assign eips = include.eips|where:"status",status|sort:"eip" %} + {% assign count = eips|size %} + {% if count > 0 %} +

    {{status}}

    +
    - + - {% for page in group.items %} + {% for page in eips %} - - - + + + {% endfor %}
    NumberTitleAuthor
    NumberTitleAuthor
    {{page.eip|xml_escape}}{{page.title|xml_escape}}{% include authorlist.html authors=page.author %}{{page.eip|xml_escape}}{{page.title|xml_escape}}{% include authorlist.html authors=page.author %}
    From baf0e7a6eeeb256f1cb27fb35fe58594e8cf8409 Mon Sep 17 00:00:00 2001 From: Dave Sag <387098+davesag@users.noreply.github.com> Date: Thu, 29 Mar 2018 15:21:34 +0530 Subject: [PATCH 0599/1085] draft EIP for a DGCL compliant Token standard. (#884) * initial submission of draft EIP for consideration * EIP-884 correct spelling and add section on permissions management * EIP-884 added oldHash * EIP-884 changed getHash to hasHash and cleaned up grammar and spelling * EIP-884 updates to wording * EIR-884 added clarification on Delaware GCL vs Reg A+ * EIR-884 tweaks so the proposed code actually compiles * EIP-884 simplified ownerAt and added requirement that a verified address that owns tokens can not be removed * EIP-884 added link to reference implementation * EIP-884 added notes on ERC721 * EIP-884 renamed document, removed references to Reg A+, and updated interface to include stock cancellation and reissuance. * EIP-884 updated some documentation in the proposed interface * EIP-884 added isHolder function to proposed interface * EIP-884 moved to new frontmatter format * EIP-884 removed 'requires' from metadata * EIP-884 renamed file to match others --- EIPS/eip-884.md | 322 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 322 insertions(+) create mode 100644 EIPS/eip-884.md diff --git a/EIPS/eip-884.md b/EIPS/eip-884.md new file mode 100644 index 0000000000000..5f72da3983514 --- /dev/null +++ b/EIPS/eip-884.md @@ -0,0 +1,322 @@ +--- +eip: 884 +title: 'DGCL Token' +author: 'Dave Sag ' +type: Standard Track +category: ERC +status: Draft +created: 2018-02-14 +--- + +# Delaware General Corporations Law (DGCL) compatible stock Token + +Ref: [proposing-an-eip-for-DGCL-Tokens](http://forum.ethereum.org/discussion/17200/proposing-an-eip-for-regulation-a-Tokens) + +## Simple Summary + +An `ERC20` compatible Token that conforms to [Delaware State Senate, 149th General Assembly, Senate Bill No. 69: An act to Amend Title 8 of the Delaware Code Relating to the General Corporation Law](https://legis.delaware.gov/json/BillDetail/GenerateHtmlDocument?legislationId=25730&legislationTypeId=1&docTypeId=2&legislationName=SB69), henceforth referred to as 'The Act'. + +## Abstract + +The recently amended 'Title 8 of the Delaware Code Relating to the General Corporation Law' now explicitly allows for the use of blockchains to maintain corporate stock ledgers. This means it is now possible to create a tradable `ERC20` Token where each Token represents a Share issued by a Delaware corporation. Such a Token must conform to the following principles over and above the `ERC20` standard. + +1. Token owners must have their identity verified. +2. The Token contract must provide the following 3 functions of a `Corporations Stock ledger` (Ref: Section 224 of The Act): + + 1. Reporting: + + It must enable the corporation to prepare the list of stockholders specified in Sections 219 and 220 of The Act. + + 2. It must record the information specified in Sections 156, 159, 217(a) and 218 of The Act: + + - Partly paid shares + - Total amount paid + - Total amount to be paid + + 3. Transfers of stock as per section 159 of The Act: + + It must record transfers of stock as governed by Article 8 of subtitle I of Title 6. + +3. Each Token MUST correspond to a single share, each of which would be paid for in full, so there is no need to record information concerning partly paid shares, and there are no partial Tokens. + +4. There must be a mechanism to allow a stockholder who has lost their private key, or otherwise lost access to their Tokens to have their address `cancelled` and the Tokens re-issued to a new address. + +## Motivation + +1. Delaware General Corporation Law requires that stock issued by a Delaware corporation be recorded in a stock ledger. +2. The stock ledger can be represented by an ERC20 Token contract that is compliant with Delaware General Corporation Law. +3. This standard can cover equity issued by any Delaware corporation, whether private or public. + +By using a `DGCL` compatible Token, a firm may be able to raise funds via IPO, conforming to Delaware Corporations Law, but bypassing the need for involvement of a traditional Stock Exchange. + +The are currently no Token standards that conform to the `DGCL` rules. `ERC20` Tokens do not support KYC/AML rules required by the General Corporation Law, and do not provide facilities for the exporting of lists of stockholders. + +### What about ERC721? + +The proposed standard could easily be used to enhance ERC721, adding features for associating tokens with assets such as share certificates. + +While the `ERC721` Token proposal allows for some association of metadata with an Ethereum address, its uses are _not completely aligned_ with The Act, and it is not, in its current form, fully `ERC20` compatible. + +## Specification + +The `ERC20` Token provides the following basic features: + + contract ERC20 { + function totalSupply() public view returns (uint256); + function balanceOf(address who) public view returns (uint256); + function transfer(address to, uint256 value) public returns (bool); + function allowance(address owner, address spender) public view returns (uint256); + function transferFrom(address from, address to, uint256 value) public returns (bool); + function approve(address spender, uint256 value) public returns (bool); + event Approval(address indexed owner, address indexed spender, uint256 value); + event Transfer(address indexed from, address indexed to, uint256 value); + } + +This will be extended as follows: + + /** + * An `ERC20` compatible Token that conforms to Delaware State Senate, + * 149th General Assembly, Senate Bill No. 69: An act to Amend Title 8 + * of the Delaware Code Relating to the General Corporation Law. + * + * Implementation Details. + * + * An implementation of this Token standard SHOULD provide the following: + * + * `name` - for use by wallets and exchanges. + * `symbol` - for use by wallets and exchanges. + * + * The implementation MUST take care not to allow unauthorised access to stock + * transfer functions. + * + * In addition to the above the following optional `ERC20` function MUST be defined. + * + * `decimals` — MUST return `0` as each Token represents a single Share and Shares are non-divisible. + * + * @dev Ref https://github.com/ethereum/EIPs/pull/884 + */ + contract ERC884 is ERC20 { + + /** + * This event is emitted when a verified address and associated identity hash are + * added to the contract. + * @param addr The address that was added. + * @param hash The identity hash associated with the address. + * @param sender The address that caused the address to be added. + */ + event VerifiedAddressAdded( + address indexed addr, + bytes32 hash, + address indexed sender + ); + + /** + * This event is emitted when a verified address its associated identity hash are + * removed from the contract. + * @param addr The address that was removed. + * @param sender The address that caused the address to be removed. + */ + event VerifiedAddressRemoved(address indexed addr, address indexed sender); + + /** + * This event is emitted when the identity hash associated with a verified address is updated. + * @param addr The address whose hash was updated. + * @param oldHash The identity hash that was associated with the address. + * @param hash The hash now associated with the address. + * @param sender The address that caused the hash to be updated. + */ + event VerifiedAddressUpdated( + address indexed addr, + bytes32 oldHash, + bytes32 hash, + address indexed sender + ); + + /** + * This event is emitted when an address is cancelled and replaced with + * a new address. This happens in the case where a stockholder has + * lost access to their original address and needs to have their stock + * reissued to a new address. This is the equivalent of issuing replacement + * stock certificates. + * @param original The address being superseded. + * @param replacement The new address. + * @param sender The address that caused the address to be superseded. + */ + event VerifiedAddressSuperseded( + address indexed original, + address indexed replacement, + address indexed sender + ); + + /** + * Add a verified address, along with an associated verification hash to the contract. + * Upon successful addition of a verified address the contract must emit + * `VerifiedAddressAdded(addr, hash, msg.sender)`. + * It MUST throw if the supplied address or hash are zero, or if the address has already been supplied. + * @param addr The address of the person represented by the supplied hash. + * @param hash A cryptographic hash of the address holder's verified information. + */ + function addVerified(address addr, bytes32 hash) public; + + /** + * Remove a verified address, and the associated verification hash. If the address is + * unknown to the contract then this does nothing. If the address is successfully removed this + * function must emit `VerifiedAddressRemoved(addr, msg.sender)`. + * It MUST throw if an attempt is made to remove a verifiedAddress that owns Tokens. + * @param addr The verified address to be removed. + */ + function removeVerified(address addr) public; + + /** + * Update the hash for a verified address known to the contract. + * Upon successful update of a verified address the contract must emit + * `VerifiedAddressUpdated(addr, oldHash, hash, msg.sender)`. + * If the hash is the same as the value already stored then + * no `VerifiedAddressUpdated` event is to be emitted. + * It MUST throw if the hash is zero, or if the address is unverified. + * @param addr The verified address of the person represented by the supplied hash. + * @param hash A new cryptographic hash of the address holder's updated verified information. + */ + function updateVerified(address addr, bytes32 hash) public; + + /** + * Cancel the original address and reissue the Tokens to the replacement address. + * Access to this function MUST be strictly controlled. + * The `original` address MUST be removed from the set of verified addresses. + * Throw if the `original` address supplied is not a stockholder. + * Throw if the `replacement` address is not a verified address. + * Throw if the `replacement` address already holds Tokens. + * This function MUST emit the `VerifiedAddressSuperseded` event. + * @param original The address to be superseded. This address MUST NOT be reused. + */ + function cancelAndReissue(address original, address replacement) public; + + /** + * The `transfer` function MUST NOT allow transfers to addresses that + * have not been verified and added to the contract. + * If the `to` address is not currently a stockholder then it MUST become one. + * If the transfer will reduce `msg.sender`'s balance to 0 then that address + * MUST be removed from the list of stockholders. + */ + function transfer(address to, uint256 value) public returns (bool); + + /** + * The `transferFrom` function MUST NOT allow transfers to addresses that + * have not been verified and added to the contract. + * If the `to` address is not currently a stockholder then it MUST become one. + * If the transfer will reduce `from`'s balance to 0 then that address + * MUST be removed from the list of stockholders. + */ + function transferFrom(address from, address to, uint256 value) public returns (bool); + + /** + * Tests that the supplied address is known to the contract. + * @param addr The address to test. + * @return true if the address is known to the contract. + */ + function isVerified(address addr) public view returns (bool); + + /** + * Checks to see if the supplied address is a stock holder. + * @param addr The address to check. + * @return true if the supplied address owns a token. + */ + function isHolder(address addr) public view returns (bool); + + /** + * Checks that the supplied hash is associated with the given address. + * @param addr The address to test. + * @param hash The hash to test. + * @return true if the hash matches the one supplied with the address in `addVerified`, or `updateVerified`. + */ + function hasHash(address addr, bytes32 hash) public view returns (bool); + + /** + * The number of addresses that hold tokens. + * @return the number of unique addresses that hold tokens. + */ + function holderCount() public view returns (uint); + + /** + * By counting the number of Token holders using `holderCount` + * you can retrieve the complete list of Token holders, one at a time. + * It MUST throw if `index >= holderCount()`. + * @param index The zero-based index of the holder. + * @return the address of the Token holder with the given index. + */ + function holderAt(uint256 index) public view returns (address); + + /** + * Checks to see if the supplied address was superseded. + * @param addr The address to check. + * @return true if the supplied address was superseded by another address. + */ + function isSuperseded(address addr) public view returns (bool); + + /** + * Gets the most recent address given a superseded one. + * Addresses may be superseded multiple times, so this function needs to + * follow the chain of addresses until it reaches the final, verified address. + * @param addr The superseded address. + * @return the verified address that ultimately holds the stock. + */ + function getCurrentFor(address addr) public view returns (address); + } + +### SEC Requirements + +The SEC has additional requirements as to how a Crowdsale ought to be run and what information must be made available to the general public. This information is however out of scope from this standard, though the standard does support the requirements. + +For example: The SEC requires a Crowdsale's website display the amount of money raised in USD. To support this a Crowdsale contract minting these Tokens must maintain a USD to ETH conversion rate (via Oracle or some other mechanism) and must record the conversion rate used at time of minting. + +Also, depending on the type of raise, the SEC (or other statutory body) can apply limits to the number of shareholders allowed. To support this the standard provides the `holderCount` and `isHolder` functions which a crowdsale can invoke to check that limits have not been exceeded. + +### Use of the Identity `hash` value. + +Implementers of a Crowdsale, in order to comply with The Act, must be able to produce an up-to-date list of the names and addresses of all stockholders. It is not desirable to include those details in a public blockchain, both for reasons of privacy, and also for reasons of economy. Storing arbitrary string data on the blockchain is strongly discouraged. + +Implementers should maintain an off-chain private database that records the owner's name, residential address, and Ethereum address. The implementer must then be able to extract the name and address for any address, and hash the name + address data and compare that hash to the hash recorded in the contract using the `hasHash` function. The specific details of this system are left to the implementer. + +It is also desirable that the implementers offer a REST API endpoint along the lines of + + GET https:////:ethereumAddress -> [true|false] + +to enable 3rd party auditors to verify that a given Ethereum address is known to the implementers as a verified address. + +How the implementers verify a person's identity is up to them and beyond the scope of this standard. + +### Handling users who have lost access to their addresses + +A traditional stock register is typically managed by a Transfer Agent who is authorised to maintain the ledger accurately, and to handle stockholder enquiries. A common request is for stock certificates to be reissued in the case where the stockholder has lost or destroyed their original. + +Token implementers can handle that via the `cancelAndReissue` function, which must perform the various changes to ensure that the old address now points to the new one, and that cancelled addresses are not then reused. + +### Permissions management + +It is not desirable that anyone can add, remove, update, or supersede verified addresses. How access to these functions is controlled is outside of the scope of this standard. + +## Rationale + +The proposed standard offers an as minimal as possible extension over the existing `ERC20` standard in order to conform to the requirements of The Act. Rather than return a `bool` for successful or unsuccessful completion of state-changing functions such as `addVerified`, `removeVerified`, and `updateVerified`, we have opted to require that implementations `throw` (preferably by using the [forthcoming `require(condition, 'fail message')` syntax](https://github.com/ethereum/solidity/issues/1686#issuecomment-328181514).) + +## Backwards Compatibility + +The proposed standard is designed to maintain compatibility with ERC20 Tokens with the following provisos. + +1. The `decimals` function MUST return `0` as the Tokens MUST NOT be divisible, +2. The `transfer` and `transferFrom` functions MUST NOT allow transfers to non-verified addresses, and MUST maintain a list of stockholders. +3. Stockholders who transfer away their remaining Tokens must be pruned from the list of stockholders. + +Proviso 1 will not break compatibility with modern wallets or exchanges as they all appear to use that information if available. + +Proviso 2 will cause transfers to fail if an attempt is made to transfer Tokens to a non-verified address. This is implicit in the design and implementers are encouraged to make this abundantly clear to market participants. We appreciate that this will make the standard unpalatable to some exchanges, but it is an SEC requirement that stockholders of a corporation provide verified names and addresses. + +Proviso 3 is an implementation detail. + +## Test Cases and Reference Implementation + +Test cases and a reference implementation are available at [github.com/davesag/ERC884-reference-implementation](https://github.com/davesag/ERC884-reference-implementation). + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From a90a5a3e58accea956dd8f1eacac5a17f98ec2e2 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Tue, 3 Apr 2018 20:02:04 +0100 Subject: [PATCH 0600/1085] Add autocommit bot and descriptions of it (#967) * Add autocommit bot and descriptions of it * Update README.md * Update EIP 1 with some changes to process --- .travis.yml | 6 ++++++ EIPS/eip-1.md | 26 ++++++++++++++++---------- PULL_REQUEST_TEMPLATE.md | 7 +++++++ README.md | 15 ++++++++++++++- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6823fc5fe2ee1..92ea6370a0ca2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,3 +25,9 @@ matrix: allow_failures: - rvm: 2.2.5 env: TASK='htmlproofer-external' + +notifications: + webhooks: + urls: + - https://ethlab-183014.appspot.com/merge/ + on_success: always diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index 6c8b250bcfbed..79df47c82ccc8 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -12,8 +12,8 @@ What is an EIP? EIP stands for Ethereum Improvement Proposal. An EIP is a design document providing information to the Ethereum community, or describing a new feature for Ethereum or its processes or environment. The EIP should provide a concise technical specification of the feature and a rationale for the feature. The EIP author is responsible for building consensus within the community and documenting dissenting opinions. -EIP Rational ------------- +EIP Rationale +------------- We intend EIPs to be the primary mechanisms for proposing new features, for collecting community input on an issue, and for documenting the design decisions that have gone into Ethereum. Because the EIPs are maintained as text files in a versioned repository, their revision history is the historical record of the feature proposal. @@ -44,11 +44,13 @@ Each EIP must have a champion - someone who writes the EIP using the style and f Vetting an idea publicly before going as far as writing an EIP is meant to save the potential author time. Asking the Ethereum community first if an idea is original helps prevent too much time being spent on something that is guaranteed to be rejected based on prior discussions (searching the Internet does not always do the trick). It also helps to make sure the idea is applicable to the entire community and not just the author. Just because an idea sounds good to the author does not mean it will work for most people in most areas where Ethereum is used. Examples of appropriate public forums to gauge interest around your EIP include [the Ethereum subreddit], [the Issues section of this repository], and [one of the Ethereum Gitter chat rooms]. In particular, [the Issues section of this repository] is an excellent place to discuss your proposal with the community and start creating more formalized language around your EIP. -Once the champion has asked the Ethereum community whether an idea has any chance of acceptance a draft EIP should be presented as a [pull request]. This gives the author a chance to continuously edit the draft EIP for proper formatting and quality. This also allows for further public comment and the author of the EIP to address concerns about the proposal. +Once the champion has asked the Ethereum community whether an idea has any chance of acceptance a draft EIP should be presented as a [pull request]. + +If the EIP collaborators approve, the EIP editor will assign the EIP a number (generally the issue or PR number related to the EIP) and merge your pull request. The EIP editor will not unreasonably deny an EIP. Reasons for denying EIP status include duplication of effort, being technically unsound, not providing proper motivation or addressing backwards compatibility, or not in keeping with the Ethereum philosophy. -If the EIP collaborators approve, the EIP editor will assign the EIP a number (generally the issue or PR number related to the EIP), label it as Standards Track, Informational, or Meta, give it status “Draft”, and add it to the git repository. The EIP editor will not unreasonably deny an EIP. Reasons for denying EIP status include duplication of effort, being technically unsound, not providing proper motivation or addressing backwards compatibility, or not in keeping with the Ethereum philosophy. +Once the first draft has been merged, you may submit follow-up pull requests with further changes to your draft until such point as you believe the EIP to be mature and ready to proceed to the next phase. -Standards Track EIPs consist of three parts, a design document, implementation, and finally if warranted an update to the [formal specification]. The EIP should be reviewed and accepted before an implementation is begun, unless an implementation will aid people in studying the EIP. Standards Track EIPs must be implemented in at least three viable Ethereum clients before it can be considered Final. +Standards Track EIPs consist of three parts, a design document, implementation, and finally if warranted an update to the [formal specification]. The EIP should be reviewed and accepted before an implementation is begun, unless an implementation will aid people in studying the EIP. Standards Track Core EIPs must be implemented in at least three viable Ethereum clients before it can be considered Final. For an EIP to be accepted it must meet certain minimum criteria. It must be a clear and complete description of the proposed enhancement. The enhancement must represent a net improvement. The proposed implementation, if applicable, must be solid and must not complicate the protocol unduly. @@ -123,9 +125,9 @@ Each EIP must begin with an RFC 822 style header preamble, preceded and followed ` title: ` -` author: ` +` author: ` -` * discussions-to: ` +` * discussions-to: ` ` status: ` @@ -147,7 +149,11 @@ The author header lists the names, and optionally the email addresses of all the Random J. User <address@dom.ain> -if the email address is included, and +or + +Random J. User <@username> + +if the email address or GitHub username is included, and Random J. User @@ -155,7 +161,7 @@ if the email address is not given. Note: The resolution header is required for Standards Track EIPs only. It contains a URL that should point to an email message or other web resource where the pronouncement about the EIP is made. -While an EIP is in private discussions (usually during the initial Draft phase), a discussions-to header will indicate the mailing list or URL where the EIP is being discussed. No discussions-to header is necessary if the EIP is being discussed privately with the author. +While an EIP is a draft, a discussions-to header will indicate the mailing list or URL where the EIP is being discussed. No discussions-to header is necessary if the EIP is being discussed privately with the author. The type header specifies the type of EIP: Standards Track, Meta, or Informational. If the track is Standards please include the subcategory (core, networking, interface, or ERC). @@ -206,7 +212,7 @@ For each new EIP that comes in, an editor does the following: - Read the EIP to check if it is ready: sound and complete. The ideas must make technical sense, even if they don't seem likely to be accepted. - The title should accurately describe the content. -- Edit the EIP for language (spelling, grammar, sentence structure, etc.), markup (Github flavored Markdown), code style +- Check the EIP for language (spelling, grammar, sentence structure, etc.), markup (Github flavored Markdown), code style If the EIP isn't ready, the editor will send it back to the author for revision, with specific instructions. diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index bd8aea3067bab..03f1f3dabb79a 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -1 +1,8 @@ When opening a pull request to submit a new EIP, please use the suggested template: https://github.com/ethereum/EIPs/blob/master/eip-X.md + +We have a GitHub bot that automatically merges some PRs. It will merge yours immediately if certain criteria are met: + + - The PR edits only existing draft PRs. + - The build passes. + - Your Github username or email address is listed in the 'author' header of all affected PRs, inside . + - If matching on email address, the email address is the one publicly listed on your GitHub profile. diff --git a/README.md b/README.md index 01c4be09c4a7b..0469ec30d151e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,20 @@ Ethereum Improvement Proposals (EIPs) describe standards for the Ethereum platfo A browsable version of all current and draft EIPs can be found on [the official EIP site](http://eips.ethereum.org/). # Contributing -First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP to it. There is a [template EIP here](eip-X.md). Then submit a Pull Request to Ethereum's [EIPs repository](https://github.com/ethereum/EIPs). + + 1. Review [EIP-1](EIPS/eip-1.md). + 2. Fork the repository by clicking "Fork" in the top right. + 3. Add your EIP to your fork of the repository. There is a [template EIP here](eip-X.md). + 4. Submit a Pull Request to Ethereum's [EIPs repository](https://github.com/ethereum/EIPs). + +Your first PR should be a first draft of the final EIP. It must meet the formatting criteria enforced by the build (largely, correct metadata in the header). An editor will manually review the first PR for a new EIP and assign it a number before merging it. Make sure you include a `discussions-to` header with the URL to a discussion forum or open GitHub issue where people can discuss the EIP as a whole. + +Once your first PR is merged, we have a bot that helps out by automatically merging PRs to draft EIPs. For this to work, it has to be able to tell that you own the draft being edited. Make sure that the 'author' line of your EIP contains either your Github username or your email address inside . If you use your email address, that address must be the one publicly shown on [your GitHub profile](https://github.com/settings/profile). + +When you believe your EIP is mature and ready to progress past the draft phase, you should do one of two things: + + - **For a Standards Track EIP of type Core**, ask to have your issue added to [the agenda of an upcoming All Core Devs meeting](https://github.com/ethereum/pm/issues), where it can be discussed for inclusion in a future hard fork. If implementers agree to include it, the EIP editors will update the state of your EIP to 'Accepted'. + - **For all other EIPs**, open a PR changing the state of your EIP to 'Final'. An editor will review your draft and ask if anyone objects to its being finalised. If the editor decides there is no rough consensus - for instance, because contributors point out significant issues with the EIP - they may close the PR and request that you fix the issues in the draft before trying again. # EIP status terms * **Draft** - an EIP that is open for consideration From 4b1d9aacbdb30ad3137dd60272fe0de05974d8ba Mon Sep 17 00:00:00 2001 From: Dave Sag <387098+davesag@users.noreply.github.com> Date: Wed, 4 Apr 2018 00:44:07 +0530 Subject: [PATCH 0601/1085] [Optimisation, ERC-884] spelling, grammar and style adjustments (#962) * ERC-884 spelling, grammar and style adjustments * ERC-884 other minor style alts * ERC-884 minor alt in response to feedback --- EIPS/eip-884.md | 110 ++++++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/EIPS/eip-884.md b/EIPS/eip-884.md index 5f72da3983514..359592b6ad75b 100644 --- a/EIPS/eip-884.md +++ b/EIPS/eip-884.md @@ -8,24 +8,24 @@ status: Draft created: 2018-02-14 --- -# Delaware General Corporations Law (DGCL) compatible stock Token +# Delaware General Corporations Law (DGCL) compatible share token -Ref: [proposing-an-eip-for-DGCL-Tokens](http://forum.ethereum.org/discussion/17200/proposing-an-eip-for-regulation-a-Tokens) +Ref: [proposing-an-eip-for-DGCL-tokens](http://forum.ethereum.org/discussion/17200/proposing-an-eip-for-regulation-a-Tokens) ## Simple Summary -An `ERC20` compatible Token that conforms to [Delaware State Senate, 149th General Assembly, Senate Bill No. 69: An act to Amend Title 8 of the Delaware Code Relating to the General Corporation Law](https://legis.delaware.gov/json/BillDetail/GenerateHtmlDocument?legislationId=25730&legislationTypeId=1&docTypeId=2&legislationName=SB69), henceforth referred to as 'The Act'. +An `ERC-20` compatible token that conforms to [Delaware State Senate, 149th General Assembly, Senate Bill No. 69: An act to Amend Title 8 of the Delaware Code Relating to the General Corporation Law](https://legis.delaware.gov/json/BillDetail/GenerateHtmlDocument?legislationId=25730&legislationTypeId=1&docTypeId=2&legislationName=SB69), henceforth referred to as 'The Act'. ## Abstract -The recently amended 'Title 8 of the Delaware Code Relating to the General Corporation Law' now explicitly allows for the use of blockchains to maintain corporate stock ledgers. This means it is now possible to create a tradable `ERC20` Token where each Token represents a Share issued by a Delaware corporation. Such a Token must conform to the following principles over and above the `ERC20` standard. +The recently amended 'Title 8 of the Delaware Code Relating to the General Corporation Law' now explicitly allows for the use of blockchains to maintain corporate share registries. This means it is now possible to create a tradable `ERC-20` token where each token represents a share issued by a Delaware corporation. Such a token must conform to the following principles over and above the `ERC-20` standard. 1. Token owners must have their identity verified. -2. The Token contract must provide the following 3 functions of a `Corporations Stock ledger` (Ref: Section 224 of The Act): +2. The token contract must provide the following three functions of a `Corporations Stock ledger` (Ref: Section 224 of The Act): 1. Reporting: - It must enable the corporation to prepare the list of stockholders specified in Sections 219 and 220 of The Act. + It must enable the corporation to prepare the list of shareholders specified in Sections 219 and 220 of The Act. 2. It must record the information specified in Sections 156, 159, 217(a) and 218 of The Act: @@ -33,33 +33,33 @@ The recently amended 'Title 8 of the Delaware Code Relating to the General Corpo - Total amount paid - Total amount to be paid - 3. Transfers of stock as per section 159 of The Act: + 3. Transfers of shares as per section 159 of The Act: - It must record transfers of stock as governed by Article 8 of subtitle I of Title 6. + It must record transfers of shares as governed by Article 8 of subtitle I of Title 6. -3. Each Token MUST correspond to a single share, each of which would be paid for in full, so there is no need to record information concerning partly paid shares, and there are no partial Tokens. +3. Each token MUST correspond to a single share, each of which would be paid for in full, so there is no need to record information concerning partly paid shares, and there are no partial tokens. -4. There must be a mechanism to allow a stockholder who has lost their private key, or otherwise lost access to their Tokens to have their address `cancelled` and the Tokens re-issued to a new address. +4. There must be a mechanism to allow a shareholder who has lost their private key, or otherwise lost access to their tokens to have their address `cancelled` and the tokens re-issued to a new address. ## Motivation -1. Delaware General Corporation Law requires that stock issued by a Delaware corporation be recorded in a stock ledger. -2. The stock ledger can be represented by an ERC20 Token contract that is compliant with Delaware General Corporation Law. +1. Delaware General Corporation Law requires that shares issued by a Delaware corporation be recorded in a share registry. +2. The share registry can be represented by an `ERC-20` token contract that is compliant with Delaware General Corporation Law. 3. This standard can cover equity issued by any Delaware corporation, whether private or public. -By using a `DGCL` compatible Token, a firm may be able to raise funds via IPO, conforming to Delaware Corporations Law, but bypassing the need for involvement of a traditional Stock Exchange. +By using a `DGCL` compatible token, a firm may be able to raise funds via IPO, conforming to Delaware Corporations Law, but bypassing the need for involvement of a traditional Stock Exchange. -The are currently no Token standards that conform to the `DGCL` rules. `ERC20` Tokens do not support KYC/AML rules required by the General Corporation Law, and do not provide facilities for the exporting of lists of stockholders. +The are currently no token standards that conform to the `DGCL` rules. `ERC-20` tokens do not support KYC/AML rules required by the General Corporation Law, and do not provide facilities for the exporting of lists of shareholders. -### What about ERC721? +### What about ERC-721? -The proposed standard could easily be used to enhance ERC721, adding features for associating tokens with assets such as share certificates. +The proposed standard could easily be used to enhance `ERC-721`, adding features for associating tokens with assets such as share certificates. -While the `ERC721` Token proposal allows for some association of metadata with an Ethereum address, its uses are _not completely aligned_ with The Act, and it is not, in its current form, fully `ERC20` compatible. +While the `ERC-721` token proposal allows for some association of metadata with an Ethereum address, its uses are _not completely aligned_ with The Act, and it is not, in its current form, fully `ERC-20` compatible. ## Specification -The `ERC20` Token provides the following basic features: +The `ERC-20` token provides the following basic features: contract ERC20 { function totalSupply() public view returns (uint256); @@ -75,23 +75,23 @@ The `ERC20` Token provides the following basic features: This will be extended as follows: /** - * An `ERC20` compatible Token that conforms to Delaware State Senate, + * An `ERC20` compatible token that conforms to Delaware State Senate, * 149th General Assembly, Senate Bill No. 69: An act to Amend Title 8 * of the Delaware Code Relating to the General Corporation Law. * * Implementation Details. * - * An implementation of this Token standard SHOULD provide the following: + * An implementation of this token standard SHOULD provide the following: * * `name` - for use by wallets and exchanges. * `symbol` - for use by wallets and exchanges. * - * The implementation MUST take care not to allow unauthorised access to stock - * transfer functions. + * The implementation MUST take care not to allow unauthorised access to + * share-transfer functions. * * In addition to the above the following optional `ERC20` function MUST be defined. * - * `decimals` — MUST return `0` as each Token represents a single Share and Shares are non-divisible. + * `decimals` — MUST return `0` as each token represents a single share and shares are non-divisible. * * @dev Ref https://github.com/ethereum/EIPs/pull/884 */ @@ -134,10 +134,10 @@ This will be extended as follows: /** * This event is emitted when an address is cancelled and replaced with - * a new address. This happens in the case where a stockholder has - * lost access to their original address and needs to have their stock + * a new address. This happens in the case where a shareholder has + * lost access to their original address and needs to have their share * reissued to a new address. This is the equivalent of issuing replacement - * stock certificates. + * share certificates. * @param original The address being superseded. * @param replacement The new address. * @param sender The address that caused the address to be superseded. @@ -150,7 +150,7 @@ This will be extended as follows: /** * Add a verified address, along with an associated verification hash to the contract. - * Upon successful addition of a verified address the contract must emit + * Upon successful addition of a verified address, the contract must emit * `VerifiedAddressAdded(addr, hash, msg.sender)`. * It MUST throw if the supplied address or hash are zero, or if the address has already been supplied. * @param addr The address of the person represented by the supplied hash. @@ -160,9 +160,9 @@ This will be extended as follows: /** * Remove a verified address, and the associated verification hash. If the address is - * unknown to the contract then this does nothing. If the address is successfully removed this + * unknown to the contract then this does nothing. If the address is successfully removed, this * function must emit `VerifiedAddressRemoved(addr, msg.sender)`. - * It MUST throw if an attempt is made to remove a verifiedAddress that owns Tokens. + * It MUST throw if an attempt is made to remove a verifiedAddress that owns tokens. * @param addr The verified address to be removed. */ function removeVerified(address addr) public; @@ -180,12 +180,12 @@ This will be extended as follows: function updateVerified(address addr, bytes32 hash) public; /** - * Cancel the original address and reissue the Tokens to the replacement address. + * Cancel the original address and reissue the tokens to the replacement address. * Access to this function MUST be strictly controlled. * The `original` address MUST be removed from the set of verified addresses. - * Throw if the `original` address supplied is not a stockholder. + * Throw if the `original` address supplied is not a shareholder. * Throw if the `replacement` address is not a verified address. - * Throw if the `replacement` address already holds Tokens. + * Throw if the `replacement` address already holds tokens. * This function MUST emit the `VerifiedAddressSuperseded` event. * @param original The address to be superseded. This address MUST NOT be reused. */ @@ -194,18 +194,18 @@ This will be extended as follows: /** * The `transfer` function MUST NOT allow transfers to addresses that * have not been verified and added to the contract. - * If the `to` address is not currently a stockholder then it MUST become one. + * If the `to` address is not currently a shareholder then it MUST become one. * If the transfer will reduce `msg.sender`'s balance to 0 then that address - * MUST be removed from the list of stockholders. + * MUST be removed from the list of shareholders. */ function transfer(address to, uint256 value) public returns (bool); /** * The `transferFrom` function MUST NOT allow transfers to addresses that * have not been verified and added to the contract. - * If the `to` address is not currently a stockholder then it MUST become one. + * If the `to` address is not currently a shareholder then it MUST become one. * If the transfer will reduce `from`'s balance to 0 then that address - * MUST be removed from the list of stockholders. + * MUST be removed from the list of shareholders. */ function transferFrom(address from, address to, uint256 value) public returns (bool); @@ -217,7 +217,7 @@ This will be extended as follows: function isVerified(address addr) public view returns (bool); /** - * Checks to see if the supplied address is a stock holder. + * Checks to see if the supplied address is a shareholder. * @param addr The address to check. * @return true if the supplied address owns a token. */ @@ -238,11 +238,11 @@ This will be extended as follows: function holderCount() public view returns (uint); /** - * By counting the number of Token holders using `holderCount` - * you can retrieve the complete list of Token holders, one at a time. + * By counting the number of token holders using `holderCount` + * you can retrieve the complete list of token holders, one at a time. * It MUST throw if `index >= holderCount()`. * @param index The zero-based index of the holder. - * @return the address of the Token holder with the given index. + * @return the address of the token holder with the given index. */ function holderAt(uint256 index) public view returns (address); @@ -254,26 +254,26 @@ This will be extended as follows: function isSuperseded(address addr) public view returns (bool); /** - * Gets the most recent address given a superseded one. + * Gets the most recent address, given a superseded one. * Addresses may be superseded multiple times, so this function needs to * follow the chain of addresses until it reaches the final, verified address. * @param addr The superseded address. - * @return the verified address that ultimately holds the stock. + * @return the verified address that ultimately holds the share. */ function getCurrentFor(address addr) public view returns (address); } -### SEC Requirements +### Securities Exchange Commission Requirements -The SEC has additional requirements as to how a Crowdsale ought to be run and what information must be made available to the general public. This information is however out of scope from this standard, though the standard does support the requirements. +The Securities Exchange Commission (SEC) has additional requirements as to how a crowdsale ought to be run and what information must be made available to the general public. This information is however out of scope from this standard, though the standard does support the requirements. -For example: The SEC requires a Crowdsale's website display the amount of money raised in USD. To support this a Crowdsale contract minting these Tokens must maintain a USD to ETH conversion rate (via Oracle or some other mechanism) and must record the conversion rate used at time of minting. +For example: The SEC requires a crowdsale's website display the amount of money raised in US Dollars. To support this a crowdsale contract minting these tokens must maintain a USD to ETH conversion rate (via Oracle or some other mechanism) and must record the conversion rate used at time of minting. Also, depending on the type of raise, the SEC (or other statutory body) can apply limits to the number of shareholders allowed. To support this the standard provides the `holderCount` and `isHolder` functions which a crowdsale can invoke to check that limits have not been exceeded. -### Use of the Identity `hash` value. +### Use of the Identity `hash` value -Implementers of a Crowdsale, in order to comply with The Act, must be able to produce an up-to-date list of the names and addresses of all stockholders. It is not desirable to include those details in a public blockchain, both for reasons of privacy, and also for reasons of economy. Storing arbitrary string data on the blockchain is strongly discouraged. +Implementers of a crowdsale, in order to comply with The Act, must be able to produce an up-to-date list of the names and addresses of all shareholders. It is not desirable to include those details in a public blockchain, both for reasons of privacy, and also for reasons of economy. Storing arbitrary string data on the blockchain is strongly discouraged. Implementers should maintain an off-chain private database that records the owner's name, residential address, and Ethereum address. The implementer must then be able to extract the name and address for any address, and hash the name + address data and compare that hash to the hash recorded in the contract using the `hasHash` function. The specific details of this system are left to the implementer. @@ -281,13 +281,13 @@ It is also desirable that the implementers offer a REST API endpoint along the l GET https:////:ethereumAddress -> [true|false] -to enable 3rd party auditors to verify that a given Ethereum address is known to the implementers as a verified address. +to enable third party auditors to verify that a given Ethereum address is known to the implementers as a verified address. How the implementers verify a person's identity is up to them and beyond the scope of this standard. ### Handling users who have lost access to their addresses -A traditional stock register is typically managed by a Transfer Agent who is authorised to maintain the ledger accurately, and to handle stockholder enquiries. A common request is for stock certificates to be reissued in the case where the stockholder has lost or destroyed their original. +A traditional share register is typically managed by a Transfer Agent who is authorised to maintain the register accurately, and to handle shareholder enquiries. A common request is for share certificates to be reissued in the case where the shareholder has lost or destroyed their original. Token implementers can handle that via the `cancelAndReissue` function, which must perform the various changes to ensure that the old address now points to the new one, and that cancelled addresses are not then reused. @@ -297,19 +297,19 @@ It is not desirable that anyone can add, remove, update, or supersede verified a ## Rationale -The proposed standard offers an as minimal as possible extension over the existing `ERC20` standard in order to conform to the requirements of The Act. Rather than return a `bool` for successful or unsuccessful completion of state-changing functions such as `addVerified`, `removeVerified`, and `updateVerified`, we have opted to require that implementations `throw` (preferably by using the [forthcoming `require(condition, 'fail message')` syntax](https://github.com/ethereum/solidity/issues/1686#issuecomment-328181514).) +The proposed standard offers as minimal an extension as possible over the existing `ERC-20` standard in order to conform to the requirements of The Act. Rather than return a `bool` for successful or unsuccessful completion of state-changing functions such as `addVerified`, `removeVerified`, and `updateVerified`, we have opted to require that implementations `throw` (preferably by using the [forthcoming `require(condition, 'fail message')` syntax](https://github.com/ethereum/solidity/issues/1686#issuecomment-328181514)). ## Backwards Compatibility -The proposed standard is designed to maintain compatibility with ERC20 Tokens with the following provisos. +The proposed standard is designed to maintain compatibility with `ERC-20` tokens with the following provisos: -1. The `decimals` function MUST return `0` as the Tokens MUST NOT be divisible, -2. The `transfer` and `transferFrom` functions MUST NOT allow transfers to non-verified addresses, and MUST maintain a list of stockholders. -3. Stockholders who transfer away their remaining Tokens must be pruned from the list of stockholders. +1. The `decimals` function MUST return `0` as the tokens MUST NOT be divisible, +2. The `transfer` and `transferFrom` functions MUST NOT allow transfers to non-verified addresses, and MUST maintain a list of shareholders. +3. Shareholders who transfer away their remaining tokens must be pruned from the list of shareholders. Proviso 1 will not break compatibility with modern wallets or exchanges as they all appear to use that information if available. -Proviso 2 will cause transfers to fail if an attempt is made to transfer Tokens to a non-verified address. This is implicit in the design and implementers are encouraged to make this abundantly clear to market participants. We appreciate that this will make the standard unpalatable to some exchanges, but it is an SEC requirement that stockholders of a corporation provide verified names and addresses. +Proviso 2 will cause transfers to fail if an attempt is made to transfer tokens to a non-verified address. This is implicit in the design and implementers are encouraged to make this abundantly clear to market participants. We appreciate that this will make the standard unpalatable to some exchanges, but it is an SEC requirement that shareholders of a corporation provide verified names and addresses. Proviso 3 is an implementation detail. From ecb731ef0081238118f60c8347b3ddf1ac0c919d Mon Sep 17 00:00:00 2001 From: David Stanfill Date: Wed, 4 Apr 2018 14:05:00 -0400 Subject: [PATCH 0602/1085] Early ASIC Mitigation Hardfork (#969) * Added initial ASIC-resistant EIP details * Format fixed * Format fixed * Format fixed * Format fixed * Format fixed * Grammar fixes * Added mention of more invasive hash algorithm replacements * Added mention of the single duplicate in 0x010001cf * Adjusted language to remove speculation and focus on the purpose and motivation of this pull request * Assigned EIP number and discussion URL, altered language to be more descriptive about the intention and risk. Removed unneeded Concensus/Block field changes. * Clarified FNV rational, provided code for basic sanity FNV candidate analysis and FNV selection, grammar fixes --- EIPS/eip-969.md | 202 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 EIPS/eip-969.md diff --git a/EIPS/eip-969.md b/EIPS/eip-969.md new file mode 100644 index 0000000000000..cc3c69c25ddaf --- /dev/null +++ b/EIPS/eip-969.md @@ -0,0 +1,202 @@ +--- +eip: 969 +title: Modifications to ethash to invalidate existing dedicated hardware implementations +author: David Stanfill +discussions-to: https://gitter.im/ethereum/topics/topic/5ac4d974109bb043328911ce/eip-969-discussion +status: Draft +type: Standards Track +category: Core +created: 2018-04-03 +--- + + +## Simple Summary + +This EIP modifies ethash in order to break ASIC miners specialized for the current ethash +mining algorithm. + + +## Abstract + +There are companies who currently have dedicated hardware based ethereum miners in +production, and may be actively mining. This EIP aims to "poison +the well" by modifying the block mining algorithm in a low risk manner that +may *"break"* these miners if they are in-fact built as traditional ASICs. + + +## Motivation + +ASIC based miners will have lower operational costs than GPU based miners which +will result in GPU based mining quickly becoming unprofitable. Given that +production of ASIC based miners has a high barrier to entry and few market players, +this will cause a trend towards centralization of mining power. + +Risks include market dominance by a single manufacturer that may utilize production +stock to mine themselves, introduce backdoors in their hardware, or otherwise +facilitate a 51% attack that would be infeasible. + +This trend towards centralization has a negative effect on network security, +putting significant control of the network in the hands of only a few entities. + +Ethash remains ASIC resistant, however ASIC manufacturer technology is advancing +and ethash may require further changes in order to remain resistant to unforeseen +design techniques. This EIP seeks explicitly to buy time during which newly developed +ASIC technology will face a barrier while more long term mechanisms to ensure +continued ASIC resistance can be explored. + +## Specification + +If `block.number >= ASIC_MITIGATION_FORK_BLKNUM`, require that the ethash solution +sealing the block has been mined using `ethashV2`. + +## EthashV2 + +`ethashV2` will be identical in specification to the current `ethash`(v1) algorithm, with +the exception of the implementation of `fnv`. + +The new algorithm replaces the 5 current uses of `fnv` inside `hashimoto` with 5 +separate instances defined as `fnvA`, `fnvB`, `fnvC`, `fnvD`, and `fnvE`, utilizing + +`FNV_PRIME_A=0x10001a7` +`FNV_PRIME_B=0x10001ab` +`FNV_PRIME_C=0x10001cf` +`FNV_PRIME_D=0x10001e3` +`FNV_PRIME_E=0x10001f9` + + +`fnvA` replaces `fnv` in the DAG item selection step +`fnvB` replaces `fnv` in the DAG item mix step +`fnvC(fnvD(fnvE` replaces `fnv(fnv(fnv(` in the compress mix step + +`fnv` as utilized in DAG-item creation should remain unchanged. + +## Agent Changes (Optional Variant) + +The JSON-RPC `eth_GetWork` call may optionally return the proposed blocks algorithm. +While a miner or pool may infer the requirement for ethashV2 based on the computed +epoch of the provided seedHash, it is beneficial to explicitly provide this +field so a miner does not require special configuration when mining on a chain +that chooses not to implement the ASIC_Mitigation hardfork. + +Due to compatibility concerns with implementations that already add additional +parameters to GetWork, it is desired to add BlockNumber as an explicit 4th parameter +as suggested in https://github.com/ethereum/go-ethereum/issues/2333. Algorithm +should then be returned as either `"ethash"` or `"ethashV2"` according to the +`block.number >= ASIC_MITIGATION_FORK_BLKNUM` criteria. + +## Rationale + +This EIP is aimed at breaking existing ASIC based miners via small changes to the +existing ethash algorithm. We hope to accomplish the following: + +1. Break existing ASIC based miners. +2. Demonstrate a willingness to fork in the event of future ASIC miner production. + +Goal #1 is something that we can only do probabilistically without detailed +knowledge of existing ASIC miner design. The known released miner is available for +purchase at https://shop.bitmain.com/product/detail?pid=00020180403174908564M8dMJKtz06B7 +with delivery slated for mid-summer. + +Our approach should balance the inherent security risks involved with changing +the mining algorithm with the risk that the change we make does not break existing + ASIC miners. This EIP leans towards minimizing the security risks by making minimal + changes to the algorithm accepting the risk that the change may not break dedicated + hardware miners that utilize partially or fully configurable logic. + +Furthermore, we do not wish to introduce significant algorithm changes that +may alter the power utilization or performance profile of existing GPU hardware. + +The change of FNV constant is a minimal change that can be quickly +implemented across the various network node and miner implementations. + +It is proposed that `ASIC_MITIGATION_FORK_BLKNUM` be no more than 5550000 (epoch 185), giving +around 30 days of notice to node and miner developers and a sufficient window +for formal analysis of the changes by experts. We must weigh this window against +the risk introduced by allowing ASICs that may exist to continue to propagate +on the network, as well as the risk of providing too much advanced warning to +ASIC developers. + +It is further understood that this change will not prevent redesign of existing +dedicated hardware with new ASIC chips. The intention of this change is only +to disable currently active or mid-production hardware and provide time for +POS development as well as larger algorithim changes to be well analyzed by +experts. + +The choice of FNV constants is made based on the formal specification at +https://tools.ietf.org/html/draft-eastlake-fnv-14#section-2.1 + +@goobur provided the following python code to output primes matching this criteria + +`candidates = [2**24 + 2**8 + _ for _ in xrange(256)]`
    +`candidates = [_ for _ in candidates if is_prime(_)]`
    +`["0x%x" % _ for _ in candidates if _ % (2**40 - 2**24 - 1) > (2**24 + 2**8 + 2**7)]`
    + +The minimal prime constraint was relaxed, as has already been the case in ethashV1. + +Typical ASIC synthesis tools would optimize multiplication of a constant +in the FNV algorithm, while reducing the area needed for the multiplier according +to the hamming weight of the constant. To reduce the chance of ASIC adaptation +through minor mask changes, we propose choosing new constants with a larger +hamming weight, however care should be taken not to choose constants with too +large of a weight. + +The current FNV prime, 0x1000193 has a hamming weight of 6. +`HammingWeight(0x10001a7) = 7;` +`HammingWeight(0x10001ab) = 7;` +`HammingWeight(0x10001cf) = 8;` +`HammingWeight(0x10001e3) = 7;` +`HammingWeight(0x10001ef) = 9; // Not chosen` +`HammingWeight(0x10001f9) = 8;` +`HammingWeight(0x10001fb) = 9; // Not chosen` + +An exhaustive analysis was done regarding the dispersion of these constants as compared to 0x01000193 +using the following process. + +``` +uint32_t candidate = 0; +uint32_t dups = 0; +uint32_t fnv_candidate = 0x10001a7; +uint8_t *counts = malloc(0xFFFFFFFF); +memset(counts, '\0', 0xFFFFFFFF); +for ( candidate = 0; candidate <= 0xFFFFFFFF; candidate++) { + uint32_t result = (uint_32)(candidate * fnv_candidate); + uint8_t oldCount = counts[result]; + counts[result] = counts[result]+1; + if (oldCount != 0) { + dups++; + } +} +printf("Candidate 0x%08x : %i dups", dups); +``` + +It can be empirically confirmed that no more than 1 duplicates occur in the 32 bit word space with these constants. + +It is worth noting that FNV is not a cryptographic hash, and it is not used as such in ethash. With +that said, a more invasive hash algorithm change could consider other options. One suggestion has been +MurmorHash3 (https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp) + +Other suggestions have been made for complete algorithm changes, including off-the-shelf solutions +such as Argon2, Equihash of Zcash fame, and Balloon Hashing. +(https://twitter.com/el33th4xor/status/981292363627810818). This may be considered once +the exact mechanism of the released ASICs is known and their effectiveness against its optimisations +can be fully evaluated. + +## Backwards Compatibility + +This change implements a backwards incompatible change to proof of work based +block mining. All existing miners will be required to update to clients which +implement this new algorithm, and all nodes will require updates to accept +solutions from the new proof of work algorithm. + +## Test Cases + +TODO: will need to generate test cases for `ethereum/tests` repository corresponding to the consensus +changes. + +## Implementation + +TODO + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 77ee0e138c22400f75e06d5afda39ada68196f07 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Wed, 4 Apr 2018 21:28:59 +0200 Subject: [PATCH 0603/1085] Automatically merged updates to draft EIP(s) 615 Hi, I'm a bot! This change was automatically merged because: - It only modifies existing draft EIP(s) - The creator of this PR is listed as an author on all modified EIP(s) - The build is passing --- EIPS/eip-615.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-615.md b/EIPS/eip-615.md index ad9d94fcf93da..45216921a0080 100644 --- a/EIPS/eip-615.md +++ b/EIPS/eip-615.md @@ -211,9 +211,8 @@ Validating that jumps are to valid addresses takes two sequential passes over th bool validate_jumps(PC) { - current_sub = PC - // build sets of BEGINSUBs and JUMPDESTs + current_sub = 0 for (PC = 0; instruction = bytecode[PC]; PC = advance_pc(PC)) { if instruction is invalid @@ -230,6 +229,7 @@ Validating that jumps are to valid addresses takes two sequential passes over th } // check that targets are in subroutine + current_sub = 0 for (PC = 0; instruction = bytecode[PC]; PC = advance_pc(PC)) { if instruction is BEGINDATA From 12dba40dbea0bcc06c4c7e2962c27fe26312ec8a Mon Sep 17 00:00:00 2001 From: MattLongCT <37944261+MattLongCT@users.noreply.github.com> Date: Thu, 5 Apr 2018 04:13:12 -0400 Subject: [PATCH 0604/1085] eip-3.md --> Status: Deferred (#971) --- EIPS/eip-3.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-3.md b/EIPS/eip-3.md index 2cf96c9707e42..6337851663540 100644 --- a/EIPS/eip-3.md +++ b/EIPS/eip-3.md @@ -2,7 +2,7 @@ eip: 3 title: Addition of CALLDEPTH opcode author: Martin Holst Swende -status: Draft +status: Deferred type: Standards Track category: Core created: 2015-11-19 From 640013e503dd2c3da4c13474ba295783a696a3ee Mon Sep 17 00:00:00 2001 From: MattLongCT <37944261+MattLongCT@users.noreply.github.com> Date: Thu, 5 Apr 2018 06:56:33 -0400 Subject: [PATCH 0605/1085] Updated Category to Meta (#972) --- EIPS/eip-609.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-609.md b/EIPS/eip-609.md index fce499ad34e79..bd423e4b96beb 100644 --- a/EIPS/eip-609.md +++ b/EIPS/eip-609.md @@ -3,7 +3,7 @@ eip: 609 title: "Hardfork Meta: Byzantium" author: Alex Beregszaszi type: Standards Track -category: Core +category: Meta status: Final created: 2017-04-23 requires: 100, 140, 196, 197, 198, 211, 214, 649, 658 From 70f7c10d15b4591c45c509c570afbbeeeb9bef83 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Thu, 5 Apr 2018 17:04:47 +0100 Subject: [PATCH 0606/1085] Create EIP 191 (#973) --- EIPS/eip-191.md | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 EIPS/eip-191.md diff --git a/EIPS/eip-191.md b/EIPS/eip-191.md new file mode 100644 index 0000000000000..de91f24f0c6fa --- /dev/null +++ b/EIPS/eip-191.md @@ -0,0 +1,63 @@ +--- +eip: 191 +title: Signed Data Standard +authors: Martin Holst Swende (@holiman), Nick Johnson +Status: Draft +Type: Standards Track +Category: ERC +Created: 2016-01-20 +--- + +# Abstract + +This ERC proposes a specification about how to handle signed data in Etherum contracts. + +# Motivation + +Several multisignature wallet implementations have been created which accepts `presigned` transactions. A `presigned` transaction is a chunk of binary `signed_data`, along with signature (`r`, `s` and `v`). The interpretation of the `signed_data` has not been specified, leading to several problems: + +* Standard Ethereum transactions can be submitted as `signed_data`. An Ethereum transaction can be unpacked, into the following components: `RLP` (hereby called `RLPdata`), `r`, `s` and `v`. If there are no syntactical constraints on `signed_data`, this means that `RLPdata` can be used as a syntactically valid `presigned` transaction. +* Multisignature wallets have also had the problem that a `presigned` transaction has not been tied to a particular `validator`, i.e a specific wallet. Example: + 1. Users `A`, `B` and `C` have the `2/3`-wallet `X` + 2. Users `A`, `B` and `D` have the `2/3`-wallet `Y` + 3. User `A` and `B` submites `presigned` transaction to `X`. + 4. Attacker can now reuse their presigned transactions to `X`, and submit to `Y`. + +## Specification + +We propose the following format for `signed_data` + +``` +0x19 <1 byte version> . +``` +Version `0` has `<20 byte address>` for the version specific data, and the `address` is the intended validator. In the case of a Multisig wallet, that is the wallet's own address . + +The initial `0x19` byte is intended to ensure that the `signed_data` is not valid [RLP](https://github.com/ethereum/wiki/wiki/RLP) + +> For a single byte whose value is in the [0x00, 0x7f] range, that byte is its own RLP encoding. + +That means that any `signed_data` cannot be one RLP-structure, but a 1-byte `RLP` payload followed by something else. Thus, any ERC-191 `signed_data` can never be an Ethereum transaction. + +Additionally, `0x19` has been chosen because since ethereum/go-ethereum#2940 , the following is prepended before hashing in personal_sign: + +``` +"\x19Ethereum Signed Message:\n" + len(message). +``` + +Using `0x19` thus makes it possible to extend the scheme by defining a version `0x45` (`E`) to handle these kinds of signatures. + +### Example + + function submitTransactionPreSigned(address destination, uint value, bytes data, uint nonce, uint8 v, bytes32 r, bytes32 s) + public + returns (bytes32 transactionHash) + { + // Arguments when calculating hash to validate + // 1: byte(0x19) - the initial 0x19 byte + // 2: byte(0) - the version byte + // 4: this - the validator address + // 4-7 : Application specific data + transactionHash = keccak256(byte(0x19),byte(0),this,destination, value, data, nonce); + sender = ecrecover(transactionHash, v, r, s); + // ... + } From 5208cb7abb99eaf5f190859044e8f810ba128d15 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Thu, 5 Apr 2018 18:55:49 +0200 Subject: [PATCH 0607/1085] Address Collision of Contract Address Causes Exceptional Halt (#689) * Add an EIP about making contract creation fail on address collision * Use 689 https://github.com/ethereum/EIPs/pull/689#discussion_r154454788 * Adjust formats according to https://github.com/ethereum/EIPs/pull/689#issuecomment-376559878 * Cleanups by @Arachnid --- EIPS/eip-689.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 EIPS/eip-689.md diff --git a/EIPS/eip-689.md b/EIPS/eip-689.md new file mode 100644 index 0000000000000..fe19393973363 --- /dev/null +++ b/EIPS/eip-689.md @@ -0,0 +1,48 @@ +--- +eip: 689 +title: Address Collision of Contract Address Causes Exceptional Halt +author: Yoichi Hirai +type: Standard Track +category: Core +status: Draft +created: 2017-08-15 +--- + +## Simple Summary + +This EIP proposes to make contract creation fail on an account with nonempty code or non-zero nonce. + +## Abstract + +Some test cases in the consensus test suite try to deploy a contract at an address already with nonempty code. Although such cases can virtually never happen on the main network before the Constantinople fork block, the test cases detected discrepancies in clients' behavior. Currently, the Yellow Paper says that the contract creation starts with the empty code and the initial nonce even in the case of address collisions. To simplify the semantics, this EIP proposes that address collisions cause failures of contract creation. + +## Motivation + +This EIP has no practical relevance to the main net history, but simplifies testing and reasoning. + +This EIP has no effects after Constantinople fork because [EIP-86](https://github.com/ethereum/EIPs/pull/208) contains the changes proposed in this EIP. Even before the Constantinople fork, this EIP has no practical relevance because the change is visible only in case of a hash collision of keccak256. + +Regarding testing, this EIP relieves clients from supporting reversion of code overwriting. + +Regarding reasoning, this EIP establishes an invariant that non-empty code is never modified. + +## Specification + +If `block.number >= 0`, when a contract creation is on an account with non-zero nonce or non-empty code, the creation fails as if init code execution resulted in an exceptional halt. This applies to contract creation triggered by a contract creation transaction and by CREATE instruction. + +## Rationale + +It seems impractical to implement never-used features just for passing tests. Client implementations will be simpler with this EIP. + +## Backwards Compatibility + +This EIP is backwards compatible on the main network. + +## Test Cases + +At least the BlockchainTest called `createJS\_ExampleContract\_d0g0v0\_EIP158` will distinguish clients that implement this EIP. + +## Implementation + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 458d33872aa29cf63eb5a3049897af0c249f6f80 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Thu, 5 Apr 2018 21:01:04 +0100 Subject: [PATCH 0608/1085] EIP 609 should be Category: Meta, not Type: Meta --- EIPS/eip-609.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/EIPS/eip-609.md b/EIPS/eip-609.md index bd423e4b96beb..b81474388105b 100644 --- a/EIPS/eip-609.md +++ b/EIPS/eip-609.md @@ -2,8 +2,7 @@ eip: 609 title: "Hardfork Meta: Byzantium" author: Alex Beregszaszi -type: Standards Track -category: Meta +type: Meta status: Final created: 2017-04-23 requires: 100, 140, 196, 197, 198, 211, 214, 649, 658 From 164b08148ddc3ac36afb330e47f662fe176a35e3 Mon Sep 17 00:00:00 2001 From: ligi Date: Fri, 6 Apr 2018 13:56:43 +0200 Subject: [PATCH 0609/1085] Update to new ABI spec URL (#978) The old one is not maintained anymore - the new one is updated - e.g. now contains tuples --- EIPS/eip-681.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-681.md b/EIPS/eip-681.md index 4133fdfeec806..a3165e6a58b1c 100644 --- a/EIPS/eip-681.md +++ b/EIPS/eip-681.md @@ -37,7 +37,7 @@ Payment request URLs contain "ethereum" in their schema (protocol) part and are number = [ "-" / "+" ] *DIGIT [ "." 1*DIGIT ] [ ( "e" / "E" ) [ 1*DIGIT ] [ "+" UNIT ] -Where `TYPE` is a standard ABI type name, as defined in [Ethereum Contract ABI specification](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI). `STRING` is a URL-encoded unicode string of arbitrary length, where delimiters and the +Where `TYPE` is a standard ABI type name, as defined in [Ethereum Contract ABI specification](https://solidity.readthedocs.io/en/develop/abi-spec.html). `STRING` is a URL-encoded unicode string of arbitrary length, where delimiters and the percentage symbol (`%`) are mandatorily hex-encoded with a `%` prefix. `UNIT` is a URL-encoded unicode string. If `UNIT` is ETH, it always means a multiplier of 1018. If it is something From 5b8055c85ead2d6f305e6211b01460308172789c Mon Sep 17 00:00:00 2001 From: Jacques Dafflon Date: Fri, 6 Apr 2018 14:39:26 +0200 Subject: [PATCH 0610/1085] Move EIP assets to assets folder (#977) - Create `assets` folder - Move existing EIPs (1, 107, 858) assets into the `assets` folder - Update link to assets in EIPs 1, 107 and 858 - Describe the inclusion of assets for EIPs in `README.md` --- EIPS/eip-1.md | 7 ++++--- EIPS/eip-107.md | 6 +++--- EIPS/eip-858.md | 2 +- README.md | 2 ++ {EIPS => assets}/eip-1/process.png | Bin {EIPS => assets}/eip-107/authorization-locked.png | Bin {EIPS => assets}/eip-107/authorization-password.png | Bin {EIPS => assets}/eip-107/authorization.png | Bin {EIPS => assets}/eip-858/calculations.md | 0 9 files changed, 10 insertions(+), 7 deletions(-) rename {EIPS => assets}/eip-1/process.png (100%) rename {EIPS => assets}/eip-107/authorization-locked.png (100%) rename {EIPS => assets}/eip-107/authorization-password.png (100%) rename {EIPS => assets}/eip-107/authorization.png (100%) rename {EIPS => assets}/eip-858/calculations.md (100%) diff --git a/EIPS/eip-1.md b/EIPS/eip-1.md index 79df47c82ccc8..73390cd5ca375 100644 --- a/EIPS/eip-1.md +++ b/EIPS/eip-1.md @@ -44,7 +44,7 @@ Each EIP must have a champion - someone who writes the EIP using the style and f Vetting an idea publicly before going as far as writing an EIP is meant to save the potential author time. Asking the Ethereum community first if an idea is original helps prevent too much time being spent on something that is guaranteed to be rejected based on prior discussions (searching the Internet does not always do the trick). It also helps to make sure the idea is applicable to the entire community and not just the author. Just because an idea sounds good to the author does not mean it will work for most people in most areas where Ethereum is used. Examples of appropriate public forums to gauge interest around your EIP include [the Ethereum subreddit], [the Issues section of this repository], and [one of the Ethereum Gitter chat rooms]. In particular, [the Issues section of this repository] is an excellent place to discuss your proposal with the community and start creating more formalized language around your EIP. -Once the champion has asked the Ethereum community whether an idea has any chance of acceptance a draft EIP should be presented as a [pull request]. +Once the champion has asked the Ethereum community whether an idea has any chance of acceptance a draft EIP should be presented as a [pull request]. If the EIP collaborators approve, the EIP editor will assign the EIP a number (generally the issue or PR number related to the EIP) and merge your pull request. The EIP editor will not unreasonably deny an EIP. Reasons for denying EIP status include duplication of effort, being technically unsound, not providing proper motivation or addressing backwards compatibility, or not in keeping with the Ethereum philosophy. @@ -64,7 +64,7 @@ EIPs can also be superseded by a different EIP, rendering the original obsolete. The possible paths of the status of EIPs are as follows: -![EIP Process](eip-1/process.png) +![EIP Process](../assets/eip-1/process.png) Some Informational and Process EIPs may also have a status of “Active” if they are never meant to be completed. E.g. EIP 1 (this EIP). @@ -114,7 +114,8 @@ Each EIP should have the following parts: EIP Formats and Templates ------------------------- -EIPs should be written in [markdown] format. Image files should be included in a subdirectory for that EIP. +EIPs should be written in [markdown] format. +Image files should be included in a subdirectory of the `assets` folder for that EIP as follow: `assets/eip-X` (for eip **X**). When linking to an image in the EIP, use relative links such as `../assets/eip-X/image.png`. EIP Header Preamble ------------------- diff --git a/EIPS/eip-107.md b/EIPS/eip-107.md index 494fdca1279ac..48b13a0390b60 100644 --- a/EIPS/eip-107.md +++ b/EIPS/eip-107.md @@ -29,19 +29,19 @@ Account unlocked : ----------------- When the account is already unlocked, the user is presented with the following popup for every transaction that the dapp attempts to make: -![](eip-107/authorization.png) +![](../assets/eip-107/authorization.png) Account locked and no "personal" api exposed via rpc: ----------------- When the account is locked, and the node does not provide access to account unlocking via its rpc interface, the following popup will be presented. This is not ideal since this requires the user to know how to unlock an account: -![](eip-107/authorization-locked.png) +![](../assets/eip-107/authorization-locked.png) Account locked but node exposing the "personal" api via rpc : ----------------- A better option is to ask the user for their password, but this is only possible if the node allows access to the "personal" api via rpc. In such case, the following dialog will be presented to the user so he/she can accept the transaction by providing the password required to unlock the account: -![](eip-107/authorization-password.png) +![](../assets/eip-107/authorization-password.png) Specification diff --git a/EIPS/eip-858.md b/EIPS/eip-858.md index b40ed5a4aa175..71ca2b96567f5 100644 --- a/EIPS/eip-858.md +++ b/EIPS/eip-858.md @@ -15,7 +15,7 @@ Reduce the block reward to 1 ETH. The current public Ethereum network has a hashrate that corresponds to a tremendous level of energy consumption. As this energy consumption has a correlated environmental cost the network participants have an ethical obligation to ensure this cost is not higher than necessary. At this time, the most direct way to reduce this cost is to lower the block reward in order to limit the appeal of ETH mining. Unchecked growth in hashrate is also counterproductive from a security standpoint. ## Motivation -The current public Ethereum network has a hashrate of 232 TH/s). This hashrate corresponds to a **lower bound** for power usage of roughly [821 MW](eip-858/calculations.md) and yearly energy consumption of 7.2 TWh (roughly 0.033% of [total](https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption) global electricity consumption). A future switch to full Proof of Stake will solve this issue entirely. Yet that switch remains enough in the future that action should be taken in the interim to limit excess harmful side affects of the present network. +The current public Ethereum network has a hashrate of 232 TH/s). This hashrate corresponds to a **lower bound** for power usage of roughly [821 MW](../assets/eip-858/calculations.md) and yearly energy consumption of 7.2 TWh (roughly 0.033% of [total](https://en.wikipedia.org/wiki/List_of_countries_by_electricity_consumption) global electricity consumption). A future switch to full Proof of Stake will solve this issue entirely. Yet that switch remains enough in the future that action should be taken in the interim to limit excess harmful side affects of the present network. ## Specification Block reward to be changed to 1 ETH / block. diff --git a/README.md b/README.md index 0469ec30d151e..2c9856a797208 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ A browsable version of all current and draft EIPs can be found on [the official Your first PR should be a first draft of the final EIP. It must meet the formatting criteria enforced by the build (largely, correct metadata in the header). An editor will manually review the first PR for a new EIP and assign it a number before merging it. Make sure you include a `discussions-to` header with the URL to a discussion forum or open GitHub issue where people can discuss the EIP as a whole. +If your EIP requires images, the image files should be included in a subdirectory of the `assets` folder for that EIP as follow: `assets/eip-X` (for eip **X**). When linking to an image in the EIP, use relative links such as `../assets/eip-X/image.png`. + Once your first PR is merged, we have a bot that helps out by automatically merging PRs to draft EIPs. For this to work, it has to be able to tell that you own the draft being edited. Make sure that the 'author' line of your EIP contains either your Github username or your email address inside . If you use your email address, that address must be the one publicly shown on [your GitHub profile](https://github.com/settings/profile). When you believe your EIP is mature and ready to progress past the draft phase, you should do one of two things: diff --git a/EIPS/eip-1/process.png b/assets/eip-1/process.png similarity index 100% rename from EIPS/eip-1/process.png rename to assets/eip-1/process.png diff --git a/EIPS/eip-107/authorization-locked.png b/assets/eip-107/authorization-locked.png similarity index 100% rename from EIPS/eip-107/authorization-locked.png rename to assets/eip-107/authorization-locked.png diff --git a/EIPS/eip-107/authorization-password.png b/assets/eip-107/authorization-password.png similarity index 100% rename from EIPS/eip-107/authorization-password.png rename to assets/eip-107/authorization-password.png diff --git a/EIPS/eip-107/authorization.png b/assets/eip-107/authorization.png similarity index 100% rename from EIPS/eip-107/authorization.png rename to assets/eip-107/authorization.png diff --git a/EIPS/eip-858/calculations.md b/assets/eip-858/calculations.md similarity index 100% rename from EIPS/eip-858/calculations.md rename to assets/eip-858/calculations.md From ea5b7b32fe7f959bb79c04731d62725e7b0a50df Mon Sep 17 00:00:00 2001 From: Jordi Baylina Date: Fri, 6 Apr 2018 15:01:42 +0200 Subject: [PATCH 0611/1085] ERC-820 Pseudo-introspection using a registry contract. (#906) * ERC-820 Pseudo-introspection using a registry contract. * Typos, links, and better explanation of Nicks deployment method * Formating fix * Email address * solidity syntax highlight * Adapt to new template for EIPs * Discussions link added * Fix link in discussion-to * Type fixed --- EIPS/eip-820.md | 274 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 EIPS/eip-820.md diff --git a/EIPS/eip-820.md b/EIPS/eip-820.md new file mode 100644 index 0000000000000..c3987645e5066 --- /dev/null +++ b/EIPS/eip-820.md @@ -0,0 +1,274 @@ +--- +eip: 820 +title: Pseudo-introspection registry contract +author: Jordi Baylina +discussions-to: https://github.com/ethereum/EIPs/issues/820 +status: Draft +type: Standards Track +category: ERC +created: 2018-01-05 +--- + +## Simple Summary + +This standard defines a universal registry smart contract where any address (contract or regular account) can register which interface it implements and which smart contract is responsible for its implementation. + +This standard keeps backwards compatibility with [EIP-165](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md) + +## Abstract + +This standard attempts to define a registry where smart contracts and regular accounts can publish which functionalities they implement. + +The rest of the world can query this registry to ask if a specific address implements a given interface and which smart contract handles its implementation. + +This registry can be deployed on any chain and will share the exact same address. + +Interfaces where the last 28 bytes are `0` are considered [EIP-165](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md) interfaces, and this registry +will forward the call to the contract to see if they implement that interface. + +This contract will act also as an [EIP-165](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md) cache in order to safe gas. + +## Motivation + +There has been different approaches to define pseudo-introspection in the Ethereum. The first is [EIP-165](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md) which has the problem that it is not available for regular accounts to use. The second approach is EIP-672 which uses reverseENS. Using reverseENS, has two issues. First, it is unnecessarily complex, and second, ENS is still a centralized contract controlled by a multisig. This multisig, theoretically would be able to modify the system. + +This standard is much simpler than [EIP-672](https://github.com/ethereum/EIPs/issues/672) and it is absolutely decentralized. + +This standard also solves the problem of having different addresses for different chains. + +## Specification + +### The smart contract + +```solidity +pragma solidity 0.4.20; + +interface ERC820ImplementerInterface { + /// @notice Contracts that implement an interferce in behalf of another contract must return true + /// @param addr Address that the contract woll implement the interface in behalf of + /// @param interfaceHash keccak256 of the name of the interface + /// @return ERC820_ACCEPT_MAGIC if the contract can implement the interface represented by + /// `ìnterfaceHash` in behalf of `addr` + function canImplementInterfaceForAddress(address addr, bytes32 interfaceHash) view public returns(bytes32); +} + +contract ERC820Registry { + bytes4 constant InvalidID = 0xffffffff; + bytes4 constant ERC165ID = 0x01ffc9a7; + bytes32 constant ERC820_ACCEPT_MAGIC = keccak256("ERC820_ACCEPT_MAGIC"); + + + mapping (address => mapping(bytes32 => address)) interfaces; + mapping (address => address) managers; + mapping (address => mapping(bytes4 => bool)) erc165Cache; + + modifier canManage(address addr) { + require(getManager(addr) == msg.sender); + _; + } + + + event InterfaceImplementerSet(address indexed addr, bytes32 indexed interfaceHash, address indexed implementer); + event ManagerChanged(address indexed addr, address indexed newManager); + + /// @notice Query the hash of an interface given a name + /// @param interfaceName Name of the interfce + function interfaceHash(string interfaceName) public pure returns(bytes32) { + return keccak256(interfaceName); + } + + /// @notice GetManager + function getManager(address addr) public view returns(address) { + // By default the manager of an address is the same address + if (managers[addr] == 0) { + return addr; + } else { + return managers[addr]; + } + } + + /// @notice Sets an external `manager` that will be able to call `setInterfaceImplementer()` + /// on behalf of the address. + /// @param addr Address that you are defining the manager for. + /// @param newManager The address of the manager for the `addr` that will replace + /// the old one. Set to 0x0 if you want to remove the manager. + function setManager(address addr, address newManager) public canManage(addr) { + managers[addr] = newManager == addr ? 0 : newManager; + ManagerChanged(addr, newManager); + } + + /// @notice Query if an address implements an interface and thru which contract + /// @param addr Address that is being queried for the implementation of an interface + /// @param iHash SHA3 of the name of the interface as a string + /// Example `web3.utils.sha3('ERC777Token`')` + /// @return The address of the contract that implements a specific interface + /// or 0x0 if `addr` does not implement this interface + function getInterfaceImplementer(address addr, bytes32 iHash) constant public returns (address) { + if (isERC165Interface(iHash)) { + bytes4 i165Hash = bytes4(iHash); + return erc165InterfaceSupported(addr, i165Hash) ? addr : 0; + } + return interfaces[addr][iHash]; + } + + /// @notice Sets the contract that will handle a specific interface; only + /// the address itself or a `manager` defined for that address can set it + /// @param addr Address that you want to define the interface for + /// @param iHash SHA3 of the name of the interface as a string + /// For example `web3.utils.sha3('Ierc777')` for the Ierc777 + function setInterfaceImplementer(address addr, bytes32 iHash, address implementer) public canManage(addr) { + require(!isERC165Interface(iHash)); + if ((implementer != 0) && (implementer!=msg.sender)) { + require(ERC820ImplementerInterface(implementer).canImplementInterfaceForAddress(addr, iHash) + == ERC820_ACCEPT_MAGIC); + } + interfaces[addr][iHash] = implementer; + InterfaceImplementerSet(addr, iHash, implementer); + } + + +/// ERC165 Specific + + function isERC165Interface(bytes32 iHash) internal pure returns (bool) { + return iHash & 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0; + } + + function erc165InterfaceSupported(address _contract, bytes4 _interfaceId) constant public returns (bool) { + if (!erc165Cache[_contract][_interfaceId]) { + erc165UpdateCache(_contract, _interfaceId); + } + return interfaces[_contract][_interfaceId] != 0; + } + + function erc165UpdateCache(address _contract, bytes4 _interfaceId) public { + interfaces[_contract][_interfaceId] = + erc165InterfaceSupported_NoCache(_contract, _interfaceId) ? _contract : 0; + erc165Cache[_contract][_interfaceId] = true; + } + + function erc165InterfaceSupported_NoCache(address _contract, bytes4 _interfaceId) public constant returns (bool) { + uint256 success; + uint256 result; + + (success, result) = noThrowCall(_contract, ERC165ID); + if ((success==0)||(result==0)) { + return false; + } + + (success, result) = noThrowCall(_contract, InvalidID); + if ((success==0)||(result!=0)) { + return false; + } + + (success, result) = noThrowCall(_contract, _interfaceId); + if ((success==1)&&(result==1)) { + return true; + } + return false; + } + + function noThrowCall(address _contract, bytes4 _interfaceId) constant internal returns (uint256 success, uint256 result) { + bytes4 erc165ID = ERC165ID; + + assembly { + let x := mload(0x40) // Find empty storage location using "free memory pointer" + mstore(x, erc165ID) // Place signature at begining of empty storage + mstore(add(x, 0x04), _interfaceId) // Place first argument directly next to signature + + success := staticcall( + 30000, // 30k gas + _contract, // To addr + x, // Inputs are stored at location x + 0x08, // Inputs are 8 bytes long + x, // Store output over input (saves space) + 0x20) // Outputs are 32 bytes long + + result := mload(x) // Load the result + } + } +} +``` + +### Raw transaction for deploying the smart contract on any chain + +``` +0xf908778085174876e800830c35008080b908246060604052341561000f57600080fd5b6108068061001e6000396000f30060606040526004361061008d5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166329965a1d81146100925780633d584063146100bd578063571a1f66146100f85780635df8122f1461012457806365ba36c11461014957806390e47957146101ac578063aabbb8ca146101ec578063ddc23ddd1461020e575b600080fd5b341561009d57600080fd5b6100bb600160a060020a03600435811690602435906044351661023a565b005b34156100c857600080fd5b6100dc600160a060020a03600435166103ec565b604051600160a060020a03909116815260200160405180910390f35b341561010357600080fd5b6100bb600160a060020a0360043516600160e060020a031960243516610438565b341561012f57600080fd5b6100bb600160a060020a03600435811690602435166104c2565b341561015457600080fd5b61019a60046024813581810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061057d95505050505050565b60405190815260200160405180910390f35b34156101b757600080fd5b6101d8600160a060020a0360043516600160e060020a0319602435166105e2565b604051901515815260200160405180910390f35b34156101f757600080fd5b6100dc600160a060020a0360043516602435610658565b341561021957600080fd5b6101d8600160a060020a0360043516600160e060020a0319602435166106b7565b8233600160a060020a031661024e826103ec565b600160a060020a03161461026157600080fd5b61026a8361076e565b1561027457600080fd5b600160a060020a0382161580159061029e575033600160a060020a031682600160a060020a031614155b15610373576040517f4552433832305f4143434550545f4d41474943000000000000000000000000008152601301604051908190039020600160a060020a03831663f008325086866000604051602001526040517c010000000000000000000000000000000000000000000000000000000063ffffffff8516028152600160a060020a0390921660048301526024820152604401602060405180830381600087803b151561034b57600080fd5b6102c65a03f1151561035c57600080fd5b505050604051805191909114905061037357600080fd5b600160a060020a0384811660008181526020818152604080832088845290915290819020805473ffffffffffffffffffffffffffffffffffffffff191693861693841790558591907f93baa6efbd2244243bfee6ce4cfdd1d04fc4c0e9a786abd3a41313bd352db153905160405180910390a450505050565b600160a060020a038082166000908152600160205260408120549091161515610416575080610433565b50600160a060020a03808216600090815260016020526040902054165b919050565b61044282826106b7565b61044d57600061044f565b815b600160a060020a03928316600081815260208181526040808320600160e060020a031996909616808452958252808320805473ffffffffffffffffffffffffffffffffffffffff19169590971694909417909555908152600284528181209281529190925220805460ff19166001179055565b8133600160a060020a03166104d6826103ec565b600160a060020a0316146104e957600080fd5b82600160a060020a031682600160a060020a031614610508578161050b565b60005b600160a060020a0384811660008181526001602052604090819020805473ffffffffffffffffffffffffffffffffffffffff191694841694909417909355908416917f605c2dbf762e5f7d60a546d42e7205dcb1b011ebc62a61736a57c9089d3a4350905160405180910390a3505050565b6000816040518082805190602001908083835b602083106105af5780518252601f199092019160209182019101610590565b6001836020036101000a038019825116818451161790925250505091909101925060409150505180910390209050919050565b600160a060020a0382166000908152600260209081526040808320600160e060020a03198516845290915281205460ff161515610623576106238383610438565b50600160a060020a03918216600090815260208181526040808320600160e060020a0319949094168352929052205416151590565b6000806106648361076e565b1561068957508161067584826105e2565b610680576000610682565b835b91506106b0565b600160a060020a038085166000908152602081815260408083208784529091529020541691505b5092915050565b600080806106e5857f01ffc9a700000000000000000000000000000000000000000000000000000000610790565b90925090508115806106f5575080155b156107035760009250610766565b61071585600160e060020a0319610790565b909250905081158061072657508015155b156107345760009250610766565b61073e8585610790565b90925090506001821480156107535750806001145b156107615760019250610766565b600092505b505092915050565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff161590565b6000807f01ffc9a70000000000000000000000000000000000000000000000000000000060405181815284600482015260208160088389617530fa935080519250505092509290505600a165627a7a72305820b424185958879a1eef1cb7235bfd8ed607a7402b46853860e5343340925f028e00291ba079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798a00aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +``` + +You can see the string of `a`s at the end of the transaction. This is the `s` of the signature, meaning that its a deterministic by hand forced signature. + +### Deployment method + +This contract is going to be deployed using the Nick's Method. + +This method works as follows: + +1. Generate a transaction that deploys the contract from a new random account. This transaction must not use [EIP-155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md) so it can work on any chain. This transaction needs to also have a relatively high gas price in order to be deployed in any chain. In this case, it's going to be 100Gwei. +2. Set the `v`, `r`, `s` of the transaction signature to the following values: +` + v: 27` +` + r: 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798` +` + s: 0x0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` +This nice `s` value is a random number generated deterministically by a human. +3. We recover the sender of this transaction. We will have an account that can broadcast that transaction, but we also have the waranty that nobody knows the private key of that account. +4. Send Ether to this deployment account. +5. Broadcast the transaction. + +This operation can be done in any chain, guaranteed that the contract address is going to always be the same and nobody will be able to mess up that address with a different contract. + + +### Special registry deployment account + +``` +0x91c2b265ece9442ed28e3c4283652b1894dcdabb +``` + +This account is generated by reverse engineering it from it's signature for the transaction, in this way no one knows the private key, but it is known that it's the valid signer of the deployment transaction. + +### Deployed contract + +``` +0x991a1bcb077599290d7305493c9a630c20f8b798 +``` + +The contract will have this address for every chain it is deployed to. + +### Interface name + +Your interface name is hashed and sent to `getInterfaceImplementer()`. If you are writing a standard, it is best practice to explicitly state the interface name and link to this published EIP-820 so that other people don't have to come here to look up these rules. + +#### If it's an approved EIP + +The interface is named like `ERC###XXXXX`. The meaning of this interface is defined in the EIP specified. And XXX should be the name of the interface camelCase. + +Examples: + +`sha3("ERC20Token")` +`sha3("ERC777Token")` +`sha3("ERC777TokensReceiver")` +`sha3("ERC777TokensSender")` + +#### [EIP-165](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md) compatible interfaces + +Interfaces where the last 28bytes are 0, then this will be considered an [EIP-165](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md) interface. + +#### Private user defined interface + +This scheme is extensible. If you want to make up your own interface name and raise awareness to get other people to implement it and then check for those implementations, great! Have fun, but please do not conflict with the reserved designations above. + +## Backwards Compatibility + +This standard is backwards compatible with [EIP-165](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md), as both methods can be implemented without conflicting one each other. + +## Test Cases + +Please, check the repository https://github.com/jbaylina/eip820 for the full test suit. + +## Implementation + +The implementation can be found in this repo: https://github.com/jbaylina/eip820 + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 9fba86e56defc6cc77ea9797f63640901c81d8f2 Mon Sep 17 00:00:00 2001 From: David Stanfill Date: Fri, 6 Apr 2018 09:15:32 -0400 Subject: [PATCH 0612/1085] Automatically merged updates to draft EIP(s) 969 Hi, I'm a bot! This change was automatically merged because: - It only modifies existing draft EIP(s) - The PR was approved or written by at least one author of each modified EIP - The build is passing --- EIPS/eip-969.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/EIPS/eip-969.md b/EIPS/eip-969.md index cc3c69c25ddaf..7c1e0a47f84f9 100644 --- a/EIPS/eip-969.md +++ b/EIPS/eip-969.md @@ -94,8 +94,7 @@ existing ethash algorithm. We hope to accomplish the following: Goal #1 is something that we can only do probabilistically without detailed knowledge of existing ASIC miner design. The known released miner is available for -purchase at https://shop.bitmain.com/product/detail?pid=00020180403174908564M8dMJKtz06B7 -with delivery slated for mid-summer. +purchase [here](https://shop.bitmain.com/product/detail?pid=00020180403174908564M8dMJKtz06B7) with delivery slated for mid-summer. Our approach should balance the inherent security risks involved with changing the mining algorithm with the risk that the change we make does not break existing @@ -173,13 +172,14 @@ It can be empirically confirmed that no more than 1 duplicates occur in the 32 b It is worth noting that FNV is not a cryptographic hash, and it is not used as such in ethash. With that said, a more invasive hash algorithm change could consider other options. One suggestion has been -MurmorHash3 (https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp) +[MurmorHash3](https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp). -Other suggestions have been made for complete algorithm changes, including off-the-shelf solutions -such as Argon2, Equihash of Zcash fame, and Balloon Hashing. -(https://twitter.com/el33th4xor/status/981292363627810818). This may be considered once -the exact mechanism of the released ASICs is known and their effectiveness against its optimisations -can be fully evaluated. +[Other suggestions have been made](https://twitter.com/el33th4xor/status/981292363627810818). [Argon2](https://github.com/P-H-C/phc-winner-argon2), [Equihash](https://blog.z.cash/why-equihash/) of Zcash fame, and [Balloon Hashing](https://crypto.stanford.edu/balloon/). + +Another possible candidate is [Cuckoo Cycle](https://github.com/tromp/cuckoo), although there are some concerns regarding unaddressed optimization vulnerabilities. One review is found [here](https://da-data.blogspot.com/2014/03/a-public-review-of-cuckoo-cycle.html) + +This may be considered once the exact mechanism of the released ASICs is known and +their effectiveness against its optimisations can be fully evaluated. ## Backwards Compatibility From 547af9da8ce936d2a7630931e89f023bbedaa2e9 Mon Sep 17 00:00:00 2001 From: Jordi Baylina Date: Fri, 6 Apr 2018 15:52:05 +0200 Subject: [PATCH 0613/1085] ERC-777 A New Advanced Token Standard (#907) * ERC777 A New Advanced Token Standard * ERC777: Add ERC777 Logo * ERC777: Normalize EIP/ERC names * ERC777: Spec for tokensToSend when burning tokens * ERC777: Update official repository * ERC777: Clarification and corrections - Clarify unclear sections of the spec - Fix typos and grammar mistakes - Improve aesthetics of the text * ERC777: Change terminology of the repo, small fix - Don't refer to the repo as the official repo but the repo of the reference implementation - Fix a small typo in the AuthorizedOperator event * ERC777: logo & release to public domain (CC0) * ERC777: Use markdown not html & relative links * ERC777: Adapt to new EIP template * ERC777: Use solidity syntax and fix relative links * ERC777: Add discussions-to link * ERC777: Fix link in discussion-to * ERC777: Fix image links * ERC777: Fix eip type * ERC777: Update header --- EIPS/eip-777.md | 544 ++++++++++++++++++ .../logo/png/ERC-777-logo-beige-1024px.png | Bin 0 -> 4202201 bytes .../logo/png/ERC-777-logo-beige-192px.png | Bin 0 -> 147973 bytes .../logo/png/ERC-777-logo-beige-2048px.png | Bin 0 -> 16806489 bytes .../logo/png/ERC-777-logo-beige-48px.png | Bin 0 -> 9365 bytes .../logo/png/ERC-777-logo-beige-600px.png | Bin 0 -> 1442999 bytes .../logo/png/ERC-777-logo-black-1024px.png | Bin 0 -> 4202201 bytes .../logo/png/ERC-777-logo-black-192px.png | Bin 0 -> 147973 bytes .../logo/png/ERC-777-logo-black-2048px.png | Bin 0 -> 16806489 bytes .../logo/png/ERC-777-logo-black-48px.png | Bin 0 -> 9365 bytes .../logo/png/ERC-777-logo-black-600px.png | Bin 0 -> 1442999 bytes .../png/ERC-777-logo-dark_grey-1024px.png | Bin 0 -> 4202201 bytes .../logo/png/ERC-777-logo-dark_grey-192px.png | Bin 0 -> 147973 bytes .../png/ERC-777-logo-dark_grey-2048px.png | Bin 0 -> 16806489 bytes .../logo/png/ERC-777-logo-dark_grey-48px.png | Bin 0 -> 9365 bytes .../logo/png/ERC-777-logo-dark_grey-600px.png | Bin 0 -> 1442999 bytes .../png/ERC-777-logo-light_grey-1024px.png | Bin 0 -> 4202201 bytes .../png/ERC-777-logo-light_grey-192px.png | Bin 0 -> 147973 bytes .../png/ERC-777-logo-light_grey-2048px.png | Bin 0 -> 16806489 bytes .../logo/png/ERC-777-logo-light_grey-48px.png | Bin 0 -> 9365 bytes .../png/ERC-777-logo-light_grey-600px.png | Bin 0 -> 1442999 bytes .../logo/png/ERC-777-logo-white-1024px.png | Bin 0 -> 4202201 bytes .../logo/png/ERC-777-logo-white-192px.png | Bin 0 -> 147973 bytes .../logo/png/ERC-777-logo-white-2048px.png | Bin 0 -> 16806489 bytes .../logo/png/ERC-777-logo-white-48px.png | Bin 0 -> 9365 bytes .../logo/png/ERC-777-logo-white-600px.png | Bin 0 -> 1442999 bytes .../eip-777/logo/svg/ERC-777-logo-beige.svg | 21 + .../eip-777/logo/svg/ERC-777-logo-black.svg | 21 + .../logo/svg/ERC-777-logo-dark_grey.svg | 21 + .../logo/svg/ERC-777-logo-light_grey.svg | 21 + .../eip-777/logo/svg/ERC-777-logo-white.svg | 21 + 31 files changed, 649 insertions(+) create mode 100644 EIPS/eip-777.md create mode 100644 assets/eip-777/logo/png/ERC-777-logo-beige-1024px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-beige-192px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-beige-2048px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-beige-48px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-beige-600px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-black-1024px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-black-192px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-black-2048px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-black-48px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-black-600px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-dark_grey-1024px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-dark_grey-192px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-dark_grey-2048px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-dark_grey-48px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-dark_grey-600px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-light_grey-1024px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-light_grey-192px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-light_grey-2048px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-light_grey-48px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-light_grey-600px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-white-1024px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-white-192px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-white-2048px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-white-48px.png create mode 100644 assets/eip-777/logo/png/ERC-777-logo-white-600px.png create mode 100644 assets/eip-777/logo/svg/ERC-777-logo-beige.svg create mode 100644 assets/eip-777/logo/svg/ERC-777-logo-black.svg create mode 100644 assets/eip-777/logo/svg/ERC-777-logo-dark_grey.svg create mode 100644 assets/eip-777/logo/svg/ERC-777-logo-light_grey.svg create mode 100644 assets/eip-777/logo/svg/ERC-777-logo-white.svg diff --git a/EIPS/eip-777.md b/EIPS/eip-777.md new file mode 100644 index 0000000000000..b813e63359e02 --- /dev/null +++ b/EIPS/eip-777.md @@ -0,0 +1,544 @@ +--- +eip: 777 +title: A New Advanced Token Standard +author: Jordi Baylina , Jacques Dafflon , Thomas Shababi +discussions-to: https://github.com/ethereum/EIPs/issues/777 +status: Draft +type: Standards Track +category: ERC +created: 2017-11-20 +requires: 820 +--- + +## Simple Summary + +This EIP defines a standard interface for token contracts. + +*The repository for this standard containing the reference implementation can be found at [jacquesd/ERC777](https://github.com/jacquesd/ERC777) and installed via npm with: `npm install erc777`.* + +## Abstract + +This standard defines a new way to interact with a Token Contract. + +It defines operators to send tokens on behalf of another address – contract or regular account. It takes advantage of [ERC820](https://github.com/ethereum/EIPs/issues/820) to find out whether and where to notify contracts and regular addresses when they receive tokens as well as to allow compatibility with old contracts. + +## Motivation + +This standard tries to improve the widely used [ERC20](https://github.com/ethereum/EIPs/issues/20) token standard. The main advantages of this standard are: + +1. Uses the same philosophy as Ether in that tokens are sent with `send(dest, value, data)`. +2. Both contracts and regular address can control and reject which token they send by registering a `tokensToSend` function – rejection is done by throwing in the function. +3. Both contracts and regular addresses can control and reject which token they receive by registering a `tokensReceived` function – rejection is done by throwing in the function. +4. The `tokensReceived` function also avoids the double call needed in the ERC20 standard (`approve` / `transferFrom`). +5. The token holder can "authorize" and "revoke" operators who can send tokens on their behalf. These operators are intended to be verified contracts such as an exchange, a cheque processor or an automatic charging system. +6. Every token transaction contains a `userData` bytes field and a similar `operatorData` – in case of an operator transaction – to be used freely by the user (token holder) and the operator respectively to pass data to the recipient. +7. It is backwards compatible way with wallets that do not contain the `tokensReceived` function by deploying a proxy contract for the wallet. + +## Specification + +### ERC777Token (Token Contract) + +``` solidity +interface ERC777Token { + function name() public constant returns (string); + function symbol() public constant returns (string); + function totalSupply() public constant returns (uint256); + function granularity() public constant returns (uint256); + function balanceOf(address owner) public constant returns (uint256); + + function send(address to, uint256 amount) public; + function send(address to, uint256 amount, bytes userData) public; + + function authorizeOperator(address operator) public; + function revokeOperator(address operator) public; + function isOperatorFor(address operator, address tokenHolder) public constant returns (bool); + function operatorSend(address from, address to, uint256 amount, bytes userData, bytes operatorData) public; + + event Sent( + address indexed operator, + address indexed from, + address indexed to, + uint256 amount, + bytes userData, + bytes operatorData + ); + event Minted(address indexed operator, address indexed to, uint256 amount, bytes operatorData); + event Burned(address indexed operator, address indexed from, uint256 amount, bytes userData, bytes operatorData); + event AuthorizedOperator(address indexed operator, address indexed tokenHolder); + event RevokedOperator(address indexed operator, address indexed tokenHolder); +} +``` + +The token-contract MUST register the `ERC777Token` interface via ERC820. + +The basic unit token MUST be 1018. + +#### Methods +##### name + +``` solidity + function name() public constant returns (string) +``` + +Returns the name of the token – e.g. `"MyToken"`. + +> **returns:** Name of the token + +
    + +##### symbol + +``` solidity +function symbol() public constant returns (string) +``` + +Returns the symbol of the token – e.g. `"MYT"`. + +> **returns:** Symbol of the token + +
    + +##### granularity + +``` solidity +function granularity() public constant returns (uint256) +``` + +Returns the smallest part of the token that's not divisible. + +Any minting, transfer or burning of tokens MUST be a multiple of this value. Any operation that would result in a balance that's not a multiple of this value, MUST be considered invalid and the transaction MUST throw. + +Most of the tokens SHOULD be fully partitionable, i.e. this function SHOULD return `1` unless there is a good reason for not allowing any partition of the token. + +*NOTE*: `granularity` MUST be greater or equal to `1`. + +> **returns:** The smallest non divisible part of the token. + +
    + +##### totalSupply + +``` solidity +function totalSupply() public constant returns (uint256) +``` + +Get the total number of minted tokens. + +> **returns:** Total supply of tokens currently in circulation. + +
    + +##### balanceOf + +``` solidity +function balanceOf(address tokenHolder) public constant returns (uint256) +``` + +Get the balance of the account with address `tokenHolder`. +> **parameters** +> - `tokenHolder`: Address for which the balance is returned +> +> **returns:** Amount of token held by `tokenHolder` in the token contract. + +
    + +##### send + +``` solidity +function send(address to, uint256 amount) public +function send(address to, uint256 amount, bytes userData) public +``` + +Send `amount` of tokens to address `to`. + +This call MUST: + - call the `tokensToSend` method on the contract implementing `ERC777TokensSender` as returned by a ERC820 lookup on the `from` address – regardless if `from` is a regular address or a contract. + - call the `tokensReceived` method on the address implementing `ERC777TokensRecipient` as returned by a ERC820 lookup on the `to` address – regardless if `to` is a regular address or a contract. + - fire the `Sent` event. + +If `to` is a contract which is not prepared to receive tokens. Specifically, it is a contract which does not register an address (its own or another) via ERC820 implementing the `ERC777TokensRecipient` interface. Then `send` MUST throw. + +The function MUST `throw` if: + - `msg.sender` account balance does not have enough tokens to spend + - `to` is a contract which is not prepared to receive tokens. + +*NOTE*: Sending an amount of `0` is valid and MUST be treated as a regular send. +> **parameters** +> - `to`: tokens recipient +> - `amount`: number of tokens transferred +> - `userData`: information attached to the transaction by the user (sender) + +
    + +##### authorizeOperator + +``` solidity +function authorizeOperator(address operator) public +``` + +Authorize a third party `operator` to send tokens on behalf of `msg.sender`. + +A `AuthorizedOperator` event MUST be fired on a successful call to this function. + +*NOTE*: The token holder (`msg.sender`) is always an operator for himself. That is, he can call `operatorSend` on himself. This right cannot be revoked. Therefore if this function is called to set the token holder (`msg.sender`) as operator, then the function MUST throw. + +*NOTE*: A token holder CAN authorize multiple operators at the same time. + +> **parameters** +> - `operator`: Address which will be granted rights to manage the tokens. + +
    + +##### revokeOperator + +``` solidity +function revokeOperator(address operator) public +``` + +Revoke a third party `operator`'s rights to send tokens on behalf of `msg.sender`. + +A `RevokedOperator` event MUST be fired on a successful call to this function. + +*NOTE*: The token holder (`msg.sender`) is always an operator for himself. That is, he can call `operatorSend` on himself. This right cannot be revoked. Therefore if this function is called to set the token holder (`msg.sender`) as operator, then the function MUST throw. + +> **parameters** +> - `operator`: Address which whose rights to manage the tokens will be revoked. + +
    + +##### isOperatorFor + +``` solidity +function isOperatorFor(address operator, address tokenHolder) public constant returns (bool) +``` + +Check whether the `operator` address is allowed to send the tokens held by the `tokenHolder` address. + +> **parameters** +> - `operator`: address to check if it has the right to manage the tokens. +> - `tokenHolder`: address which holds the tokens to be managed. + +
    + +##### operatorSend + +``` solidity +function operatorSend(address from, address to, uint256 amount, bytes userData, bytes operatorData) public +``` + +Send `amount` of tokens on behalf of the address `from` to the address `to`. + +`msg.sender` MUST be an authorized operator or the owner for the `from` address. + +This call MUST: + - call the `tokensToSend` method on the contract implementing `ERC777TokensSender` as returned by a ERC820 lookup on the `from` address + - call the `tokensReceived` method on the contract implementing `ERC777TokensRecipient` as returned by a ERC820 lookup on the `to` address + - fire the `Sent` event + +If `to` is a contract which is not prepared to receive tokens. Specifically, it is a contract which does not register an address (its own or another) via ERC820 implementing the `ERC777TokensRecipient` interface. Then `operatorSend` MUST throw. + +The method MUST throw if: + - `from` account balance does not have enough tokens to spend. + - `to` is a contract which does not register an address (its own or another) via ERC820 which implement the `ERC777TokensRecipient` interface. + - `to` is a contract which is not prepared to receive tokens. + - `msg.sender` is not an authorized operator for `from`. + +> **parameters** +> - `from`: token holder (sender) +> - `to`: tokens recipient +> - `amount`: number of tokens transferred +> - `userData`: information attached to the transaction, previously provided by the sender (`from` address). +> - `operatorData`: information attached to the transaction by the operator + +*NOTE*: The operator is free to pass any data via the `operatorData` parameter but the `userData` parameter is reserved for data provided by the user (token holder). The token holder should provide this data to the operator beforehand. + +
    + +#### Events + +##### Sent + +``` solidity +event Sent(address indexed operator, address indexed from, address indexed to, uint256 amount, bytes userData, bytes operatorData) +``` + +Indicate a transaction of `amount` of tokens from the `from` address to the `to` address. + +This event MUST be fired on a successful call to `send` and `operatorSend`. + +> **parameters** +> - `operator`: address which triggered the transfer, either the token holder for a direct send or an authorized operator for `operatorSend` +> - `from`: token holder +> - `to`: tokens recipient +> - `amount`: number of tokens sent +> - `userData`: information attached to the transaction by the token holder +> - `operatorData`: information attached to the transaction by the operator + +
    + +##### Minted + +``` solidity +event Minted(address indexed operator, address indexed to, uint256 amount, bytes operatorData) +``` + +Indicate the minting of `amount` of tokens to the `to` address. + +This standard does not enforce a specific way to mint tokens as this can be done in various ways depending on the use case of the tokens. + +However, this event MUST be fired every time tokens are minted and credited to a `to` recipient address. A `Sent` event (even with the `0x0` as `from` address) MUST NOT be fired to indicate minting. + +> **parameters** +> - `operator`: address which triggered the minting +> - `to`: tokens recipient +> - `amount`: number of tokens minted +> - `operatorData`: information attached to the minting by the operator + +###### `tokensReceived` for minting + +Every mint MUST call `tokensReceived` on the address implementing `ERC777TokensRecipient` for the `to` address as returned by a ERC820 lookup. + +Minting MUST follow the same rules as `send`/`operatorSend` with the exception that `tokensToSend` MUST NOT be called in any case on any address. In addition, if `to` is a contract which is not prepared to receive tokens. Specifically, it is a contract which does not register an address (its own or another) via ERC820 implementing the `ERC777TokensRecipient` interface. Then the minting MUST throw. + +The `from` parameter of `tokensReceived` MUST be `0x0`. The operator MUST be `msg.sender`. The `userData` MUST be empty. `operatorData` MAY contain data related to the minting. + +
    + +##### Burned + +``` solidity +event Burned(address indexed operator, address indexed from, uint256 amount, bytes userData, bytes operatorData) +``` + +Indicate the burning of `amount` of tokens from the `from` address. + +This standard does not enforce a specific way to burn tokens as this can be done in various ways depending on the use case of the tokens. + +However, this event MUST be fired every time tokens are burned and taken from a `from` recipient address. A `Sent` event (even with the `0x0` as `to` address) MUST NOT be fired. + +> **parameters** +> - `operator`: address which triggered the minting +> - `from`: token holder +> - `amount`: number of tokens burned +> - `userData`: information attached to the burn by the token holder +> - `operatorData`: information attached to the burn by the operator + +###### `tokensToSend` for burning + +Every burn MUST call `tokensToSend` on the address implementing `ERC777TokensSender` for the `from` address as returned by a ERC820 lookup. + +Burning MUST follow the same rules as `send`/`operatorSend` with the exception that `tokensReceived` MUST NOT be called in any case on any address. But if the `from` address register an address via ERC820 implementing the `ERC777TokensSender` interface, `tokensToSend` MUST be called. + +The `to` parameter of `tokensToSend` MUST be `0x0`. The operator MUST be `msg.sender`. The `userData` MUST be empty. `operatorData` MAY contain data related to the minting. + +
    + +##### AuthorizedOperator + +``` solidity +event AuthorizedOperator(address indexed operator, address indexed tokenHolder) +``` + +Indicate that the `operator` address is allowed to send the token of (i.e. is an operator for) the address `tokenHolder`. + +This event MUST be fired on a successful call to `authorizeOperator`. + +> **parameters** +> - `operator`: Address which is granted rights to manage the tokens. +> - `tokenHolder`: address which holds the tokens to be managed. + +
    + +##### RevokedOperator + +``` solidity +event RevokedOperator(address indexed operator, address indexed tokenHolder) +``` + +Indicate that the `operator` address is denied the rights to send the token of (i.e. is not operator for) the address `tokenHolder`. + +This event MUST be fired on a successful call to `revokeOperator`. + +> **parameters** +> - `operator`: Address which is denied the rights to manage the tokens. +> - `tokenHolder`: address which holds the tokens to be managed. + +
    + +### ERC777TokensSender + +Any address (contract or regular account) CAN register a contract (itself or an other) implementing the `ERC777TokensSender` interface via the ERC820 registry. + +``` solidity +interface ERC777TokensSender { + function tokensToSend( + address operator, + address from, + address to, + uint value, + bytes userData, + bytes operatorData + ) public; +} +``` + +#### Methods + +##### tokensToSend + +``` solidity +function tokensToSend(address operator, address from, address to, uint value, bytes userData, bytes operatorData) public +``` + +Notify the transmission of `amount` of tokens from the `from` address. + +> **parameters** +> - `operator`: address which triggered the transfer, either sender for a direct send or an authorized operator for `operatorSend` +> - `from`: token holder (sender) +> - `to`: tokens recipient (or `0x` for burning) +> - `amount`: number of tokens sent or burned +> - `userData`: information attached to the transaction by the sender +> - `operatorData`: information attached to the transaction by the operator + +###### Burning Versus Sending + +When tokens are sent as a result of burning: + - `to` MUST be `0x0` + - `userData` MUST be empty + - `operator` MUST be the address which initiated the burning + - `operatorData` MAY contain data + +When tokens are sent as a result of sending (`send` or `operatorSend`): + - `to` MUST be the address to which the tokens will be sent + - `to` MUST NOT be `0x0` + + If it is a direct `send` (i.e. not an `operatorSend`) the `operator` MUST be the address from which the tokens originate. That is the `from` and `operator` addresses MUST be equals. + + +### ERC777TokensRecipient + +Any address (contract or regular account) CAN register a contract (itself or an other) implementing the `ERC777TokensRecipient` interface via the ERC820 registry. + +``` solidity +interface ERC777TokensRecipient { + function tokensReceived(address operator, address from, address to, uint amount, bytes userData, bytes operatorData) public; +} +``` + +#### Methods + +##### tokensReceived + +``` solidity +function tokensReceived(address operator, address from, address to, uint amount, bytes userData, bytes operatorData) public +``` + +Notify the transmission of `amount` of tokens to the `to` address. + +> **parameters** +> - `operator`: address which triggered the transfer, either sender for a direct send or an authorized operator for `operatorSend` +> - `from`: token holder (sender or `0x` for minting) +> - `to`: tokens recipient (or `0x` for burning) +> - `amount`: number of tokens sent, minted or burned +> - `userData`: information attached to the transaction by the sender +> - `operatorData`: information attached to the transaction by the operator + +###### Minting Versus Sending + +When tokens are received as a result of minting: + - `from` MUST be `0x0` + - `userData` MUST be empty + - `operator` MUST be the address which initiated the minting + - `operatorData` MAY contain data. + +When tokens are received as a result of sending (`send` or `operatorSend`): + - `from` MUST be the one from which the tokens originate and + - `from` MUST NOT be `0x0`. + +If it is a direct `send` (i.e. not an `operatorSend`) the `operator` MUST be the address from which the tokens originate. That is the `from` and `operator` addresses MUST be equals. + +### Logo + +| **Image** |  ![beige logo](../assets/eip-777/logo/png/ERC-777-logo-beige-48px.png) |  ![white logo](../assets/eip-777/logo/png/ERC-777-logo-white-48px.png) |  ![light grey logo](../assets/eip-777/logo/png/ERC-777-logo-light_grey-48px.png) |  ![dark grey logo](../assets/eip-777/logo/png/ERC-777-logo-dark_grey-48px.png) |  ![black logo](../assets/eip-777/logo/png/ERC-777-logo-black-48px.png?raw=true) +|----------:|:---------:|:---------:|:------------:|:-----------:|:---------:| +| **Color** | beige | white | light grey | dark grey | black | +| **Hex** | `#C99D66` | `#FFFFFF` | `#EBEFF0` | `#3C3C3D` | `#000000` | + +The logo MUST NOT be used to advertise, promote or associate in any way technology – such as tokens – which is not ERC777 compliant. + +The logo for the standard can be found in the `/assets/eip-777/logo` folder in `svg` and `png` formats. The `png` version of the logo offers a few sizes in pixel. If needed, other sizes CAN be created by converting from `svg` into `png`. + +ERC777 token contract authors CAN create a specific logo for their token based on this logo. + +## Rationale + +This standard solves some of the problems of the [EIP223](https://github.com/ethereum/EIPs/issues/223) and goes an step further by allowing operators (generally contracts) that can manage the tokens in the same way that the ERC20 with infinite `approve` was allowed. + +Also the usage of ERC820 allows backwards compatibility with wallets and proxy contracts without having to be redeployed. + +## Backwards Compatibility (ERC20Token) + +This EIP does not introduce backward incompatibilities and is compatible with the older ERC20 token standard. + +This EIP does not uses `transfer` and `transferFrom` and uses `send` and `operatorSend` to avoid mistakes in knowing which interface you are using. + +This standard allows the implementation of ERC20 functions `transfer`, `transferFrom`, `approve` and `allowance` alongside to make a token compatible with ERC20. + +The token can implement `decimals()` for backwards compatibility. If implemented, it MUST always return `18`. + +Therefore a token contract can implement both ERC20 and ERC777 in parallel. Read-only functions (such as `name`, `symbol`, `balanceOf`, `totalSupply`) and internal data (such as the mapping of balances) overlap without problem. Note however that the following functions are mandatory in ERC777 and MUST be implemented: `name`, `symbol` `balanceOf` and `totalSupply` (`decimal` is not part of the ERC777 standard). + +The write methods from both standards are decoupled and can operate independently from each other. Note that ERC20 functions SHOULD be limited to only being called from old contracts. + +If the token implements ERC20, it MUST be register the `ERC20Token` interface via ERC820. If the contract has a switch to enable or disable ERC20 methods, every time the switch is triggered, the token MUST register or unregister accordingly the `ERC20Token` interface via ERC820. + +The only difference for new contracts implementing ERC20 is that registration of `ERC777TokensSender` and `ERC777TokensRecipient` via ERC820 takes precedence over ERC20. This means that even with a ERC20 `transfer` call, the token contract MUST check via ERC820 if the `from` / `to` address implements `tokensToSend` / `tokensReceived` and call it if available. Note that when calling ERC20 `transfer` on a contract, if the contract does not implement `tokensReceived`, the `transfer` call SHOULD still be accepted even if this means the tokens will probably be locked. + +The table below summarize the different actions the token contract must take when sending, minting and transferring token via ERC777 and ERC20: + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ERC820to addressERC777 send/operatorSend and MintingERC20 transfer
    + ERC777TokensRecipient
    registered +
    regular address + MUST call tokensReceived +
    contract
    + ERC777TokensRecipient
    not registered +
    regular addressSHOULD acceptSHOULD accept
    contractMUST throw
    + +There is no particular action to take if `tokensToSend` is not implemented. The transfer MUST proceed and be canceled only if another condition is not respected such as lack of funds, a throw in `tokensReceived` (if present) or in some specific cases if `tokensReceived` is not implemented. + +## Test Cases + +The [repository with the reference implementation](https://github.com/jacquesd/ERC777) contains all the [tests](https://github.com/jacquesd/ERC777/blob/master/test/ReferenceToken-test.js). + +## Implementation + +The repository at [/jacquesd/ERC777](https://github.com/jacquesd/ERC777) contains the [reference implementation](https://github.com/jacquesd/ERC777/blob/master/contracts/ReferenceToken.sol). + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/assets/eip-777/logo/png/ERC-777-logo-beige-1024px.png b/assets/eip-777/logo/png/ERC-777-logo-beige-1024px.png new file mode 100644 index 0000000000000000000000000000000000000000..7faf0eee9656298ac446472a79224d8cd6a19884 GIT binary patch literal 4202201 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%0D-jyib5D*Z6WUxAV7cs0RjXF5FkK+009C72oM-g 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

    tyRA9s)v^H7W^(}n0(lk?2FUaD)J}i^ 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

    ZUK!5-N0t5&UAV7cs0RqhwxO#a{dlCfrbW(#q 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

    cP#n%a7S$2uC@B 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 literal 0 HcmV?d00001 diff --git a/assets/eip-777/logo/png/ERC-777-logo-beige-48px.png b/assets/eip-777/logo/png/ERC-777-logo-beige-48px.png new file mode 100644 index 0000000000000000000000000000000000000000..e2743edaeacd57cb57c536cddf2b850dceec6888 GIT binary patch literal 9365 zcmeHNUuYaf82@JOE`L46NU^493tAh*hbXmGQ_+^xHV9Q}O|2rt)JxKeLGa&;Xwe5z z&<9%zO`1zB2&ENYT2ur@A0+7|SW6$o3dIysBDU5VQycGgKEK(`-feO>vpc(YX&*9h zJAZ!Pzu)Za%(u(E|HP&Z$-2fm07$lNY~4(Cv;5Um(RC}Ievhi!mp5*E1)%;W`D4(x ze=)!^Xlq@&r6<9f?>O-*$t;wsIs?qa`{Bb+#THG~Cros7veorB+WxC9PUYiB)c$L? z|C~(PbuyltUfJE3RoRKFfKua2CmTKiz-LQgp~fbsY&FXhg_W(f$LeZw4hFcJ8ohR> z#D$j_(+uHV8n7Y|0z0EK9GC!-B{H;JXRIO^XQy>`0}~iIu=8dzbe+yvg)r?_8JGZA z)}0j!P-iw5{||rD2?Qp9>?$lDfHS%sND}ir|2m!k%o4*G<2&?HrYLrh#%iS&!Vx7l z1K4}5pHL<6%s?td`$C`EHhwmi{OjrV_9K>Bh9*`ARtn4XcW*|Ha&}cq_?w2Q>c^J% z?wxaAh7vf*%9okZVKQ z<5@gPXTW85OjQRy2fPL>fp0O!wz*?SiBh4=%t?M~yjVfX+al3kU@V_;N_(OzehbO? z5(v43Sd%w^3bg;euVe4;LF^h6n8`{jofrMW82H~hVraaCj(_?Ry(&$QldenNb>yw( z9>0u!>cZeGg?NPoWT>33a?!cJ@6?L35vfr2GMrAm%aFaPHjE#w>g<0t=q#)46lPH; zV}y+i>{vm;zphfE89R6RO5*Ku1TTHK%RuGNXk0!Y7Fc^oNq*WXSxDx!wJ+}drz99+ zu&hfclkVP1Ti_v890>Ts>dyX$$~F7ak1>Jc16>Dc&n`NYm~(R7O*WOYPuMs)w6{lk z;vL`4ySD7veY%XT+TQoL3@%79+J$h}E}nsN?R07uWs>d|G^Z^DS^q*1Y5-?gqAjAcT@jbMJyqhS*1NW!)4;O1kA5l6DYC4NmPwIjv?EKjqE{z1WXDSz&0NwO0dZ+k>-z={S^jdgH zD-#inM1VFwJpp7tMU2l^Jv0G%5YQ>0UH^#U+9fb_u&0somPXwaao{I(csa1pcOag{ zCcgl!G6_w9-akqZ_;TXbG=1u5 zk^cqogk+c^do+!jp~+A>QG$%eH=5=69!;aBS!(SuO)2d@%7f#SVcXfQn5n6fea2br jkVkx>xiACQ>I{7F%){$XuKe(njIV9|rq<8bb-eRGiq=)B literal 0 HcmV?d00001 diff --git a/assets/eip-777/logo/png/ERC-777-logo-beige-600px.png b/assets/eip-777/logo/png/ERC-777-logo-beige-600px.png new file mode 100644 index 0000000000000000000000000000000000000000..26514a7ebb3d75e7ea374c3d6f3c3a26045c7657 GIT binary patch literal 1442999 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 literal 0 HcmV?d00001 diff --git a/assets/eip-777/logo/png/ERC-777-logo-black-1024px.png b/assets/eip-777/logo/png/ERC-777-logo-black-1024px.png new file mode 100644 index 0000000000000000000000000000000000000000..7d1f221f174a98d3e8c160f7169d76a9b65038ba GIT binary patch literal 4202201 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

    &N) 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 literal 0 HcmV?d00001 diff --git a/assets/eip-777/logo/png/ERC-777-logo-black-192px.png b/assets/eip-777/logo/png/ERC-777-logo-black-192px.png new file mode 100644 index 0000000000000000000000000000000000000000..0b64da591f8aa68acb9d82f9c555dfae45e0edb3 GIT binary patch literal 147973 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 literal 0 HcmV?d00001 diff --git a/assets/eip-777/logo/png/ERC-777-logo-black-2048px.png b/assets/eip-777/logo/png/ERC-777-logo-black-2048px.png new file mode 100644 index 0000000000000000000000000000000000000000..15422504708034e02acd67a69d54ff37c3eae433 GIT binary patch literal 16806489 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