Merge branch 'master' into eip-150-add-previous-gas-costs

This commit is contained in:
Greg Colvin 2018-09-25 12:18:48 -06:00 committed by GitHub
commit 81c1265d88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
82 changed files with 8415 additions and 714 deletions

3
.gitattributes vendored Normal file
View File

@ -0,0 +1,3 @@
# GitHub highlighting for Solidity files
# See https://github.com/github/linguist/pull/3973#issuecomment-357507741
*.sol linguist-language=Solidity

View File

@ -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 --assume-extension --empty-alt-ignore --url-ignore=/EIPS/eip-1,EIPS/eip-1,/EIPS/eip-107,/EIPS/eip-858"
HTMLPROOFER_OPTIONS="./_site --internal-domains=eips.ethereum.org --check-html --check-opengraph --report-missing-names --log-level=:debug --assume-extension --empty-alt-ignore --timeframe=6w --url-ignore=/EIPS/eip-1,EIPS/eip-1,/EIPS/eip-107,/EIPS/eip-858"
if [[ $TASK = 'htmlproofer' ]]; then
bundle exec jekyll doctor
@ -22,6 +22,6 @@ elif [[ $TASK = 'eip-validator' ]]; then
exit 1
fi
FILES=$(ls EIPS/*.md)
FILES="$(ls EIPS/*.md | egrep "eip-[0-9]+.md")"
bundle exec eip_validator $FILES
fi

View File

@ -2,8 +2,12 @@ sudo: false # route your build to the container-based infrastructure for a faste
language: ruby
# Cache Ruby bundles
cache: bundler
cache:
# Cache Ruby bundles
- bundler
- directories:
- $TRAVIS_BUILD_DIR/tmp/.htmlproofer #https://github.com/gjtorikian/html-proofer/issues/381
# Assume bundler is being used, therefore
# the `install` step will run `bundle install` by default.
@ -31,3 +35,8 @@ notifications:
urls:
- https://ethlab-183014.appspot.com/merge/
on_success: always
addons:
apt:
packages:
"libcurl4-openssl-dev" # https://github.com/gjtorikian/html-proofer/issues/376#issuecomment-332767999

View File

@ -14,7 +14,7 @@ EIP stands for Ethereum Improvement Proposal. An EIP is a design document provid
## 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.
We intend EIPs to be the primary mechanisms for proposing new features, for collecting community technical 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.
@ -48,26 +48,27 @@ Your role as the champion is to write the EIP using the style and format describ
Each status change is requested by the EIP author and reviewed by the EIP editors. Use a pull request to update the status. Please include a link to where people should continue discussing your EIP. The EIP editors will process these requests as per the conditions below.
* **Active** -- 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).
* **Work in progress (WIP)** -- Once the champion has asked the Ethereum community whether an idea has any chance of support, they will write a draft EIP as a [pull request]. Consider including an implementation if this will aid people in studying the EIP.
* :arrow_right: Draft -- If agreeable, 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.
* :x: Draft -- Reasons for denying draft status include being too unfocused, too broad, duplication of effort, being technically unsound, not providing proper motivation or addressing backwards compatibility, or not in keeping with the [Ethereum philosophy](https://github.com/ethereum/wiki/wiki/White-Paper#philosophy).
* **Draft** -- 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 status. An EIP in draft status must be implemented to be considered for promotion to the next status (ignore this requirement for core EIPs).
* :arrow_right: Last Call -- If agreeable, the EIP editor will assign Last Call status and set a review end date, normally 14 days later.
* :x: Last Call -- A request for Last Call status will be denied if material changes are still expected to be made to the draft. We hope that EIPs only enter Last Call once, so as to avoid unnecessary noise on the RSS feed. Last Call will be denied if the implementation is not complete and supported by the community.
* :x: Last Call -- A request for Last Call status will be denied if material changes are still expected to be made to the draft. We hope that EIPs only enter Last Call once, so as to avoid unnecessary noise on the RSS feed.
* **Last Call** -- This EIP will listed prominently on the http://eips.ethereum.org/ website (subscribe via RSS at [last-call.xml](/last-call.xml)).
* :x: -- A Last Call which results in material changes or substantial unaddressed complaints will cause the EIP to revert to Draft.
* :arrow_right: Accepted (Core EIPs only) -- After the review end date, the Ethereum Core Developers will vote on whether to accept this change. If yes, the status will upgrade to Accepted.
* :arrow_right: Final (Not core EIPs) -- A successful Last Call without material changes or unaddressed complaints will become Final.
* **Accepted (Core EIPs only)** -- This is being implemented by Ethereum Core Developers.
* :arrow_right: Final -- Standards Track Core EIPs must be implemented in at least three viable Ethereum clients before it can be considered Final. When the implementation is complete and supported by the community, the status will be changed to “Final”.
* :x: -- A Last Call which results in material changes or substantial unaddressed technical complaints will cause the EIP to revert to Draft.
* :arrow_right: Accepted (Core EIPs only) -- A successful Last Call without material changes or unaddressed technical complaints will become Accepted.
* :arrow_right: Final (Not core EIPs) -- A successful Last Call without material changes or unaddressed technical complaints will become Final.
* **Accepted (Core EIPs only)** -- This EIP is in the hands of the Ethereum client developers. Their process for deciding whether to encode it into their clients as part of a hard fork is not part of the EIP process.
* :arrow_right: Final -- Standards Track Core EIPs must be implemented in at least three viable Ethereum clients before it can be considered Final. When the implementation is complete and adopted by the community, the status will be changed to “Final”.
* **Final** -- This EIP represents the current state-of-the-art. A Final EIP should only be updated to correct errata.
Other exceptional statuses include:
* Deferred -- This is for core EIPs that have been put off for a future hard fork.
* Rejected -- An EIP that is fundamentally broken and will not be implemented.
* Active -- This is similar to Final, but denotes an EIP which which may be updated without changing its EIP number.
* Superseded -- An EIP which was previously final but is no longer considered state-of-the-art. Another EIP will be in Final status and reference the Superseded EIP.
* **Deferred** -- This is for core EIPs that have been put off for a future hard fork.
* **Rejected** -- An EIP that is fundamentally broken or a Core EIP that was rejected by the Core Devs and will not be implemented.
* **Active** -- This is similar to Final, but denotes an EIP which which may be updated without changing its EIP number.
* **Superseded** -- An EIP which was previously final but is no longer considered state-of-the-art. Another EIP will be in Final status and reference the Superseded EIP.
## What belongs in a successful EIP?
@ -99,13 +100,15 @@ Each EIP must begin with an RFC 822 style header preamble, preceded and followed
` author:` <a list of the author's or authors' name(s) and/or username(s), or name(s) and email(s). Details are below.>
` * discussions-to:` <url>
` * discussions-to:` \<a url pointing to the official discussion thread\>
- :x: `discussions-to` can not be a Github `Pull-Request`.
` status:` <Draft | Last Call | Accepted | Final | Active | Deferred | Rejected | Superseded>
`* review-period-end: YYYY-MM-DD
`* review-period-end:` YYYY-MM-DD
` type: `<Standards Track (Core, Networking, Interface, ERC) | Informational | Meta>
` type:` <Standards Track (Core, Networking, Interface, ERC) | Informational | Meta>
` * category:` <Core | Networking | Interface | ERC>
@ -117,7 +120,7 @@ Each EIP must begin with an RFC 822 style header preamble, preceded and followed
` * superseded-by:` <EIP number(s)>
` * resolution:` <url>
` * resolution:` \<a url pointing to the resolution of this EIP\>
#### Author header

View File

@ -5,28 +5,30 @@ author: Nick Savers (@nicksavers)
type: Meta
status: Draft
created: 2018-04-20
requires: 145, 210
requires: 145, 1014, 1052, 1234, 1283
---
## Abstract
This specifies the changes included in the hard fork named Constantinople.
This meta-EIP specifies the changes included in the Ethereum hardfork named Constantinople.
## Specification
- Codename: Constantinople
- Aliases: Metropolis/Constantinople, Metropolis part 2
- Activation:
- Block >= TBD on Mainnet
- Block >= TBD on Ropsten testnet
- `Block >= TBD` on the Ethereum mainnet
- `Block >= TBD` on the Ropsten testnet
- Included EIPs:
- [EIP 145](./eip-145.md) (Bitwise shifting instructions in EVM)
- [EIP 210](./eip-210.md) (Blockhash refactoring)
- ...
- [EIP 145](./eip-145.md): Bitwise shifting instructions in EVM
- [EIP 1014](./eip-1014.md): Skinny CREATE2
- [EIP 1052](./eip-1052.md): EXTCODEHASH Opcode
- [EIP 1234](./eip-1234.md): Delay difficulty bomb, adjust block reward
- [EIP 1283](./eip-1283.md): Net gas metering for SSTORE without dirty maps
## References
1. Links to Ethereum blog announcement and others
The list above includes the EIPs discussed as candidates for Constantinople at the All Core Dev [Constantinople Session #1](https://github.com/ethereum/pm/issues/55). See also [Constantinople Progress Tracker](https://github.com/ethereum/pm/issues/53).
## Copyright

23
EIPS/eip-1014.md Normal file
View File

@ -0,0 +1,23 @@
---
eip: 1014
title: Skinny CREATE2
author: Vitalik Buterin (@vbuterin)
category: Core
type: Standards Track
status: Draft
created: 2018-04-20
---
### Specification
Adds a new opcode at 0xf5, which takes 4 stack arguments: endowment, memory_start, memory_length, salt. Behaves identically to CREATE, except using `sha3(msg.sender ++ salt ++ init_code)[12:]` instead of the usual sender-and-nonce-hash as the address where the contract is initialized at.
### Motivation
Allows interactions to (actually or counterfactually in channels) be made with addresses that do not exist yet on-chain but can be relied on to only possibly eventually contain code that has been created by a particular piece of init code. Important for state-channel use cases that involve counterfactual interactions with contracts.
#### Option 2
Use `sha3(0xff ++ msg.sender ++ salt ++ init_code)[12:]`
Rationale: ensures that addresses created with this scheme cannot collide with addresses created using the traditional `sha3(rlp([sender, nonce]))` formula, as 0xff can only be a starting byte for RLP for data many petabytes long.

View File

@ -1,7 +1,7 @@
---
eip: 1052
title: EXTCODEHASH opcode
author: Nick Johnson <arachnid@notdot.net>
author: Nick Johnson <arachnid@notdot.net>, Paweł Bylica <pawel@ethereum.org>
discussions-to: https://ethereum-magicians.org/t/extcodehash-opcode/262
status: Draft
type: Standards Track
@ -18,16 +18,57 @@ Many contracts need to perform checks on a contract's bytecode, but do not neces
Contracts can presently do this using the `EXTCODECOPY` opcode, but this is expensive, especially for large contracts, in cases where only the hash is required. As a result, we propose a new opcode, `EXTCODEHASH`, which returns the keccak256 hash of a contract's bytecode.
## Specification
A new opcode, `EXTCODEHASH`, is introduced, with number 0x3D. `EXTCODEHASH` takes one argument from the stack, and pushes the keccak256 hash of the code at that address to the stack.
A new opcode, `EXTCODEHASH`, is introduced, with number 0x3F. The `EXTCODEHASH`
takes one argument from the stack, zeros the first 96 bits
and pushes to the stack the keccak256 hash of the code of the account
at the address being the remaining 160 bits.
In case the account does not exist `0` is pushed to the stack.
In case the account does not have code the keccak256 hash of empty data
(i.e. `c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470`)
is pushed to the stack.
The gas cost of the `EXTCODEHASH` is 400.
## Rationale
As described in the motivation section, this opcode is widely useful, and saves on wasted gas in many cases.
As described in the motivation section, this opcode is widely useful, and saves
on wasted gas in many cases.
The gas cost is the same as the gas cost for the `BALANCE` opcode because the
execution of the `EXTCODEHASH` requires the same account lookup as in `BALANCE`.
Only the 20 last bytes of the argument are significant (the first 12 bytes are
ignored) similarly to the semantics of the `BALANCE`, `EXTCODESIZE` and
`EXTCODECOPY`.
The `EXTCODEHASH` distincts accounts without code and non-existing accounts.
This is consistent with the way accounts are represented in the state trie.
This also allows smart contracts to check whenever an account exists.
## Backwards Compatibility
There are no backwards compatibility concerns.
## Test Cases
TBD
1. The `EXTCODEHASH` of the account without code is `c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470`
what is the keccack256 hash of empty data.
2. The `EXTCODEHASH` of non-existent account is `0`.
3. The `EXTCODEHASH` of an precompiled contract is either `c5d246...` or `0`.
4. If `EXTCODEHASH` of `A` is `X`, then `EXTCODEHASH` of `A + 2**160` is `X`.
5. The `EXTCODEHASH` of an account that selfdestructed in the current transaction.
6. The `EXTCODEHASH` of an account that selfdestructed and later the selfdestruct has been reverted.
7. The `EXTCODEHASH` of an account created in the current transaction.
8. The `EXTCODEHASH` of an account that has been newly create and later the creation has been reverted.
9. The `EXTCODEHASH` of an account that firstly does not exist and later is empty.
10. The `EXTCODEHASH` of an empty account that is going to be cleared by the state clearing rule.
## Implementation
TBD

View File

@ -93,19 +93,19 @@ function safeIncrement(uint8 interval) public returns (byte status, uint8 newCou
}
```
In the rare case that there a multiple codes required to express an idea,
they should be organized in asending order.
In the rare case that there are multiple codes required to express an idea,
they should be organized in ascending order.
### Code Table
Codes break nicely into a 16x16 matrix, represented as a 2-digit hex number.
The high nibble represents the code's kind or "category", and the low nibble contains
the state or "reason". We present them below as separate tables per range for
explanitory and layout reasons.
explanatory and layout reasons.
Unspecified codes are _not_ free for arbitrary use, but rather open for further specification.
#### Generic
#### `0x0*` Generic
General codes. These double as bare "reasons", since `0x01 == 1`.
@ -128,7 +128,7 @@ General codes. These double as bare "reasons", since `0x01 == 1`.
| `0x0E` | |
| `0x0F` | Meta or Info Only |
#### Permission
#### `0x1*` Permission
Related to permisson, authorization, approval, and so on.
@ -151,7 +151,7 @@ Related to permisson, authorization, approval, and so on.
| `0x1E` | |
| `0x1F` | Permission Meta or Info |
#### Find, Match, &c
#### `0x2*` Find, Match, &c
This range is broadly intended for finding and matching.
Data lookups and order matching are two common use cases.
@ -175,10 +175,10 @@ Data lookups and order matching are two common use cases.
| `0x2E` | |
| `0x2F` | Matching Meta or Info |
#### Negotiation, Terms, and Offers
#### `0x3*` Negotiation, Terms, and Offers
Negotiation, and very broadly the flow of such transactions.
Note that "other party" may be more than one actor (not nessesarily the sender).
Note that "other party" may be more than one actor (not necessarily the sender).
| Code | Description |
|-----------------|:----------------------------|
@ -199,7 +199,7 @@ Note that "other party" may be more than one actor (not nessesarily the sender).
| `0x3E` | |
| `0x3F` | Negotiation Meta or Info |
#### Availability
#### `0x4*` Availability
Service or action availability.
@ -222,27 +222,27 @@ Service or action availability.
| `0x4E` | |
| `0x4F` | Availability Meta or Info |
#### `0x5_` TBD
#### `0x5*` TBD
Currently unspecified
#### `0x6_` TBD
#### `0x6*` TBD
Currently unspecified
#### `0x7_` TBD
#### `0x7*` TBD
Currently unspecified
#### `0x8_` TBD
#### `0x8*` TBD
Currently unspecified
#### `0x9_` TBD
#### `0x9*` TBD
Currently unspecified
#### Application-Specific Codes
#### `0xA*` Application-Specific Codes
Contracts may have special states that they need to signal.
This proposal only outlines the broadest meanings, but implementers may have very
@ -267,19 +267,19 @@ specific meanings for each, as long as they are coherent with the broader defini
| `0xAE` | |
| `0xAF` | App-Specific Meta or Info |
#### `0xB_` TBD
#### `0xB*` TBD
Currently unspecified
#### `0xC_` TBD
#### `0xC*` TBD
Currently unspecified
#### `0xD_` TBD
#### `0xD*` TBD
Currently unspecified
#### Cryptography and Authentication
#### `0xE*` Cryptography and Authentication
Actions around signatures, cryptography, signing, and application-level authentication.
@ -307,7 +307,7 @@ or process used.
#### `0xF0` Off-Chain
For off-chain actions. Much like th `0x0_: Generic` range, `0xF_` is very general,
For off-chain actions. Much like th `0x0_: Generic` range, `0xF*` is very general,
and does little to modify the reason.
Among other things, the meta code `0xFF` may be used to describe what the off-chain process is.
@ -489,7 +489,7 @@ most forwards-compatible method of transmission is as the first value of a multi
Familiarity is also a motivating factor. A consistent position and encoding together
follow the principle of least surprise. It is both viewable as a "header" in the HTTP analogy,
or like the "tag" in BEAM tagged tupples.
or like the "tag" in BEAM tagged tuples.
### Human Readable
@ -500,7 +500,13 @@ Cognitive load is lowered by organizing the table into categories and reasons.
While this repository includes helper enums, we have found working directly in
the hex values to be quite natural. ESC `0x10` is just as comfortable as HTTP 401, for example.
### Extensiblilty
#### Localizations
One commonly requested application of this spec is human-readable translations
of codes. This has been moved to its own proposal: [ERC-1444](https://github.com/ethereum/EIPs/pull/1444/),
primarily due to a desire to keep both specs focused.
### Extensibility
The `0xA` category is reserved for application-specific statuses.
In the case that 256 codes become insufficient, `bytes1` may be embedded in larger byte arrays.
@ -526,7 +532,7 @@ but becomes very natural after a couple hours of use.
#### Short Forms
Generic is `0x0_`, general codes are consistent with their integer representations
Generic is `0x0*`, general codes are consistent with their integer representations
```solidity
hex"1" == hex"01" == 1 // with casting
@ -578,7 +584,9 @@ function appCode(Sleep _state) returns (byte code) {
## Implementation
Reference cases and helper library can be found [here](https://github.com/Finhaven/EthereumStatusCodes)
Reference cases and helper libraries (Solidity and JS) can be found at:
* [Source Code](https://github.com/expede/ethereum-status-codes/)
* [Package on npm](https://www.npmjs.com/package/ethereum-status-codes)
## Copyright

125
EIPS/eip-1081.md Normal file
View File

@ -0,0 +1,125 @@
---
eip: 1081
Title: Standard Bounties
Authors: Mark Beylin <mark.beylin@consensys.net>, Kevin Owocki <kevin.owocki@consensys.net>, Ricardo Guilherme Schmidt (@3esmit)
Discussions-to: https://gitter.im/bounties-network/Lobby
Status: Draft
Type: Standards Track
Category: ERC
Created: 2018-05-14
Requires: 20
---
## 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.-->
A standard contract and interface for issuing bounties on Ethereum, usable for any type of task, paying in any ERC20 token or in ETH.
## Abstract
<!--A short (~200 word) description of the technical issue being addressed.-->
In order to encourage cross-platform interoperability of bounties on Ethereum, and for easier reputational tracking, StandardBounties can facilitate the administration of funds in exchange for deliverables corresponding to a completed task, in a publicly auditable and immutable fashion.
## Motivation
In the absence of a standard for bounties on Ethereum, it would be difficult for platforms to collaborate and share the bounties which users create (thereby recreating the walled gardens which currently exist on Web2.0 task outsourcing platforms). A standardization of these interactions across task types also makes it far easier to track various reputational metrics (such as how frequently you pay for completed submissions, or how frequently your work gets accepted).
## Specification
After studying bounties as they've existed for thousands of years (and after implementing and processing over 300 of them on main-net in beta), we've discovered that there are 3 core steps to every bounty:
- a bounty is **issued**: an `issuer` specifies the requirements for the task, describing the desired outcome, and how much they would be willing to pay for the completion of that task (denoted in one or several tokens).
- a bounty is **fulfilled**: a bounty `fulfiller` may see the bounty, complete the task, and produce a deliverable which is itself the desired outcome of the task, or simply a record that it was completed. Hashes of these deliverables should be stored immutably on-chain, to serve as proof after the fact.
- a fulfillment is **accepted**: a bounty `issuer` or `arbiter` may select one or more submissions to be accepted, thereby releasing payment to the bounty fulfiller(s), and transferring ownership over the given deliverable to the `issuer`.
To implement these steps, a number of functions are needed:
- `initializeBounty(address _issuer, address _arbiter, string _data, uint _deadline)`: This is used when deploying a new StandardBounty contract, and is particularly useful when applying the proxy design pattern, whereby bounties cannot be initialized in their constructors. Here, the data string should represent an IPFS hash, corresponding to a JSON object which conforms to the schema (described below).
- `fulfillBounty(address[] _fulfillers, uint[] _numerators, uint _denomenator, string _data)`: This is called to submit a fulfillment, submitting a string representing an IPFS hash which contains the deliverable for the bounty. Initially fulfillments could only be submitted by one individual at a time, however users consistently told us they desired to be able to collaborate on fulfillments, thereby allowing the credit for submissions to be shared by several parties. The lines along which eventual payouts are split are determined by the fractions of the submission credited to each fulfiller (using the array of numerators and single denominator). Here, a bounty platform may also include themselves as a collaborator to collect a small fee for matching the bounty with fulfillers.
- `acceptFulfillment(uint _fulfillmentId, StandardToken[] _payoutTokens, uint[] _tokenAmounts)`: This is called by the `issuer` or the `arbiter` to pay out a given fulfillment, using an array of tokens, and an array of amounts of each token to be split among the contributors. This allows for the bounty payout amount to move as it needs to based on incoming contributions (which may be transferred directly to the contract address). It also allows for the easy splitting of a given bounty's balance among several fulfillments, if the need should arise.
- `drainBounty(StandardToken[] _payoutTokens)`: This may be called by the `issuer` to drain a bounty of it's funds, if the need should arise.
- `changeBounty(address _issuer, address _arbiter, string _data, uint _deadline)`: This may be called by the `issuer` to change the `issuer`, `arbiter`, `data`, and `deadline` fields of their bounty.
- `changeIssuer(address _issuer)`: This may be called by the `issuer` to change to a new `issuer` if need be
- `changeArbiter(address _arbiter)`: This may be called by the `issuer` to change to a new `arbiter` if need be
- `changeData(string _data)`: This may be called by the `issuer` to change just the `data`
- `changeDeadline(uint _deadline)`: This may be called by the `issuer` to change just the `deadline`
Optional Functions:
- `acceptAndFulfill(address[] _fulfillers, uint[] _numerators, uint _denomenator, string _data, StandardToken[] _payoutTokens, uint[] _tokenAmounts)`: During the course of the development of this standard, we discovered the desire for fulfillers to avoid paying gas fees on their own, entrusting the bounty's `issuer` to make the submission for them, and at the same time accept it. This is useful since it still immutably stores the exchange of tokens for completed work, but avoids the need for new bounty fulfillers to have any ETH to pay for gas costs in advance of their earnings.
- `changeMasterCopy(StandardBounty _masterCopy)`: For `issuer`s to be able to change the masterCopy which their proxy contract relies on, if the proxy design pattern is being employed.
- `refundableContribute(uint[] _amounts, StandardToken[] _tokens)`: While non-refundable contributions may be sent to a bounty simply by transferring those tokens to the address where it resides, one may also desire to contribute to a bounty with the option to refund their contribution, should the bounty never receive a correct submission which is paid out.
`refundContribution(uint _contributionId)`: If a bounty hasn't yet paid out to any correct submissions and is past it's deadline, those individuals who employed the `refundableContribute` function may retreive their funds from the contract.
**Schemas**
Persona Schema:
```
{
name: // optional - A string representing the name of the persona
email: // optional - A string representing the preferred contact email of the persona
githubUsername: // optional - A string representing the github username of the persona
address: // required - A string web3 address of the persona
}
```
Bounty issuance `data` Schema:
```
{
payload: {
title: // A string representing the title of the bounty
description: // A string representing the description of the bounty, including all requirements
issuer: {
// persona for the issuer of the bounty
},
funders:[
// array of personas of those who funded the issue.
],
categories: // an array of strings, representing the categories of tasks which are being requested
created: // the timestamp in seconds when the bounty was created
tokenSymbol: // the symbol for the token which the bounty pays out
tokenAddress: // the address for the token which the bounty pays out (0x0 if ETH)
// ------- add optional fields here -------
sourceFileName: // A string representing the name of the file
sourceFileHash: // The IPFS hash of the file associated with the bounty
sourceDirectoryHash: // The IPFS hash of the directory which can be used to access the file
webReferenceURL: // The link to a relevant web reference (ie github issue)
},
meta: {
platform: // a string representing the original posting platform (ie 'gitcoin')
schemaVersion: // a string representing the version number (ie '0.1')
schemaName: // a string representing the name of the schema (ie 'standardSchema' or 'gitcoinSchema')
}
}
```
Bounty `fulfillment` data Schema:
```
{
payload: {
description: // A string representing the description of the fulfillment, and any necessary links to works
sourceFileName: // A string representing the name of the file being submitted
sourceFileHash: // A string representing the IPFS hash of the file being submitted
sourceDirectoryHash: // A string representing the IPFS hash of the directory which holds the file being submitted
fulfillers: {
// personas for the individuals whose work is being submitted
}
// ------- add optional fields here -------
},
meta: {
platform: // a string representing the original posting platform (ie 'gitcoin')
schemaVersion: // a string representing the version number (ie '0.1')
schemaName: // a string representing the name of the schema (ie 'standardSchema' or 'gitcoinSchema')
}
}
```
## 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 development of this standard began a year ago, with the goal of encouraging interoperability among bounty implementations on Ethereum. The initial version had significantly more restrictions: a bounty's `data` could not be changed after issuance (it seemed unfair for bounty `issuer`s to change the requirements after work is underway), and the bounty payout could not be changed (all funds needed to be deposited in the bounty contract before it could accept submissions).
The initial version was also far less extensible, and only allowed for fixed payments to a given set of fulfillments. This new version makes it possible for funds to be split among several correct submissions, for submissions to be shared among several contributors, and for payouts to not only be in a single token as before, but in as many tokens as the `issuer` of the bounty desires. These design decisions were made after the 8+ months which Gitcoin, the Bounties Network, and Status Open Bounty have been live and meaningfully facilitating bounties for repositories in the Web3.0 ecosystem.
## 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.-->
Tests for our implementation can be found here: https://github.com/Bounties-Network/StandardBounties/tree/develop/test
## 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.-->
A reference implementation can be found here: https://github.com/Bounties-Network/StandardBounties/blob/develop/contracts/StandardBounty.sol
**Although this code has been tested, it has not yet been audited or bug-bountied, so we cannot make any assertions about it's correctness, nor can we presently encourage it's use to hold funds on the Ethereum mainnet.**
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

View File

@ -15,9 +15,9 @@ This EIP proposes a change to how gas is charged for EVM SSTORE operations, in o
## Motivation
Presently, SSTORE operations are charged as follows:
- 20000 gas to set a slot from 0 to non-0
- 20,000 gas to set a slot from 0 to non-0
- 5,000 gas for any other change
- A 10000 gas refund when a slot is set from non-0 to 0. Refunds are applied at the end of the transaction.
- A 10,000 gas refund when a slot is set from non-0 to 0. Refunds are applied at the end of the transaction.
In situations where a single update is made to a storage value in a transaction, these gas costs have been determined to fairly reflect the resources consumed by the operation. However, this results in excessive gas costs for sequences of operations that make multiple updates.
@ -32,13 +32,14 @@ Addressing this issue would also enable new use-cases that are currently cost-pr
## Specification
The following changes are made to the EVM:
- An EVM-global 'dirty map' is maintained, tracking all storage slots in all contracts that have been modified in the current transaction.
- When a storage slot is written to for the first time, the slot is marked as dirty. If the slot was previously set to 0, 20000 gas is deducted; otherwise, 5000 gas is deducted. If the slot was previously set to 0, and is being set to 0, only 200 gas is deducted.
- A 'dirty map' for each transaction is maintained, tracking all storage slots in all contracts that have been modified in the current transaction. The dirty map is scoped in the same manner as updates to storage, meaning that changes to the dirty map in a call that later reverts are not retained.
- When a storage slot is written to with the value it already contains, 200 gas is deducted.
- When a storage slot's value is changed for the first time, the slot is marked as dirty. If the slot was previously set to 0, 20000 gas is deducted; otherwise, 5000 gas is deducted.
- When a storage slot that is already in the dirty map is written to, 200 gas is deducted.
- At the end of the transaction, for each slot in the dirty map:
- If the slot was 0 before the transaction and is 0 now, refund 19800 gas.
- If the slot was nonzero before the transaction and its value has not changed, refund 4800 gas.
- If the slot was nonzero before the transaction and is 0 now, refund 10000 gas.
- If the slot was nonzero before the transaction and is 0 now, refund 15000 gas.
After these changes, transactions that make only a single change to a storage slot will retain their existing costs. However, contracts that make multiple changes will see significantly reduced costs. Repeating the examples from the Motivation section:
@ -59,7 +60,19 @@ This EIP requires a hard fork to implement.
No contract should see an increase in gas cost for this change, and many will see decreased gas consumption, so no contract-layer backwards compatibility issues are anticipated.
## Test Cases
TBD
- Writing x to a storage slot that contains 0, where x != 0 (20k gas, no refund)
- Writing y to a storage slot that contained x, where x != y and x != 0 (5k gas, no refund)
- Writing 0 to a storage slot that contains x, where x != 0 (5k gas, 10k refund)
- Writing 0 to a storage slot that already contains zero (200 gas, no refund)
- Writing x to a storage slot that already contains x, where x != 0 (200 gas, no refund)
- Writing x, then y to a storage slot that contains 0, where x != y (20200 gas, no refund)
- Writing x, then y to a storage slot that contains 0, where x != y != z and x != 0 (5200 gas, no refund)
- Writing x, then 0 to a storage slot that contains 0, where x != 0 (20200 gas, 19800 refund)
- Writing x, then y to a storage slot that contains y, where x != y != 0 (5200 gas, 4800 refund)
- Writing x, then 0 to a storage slot that contains 0, then reverting the stack frame in which the writes occurred (20200 gas, no refund)
- Writing x, then y to a storage slot that contains y, then reverting the stack frame in which the writes occurred (5200 gas, no refund)
- In a nested frame, writing x to a storage slot that contains 0, then returning, and writing 0 to that slot (20200 gas, 19800 refund)
## Implementation
TBD

View File

@ -1,8 +1,8 @@
---
eip: 1102
title: Opt-in web3 access
title: Opt-in provider access
author: Paul Bouchon <mail@bitpshr.net>
discussions-to: https://ethereum-magicians.org/t/opt-in-web3-access/414
discussions-to: https://ethereum-magicians.org/t/eip-1102-opt-in-provider-access/414
status: Draft
type: Standards Track
category: Interface
@ -11,17 +11,39 @@ created: 2018-05-04
## Simple summary
This proposal describes a new way for DOM environments to expose the web3 API that requires user approval.
This proposal describes a way for DOM environments to expose an Ethereum provider that requires user approval.
## Abstract
MetaMask and most other tools that provide access to web3-enabled environments do so automatically and without user consent. This exposes users of such environments to fingerprinting attacks since untrusted websites can check for a `web3` object and reliably identify web3-enabled clients.
The previous generation of Ethereum-enabled DOM environments follows a pattern of injecting a fully-enabled provider into the DOM without user consent. This puts users of such environments at risk because malicious websites can use this provider to view account information and to arbitrarily initiate unwanted Ethereum transactions on a user's behalf.
This proposal outlines a new protocol in which dapps request access to the web3 API instead of relying on its preexistence in a given DOM environment.
This proposal outlines a protocol in which DOM environments expose a read-only provider until full provider access is approved by the user.
## Specification
### Typical dapp initialization
### Definitions
1. **Read-only provider**
A read-only provider has no populated accounts and any RPC request that requires an account will fail.
2. **Full provider**
A full provider has populated accounts and any RPC request that requires an account will succeed.
3. **`Provider#enable`**
Providers exposed by DOM environments define a new `enable` method that returns a Promise. Calling this method triggers a user interface that allows the user to approve or deny full provider access for a given dapp. The returned Promise is resolved if the user approves full provider access or rejected if the user denies full provider access.
```js
ethereum.enable(): Promise<any>
```
### Protocol
DOM environments expose a read-only provider globally at `window.ethereum` by default. Before initiating any RPC request that requires an account, like `eth_sendTransaction`, dapps must request a full provider by calling a new provider method, `ethereum.enable()`. This method triggers a user interface that allows the user to approve or deny full provider access for a given dapp. If the user approves full provider access, the provider at `window.ethereum` is populated with accounts and fully-enabled; if the user denies full provider access, the provider at `window.ethereum` is left unchanged.
#### Typical dapp initialization
```
START dapp
@ -31,73 +53,71 @@ IF web3 is undefined
STOP dapp
```
### Proposed dapp initialization
#### Proposed dapp initialization
```
START dapp
IF web3 is defined
CONTINUE dapp
IF web3 is undefined
REQUEST[1] web3 API
IF provider is defined
ENABLE[1] full provider
IF user approves
INJECT[2] web3 API
NOTIFY[3] dapp
RESOLVE[2] full provider
CONTINUE dapp
IF user rejects
IF non-web3 environment
NOOP[4]
IF user denies
REJECT[3] with error
STOP dapp
IF provider is undefined
STOP dapp
```
#### `[1] REQUEST`
##### `[1] ENABLE`
Dapps MUST request the web3 API by sending a message using [`window.postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) API. This message MUST be sent with a payload object containing a `type` property with a value of “WEB3_API_REQUEST” and an optional `id` property corresponding to an identifier of a specific wallet provider, such as "METAMASK".
Dapps MUST request a full provider by calling the `enable` method on the default read-only provider. This method MUST trigger a user interface that allows the user to approve or deny full provider access for a given dapp. This method MUST return a Promise that is resolved with an array of the user's public addresses if the user approves full provider access or rejected if the user denies full provider access.
#### `[2] INJECT`
##### `[2] RESOLVE`
Dapp browsers should inject the web3 API using an implementation-specific strategy that can expose the web3 API to the users browser context, such as HTML script tag injection.
If a user approves full provider access, DOM environments MUST expose a fully-enabled provider at `window.ethereum` that is populated with accounts. The Promise returned when calling the `enable` method MUST be resolved with an array of the user's public addresses.
#### `[3] NOTIFY`
##### `[3] REJECT`
Dapps browsers MUST notify dapps of successful web3 exposure by sending a message using [`window.postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) API. This message MUST be sent with a payload object containing a `type` property with a value of “WEB3_API_SUCCESS" and an optional `id` property corresponding to an identifier of a specific wallet provider, such as "METAMASK".
If a user denies full provider access, the Promise returned when calling the `enable` method MUST be rejected with an informative Error.
#### `[4] NOOP`
If a user rejects web3 access on an untrusted site, the site itself MUST NOT be notified in any way; notification of a rejection would allow third-party tools to still identify that a client is web3-enabled despite not being granted web3 access.
### Example implementation: `postMessage`
The following example demonstrates one possible implementation of this strategy in a browser-based DOM environment. Note that web3 environments on other platforms would most likely use platform-specific native messaging protocols, not `postMessage`.
### Example initialization
```js
if (typeof web3 !== 'undefined') {
// web3 API defined, start dapp
} else {
window.addEventListener('message', function (event) {
if (!event.data || !event.data.type) { return; }
if (event.data.type === 'WEB3_API_SUCCESS') {
// web3 API defined, start dapp
}
});
// request web3 API
window.postMessage({ type: 'WEB3_API_REQUEST' });
}
window.addEventListener('load', async () => {
// Read-only provider is exposed by default
console.log(await ethereum.send('net_version'));
try {
// Request full provider if needed
await ethereum.enable();
// Full provider exposed
await ethereum.send('eth_sendTransaction', [/* ... */]);
} catch (error) {
// User denied full provider access
}
});
```
## Rationale
An [open issue](https://github.com/MetaMask/metamask-extension/issues/714) against the [MetaMask](https://github.com/MetaMask/metamask-extension) extension has received community upvotes and Richard Burton of the [Balance](https://github.com/balance-io) team published a well-received [blog post](https://medium.com/@ricburton/metamask-walletconnect-js-b47857efb4f7) discussing these potential changes.
### Constraints
* Web3 MUST NOT be exposed to websites by default.
* Dapps MUST request web3 if it does not exist.
* Users MUST be able to approve or reject web3 access.
* Web3 MUST be exposed to websites after user consent.
* Environments MAY continue auto-exposing web3 if users can disable this behavior.
* Browsers MUST expose a read-only provider at `window.ethereum` by default.
* Browsers MUST NOT expose a full provider globally by default.
* Dapps MUST request access to a full provider.
* Users MUST be able to approve or deny full provider access.
* A full provider MUST be exposed at `window.ethereum` after user approval.
* Dapps MUST be notified of user approval of full provider access.
* Dapps MUST be notified of user denial of full provider access.
## Rationale
The pattern of full provider auto-injection followed by the previous generation of Ethereum-enabled DOM environments fails to protect user privacy and fails to maintain safe user experience: untrusted websites can both view account information and arbitrarily initiate transactions on a user's behalf. Even though most users may reject unsolicited transactions on untrusted websites, a protocol for provider exposure should make such unsolicited requests impossible.
This proposal establishes a new pattern wherein dapps must request access to a full Ethereum provider. This protocol directly strengthens user privacy by hiding user accounts and preventing unsolicited transaction requests on untrusted sites.
### Immediate value-add
* Users can reject web3 access on untrusted sites to prevent web3 fingerprinting.
* Users can reject full provider access on untrusted sites to hide accounts.
* Users can reject full provider access on untrusted sites to prevent unsolicited transactions.
### Long-term value-add
@ -108,11 +128,11 @@ An [open issue](https://github.com/MetaMask/metamask-extension/issues/714) again
## Backwards compatibility
This proposal impacts dapp authors and requires that they request access to the web3 API before using it. This proposal also impacts developers of web3-enabled environments or dapp browsers as these tools should no longer auto-expose the web3 API; instead, they should only do so if a website requests the API and if the user consents to its access. Environments may continue to auto-expose the web3 API as long as users have the ability to disable this behavior.
This proposal impacts dapp authors and requires that they request access to a full Ethereum provider before using it to initiate any RPC call that requires an account. This proposal also impacts developers of Ethereum-enabled DOM environments or dapp browsers as these tools should no longer auto-expose a full provider populated with accounts; instead, they should expose a read-only provider and only expose a full provider if a website requests one and a user consents to its access.
## Implementation
The MetaMask team is currently working an [MVP implementation](https://github.com/MetaMask/metamask-extension/issues/3930) of the strategy described above and expects to begin limited user testing soon.
The MetaMask team is currently working an [MVP implementation](https://github.com/MetaMask/metamask-extension/pull/4703) of the strategy described above and expects to begin limited user testing soon.
## Copyright

View File

@ -1,6 +1,6 @@
---
eip: 1109
title: Remove CALL costs for precompiled contracts
title: PRECOMPILEDCALL opcode (Remove CALL costs for precompiled contracts)
author: Jordi Baylina (@jbaylina)
discussions-to: https://ethereum-magicians.org/t/eip-1109-remove-call-costs-for-precompiled-contracts/447
status: Draft
@ -11,41 +11,73 @@ created: 2018-05-22
## Simple Summary
This EIP removes the gas costs of the CALL-like opcodes when calling precompiled contracts.
This EIP creates a specific OPCODE named "PRECOMPILEDCALL" to call Precompiled contracts without the costs of a normal CALL.
## Abstract
This EIP tries to resolve the problem of high gas consumption when calling precompiled contracts with a small gas cost. Setting the gas costs to 0 when calling a precompiled contract allows to define precompiled contracts whose effective cost when calling it is less than 700.
This EIP tries to resolve the problem of high gas consumption when calling precompiled contracts with a small gas cost. Using this opcode for calling precompiled contracts allows to define precompiled contracts whose effective cost it is less than 700.
## Motivation
Each precompiled contract has an already defined a cost for calling it. It does not make sense to add the implicit extra gas cost of the CALL opcode.
Each precompiled contract has an already defined cost for calling it. It does not make sense to add the implicit extra gas cost of the CALL opcode.
As an example, SHA256 precompiled contract costs 60 and ECADD costs 500 (proposed to costs only 50 in [EIP1108](https://github.com/ethereum/EIPs/pull/1108) . When a precompiled contract is called, 700 gas is consumed just for the CALL opcode besides the costs of the precompiled contract.
This makes no sense, and right now it's impossible to define a precompiled contract whose effective cost for using it is less than 700.
This makes no sense, and right now it's impossible to define a precompiled contract whose effective cost for using it, is less than 700.
## Specification
If `block.number >= XXXXX`, for each CALL, DELEGATECALL and CALLCODE opcode with a destination address < 256 use a Gcall (basic cost of the call) of 0 instead of 700.
If `block.number >= XXXXX`, define a new opcode named PRECOMPILEDCALL with code value 0xfb .
The gas cost of the OPCODE is 2 (Gbase) plus the Specific gas cost defined for each specific precompiled smart contract.
The OPCODE takes 5 words from the stack and returns 1 word to the stack.
The input stack values are:
mu_s[0] = The address of the precompiled smart contract that is called.
mu_s[1] = Pointer to memory for the input parameters.
mu_s[2] = Length of the input parametes in bytes.
mu_s[3] = Pointer to memory where the output is stored
mu_s[4] = Length of the output buffer.
The return will be 1 in case of success call and 0 in any of the next cases:
1.- mu_s[0] is an address of an undefined precompiled smart contract.
2.- The precompiled smart contract fails (as defined on each smart contract). Invalid input parameters for example.
Precompiled smart contracs, does not execute opcodes, so there is no need to pass a gas parameter as a normal CALL. If the available gas is less that 2 plus the required gas required for the specific precompiled smart cotract, the context just STOPS executing with an "Out of Gas" error.
There is no stack check for this call.
The normal CALLs to the precompiled smart contracts continue to work with the exact same behavior.
A PRECOMPILEDCALL to a regular address or regular smart contract, is considered a call to an "undefined smart contract", so the VM MUST not execute it and the opcode must return 0x0 .
The cost of the CALL opcode is calculated in exactly the same way that any normal call, including the cost for using a value different than 0 and for creating a new account. The only difference is that Gcall is not added when calculating Cextra.
## Rationale
This implementation is the one that needs less modification of the clients.
There was a first proposal for removing the gast consts for the CALL, but it looks that it's easier to implement and test a new opcode just for that.
The code is just the next opcode available after the STATICCALL opcode.
## Backwards Compatibility
This EIP is backwards compatible. Smart contracts that call precompiled contracts will cost less from now on. Smart contracts that relay in a high gas consumption for a specific code are not expected.
This EIP is backwards compatible. Smart contracts that call precompiled contracts using this new opcode will cost less from now on.
Old contracts that call precompiled smart contracts with the CALL method, will continue working.
## Test Cases
- Normal call to a defined precompiled contract.
- Call to undefined precompiled contract.
- Call to defined precompiled contract with a value!=0 on the call.
- Call to undefined precompiled contract with a value!=0 on the call.
- Normal call to precompiled contract with remaining gas<700 but gas>[the cost of the call].
- Call to a regular contract
- Call to a regular account
- Call to 0x0 smart contract (Does not exists).
- Call with large values for the offste pointers and lenghts
- Call with the exact gas remaining needed to call smart contract.
- Call with the exact gas remaining minus one needed to call smart contract.
## Implementation

View File

@ -49,8 +49,7 @@ This version:
- Generalizes storage URIs to represent any content addressable URI
scheme, not only IPFS.
- Renames *release lockfile* to *package manifest*, or *package* for
short.
- Renames *release lockfile* to *package manifest*.
- Adds support for languages other than Solidity by generalizing the
compiler information format.
@ -117,10 +116,10 @@ document are to be interpreted as described in RFC 2119.
### Prefixed vs Unprefixed
A [prefixed](#term-prefixed) hexadecimal value begins with `'0x'`.
A [prefixed](#term-prefixed) hexadecimal value begins with `0x`.
[Unprefixed](#term-unprefixed) values have no prefix. Unless otherwise
specified, all hexadecimal values **should** be represented with the
`'0x'` prefix.
`0x` prefix.
<table>
<colgroup>
@ -225,7 +224,7 @@ document conforms to. Packages **must** include this field.
The `package_name` field defines a human readable name for this package.
Packages **must** include this field. Package names **must** begin with
a lowercase letter and be comprised of only lowercase letters, numeric
characters, and the dash character `'-'`. Package names **must** not
characters, and the dash character `-`. Package names **must** not
exceed 214 characters in length.
<table>
@ -639,8 +638,8 @@ encoded when [linking](#term-linking) the corresponding bytecode.
</tr>
<tr class="odd">
<td><p>Allowed Values</p></td>
<td><p><code>'literal'</code> for bytecode literals</p>
<p><code>'reference'</code> for named references to a particular <a href="#term-contract-instance">Contract Instance</a></p></td>
<td><p><code>&quot;literal&quot;</code> for bytecode literals</p>
<p><code>&quot;reference&quot;</code> for named references to a particular <a href="#term-contract-instance">Contract Instance</a></p></td>
</tr>
</tbody>
</table>
@ -1434,7 +1433,7 @@ nightly should be denoted in the form of `<semver>-<commit-hash>` ex:
#### Settings: `settings`
The `settings` field defines any settings or configuration that was used
in compilation. For the `'solc'` compiler, this **should** conform to
in compilation. For the `"solc"` compiler, this **should** conform to
the [Compiler Input and Output
Description](http://solidity.readthedocs.io/en/latest/using-the-compiler.html#compiler-input-and-output-json-description).
@ -1558,7 +1557,7 @@ Bytecode
The set of EVM instructions as produced by a compiler. Unless otherwise
specified this should be assumed to be hexadecimal encoded, representing
a whole number of bytes, and [prefixed](#term-prefixed) with `'0x'`.
a whole number of bytes, and [prefixed](#term-prefixed) with `0x`.
Bytecode can either be linked or unlinked. (see
[Linking](#term-linking))
@ -1793,7 +1792,7 @@ for package manifests.)
Prefixed
--------
[Bytecode](#term-bytecode) string with leading `'0x'`.
[Bytecode](#term-bytecode) string with leading `0x`.
<table>
<colgroup>

153
EIPS/eip-1129.md Normal file
View File

@ -0,0 +1,153 @@
---
eip: 1129
title: Standardised DAPP announcements
author: Jan Turk (@ThunderDeliverer)
discussions-to: https://ethereum-magicians.org/t/eip-sda-standardised-dapp-announcements/508?u=thunderdeliverer
status: Draft
type: Standards Track
category: ERC
created: 2018-05-31
---
<!--You can leave these HTML comments in your merged EIP and delete the visible duplicate text guides, they will not appear and may be helpful to refer to if you edit it again. 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.-->
Standardisation of announcements in DAPPs and services on Ethereum network. This ERC provides proposed mechanics to increase the quality of service provided by DAPP developers and service providers, by setting a framework for announcements. Be it transitioning to a new smart contract or just freezing the service for some reason.
## Abstract
<!--A short (~200 word) description of the technical issue being addressed.-->
The proposed ERC defines format on how to post announcements about the service as well as how to remove them. It also defines mechanics on posting permissions and human friendly interface.
## 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.-->
Currently there are no guidelines on how to notify the users of the service status in the DAPPs. This is especially obvious in ERC20 and it's derivates. If the service is impeded by any reason it is good practice to have some sort of guidelines on how to announce that to the user. The standardisation would also provide traceability of the service's status.
## 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 (go-ethereum, parity, cpp-ethereum, ethereumj, ethereumjs, and [others](https://github.com/ethereum/wiki/wiki/Clients)).-->
### Structures
#### Announcer
Stores information about the announcement maker. The `allowedToPost` stores posting permissions and is used for modifiers limiting announcement posting only to authorised entities. The `name` is used for human friendly identifier of the author to be stored.
``` js
struct Announcer{
bool allowedToPost;
string name;
}
```
#### Announcement
Stores information about the individual announcement. The human friendly author identifier is stored in `author`. Ethereum address associated with the author is stored in `authorAddress`. The announcement itself is stored in `post`.
``` js
struct Announcement{
string author;
address authorAddress;
string post;
}
```
### Methods
#### the number of ammouncements
Returns the number of announcement currently active.
OPTIONAL - this method can be used to provide quicker information for the UI, but could also be retrieved from `numberOfMessages` variable.
``` js
function theNumberOfAnnouncements() public constant returns(uint256 _numberOfAnnouncements)
```
#### read posts
Returns the specified announcement as well as human friendly poster identificator (name or nickname).
``` js
function readPosts(uint256 _postNumber) public constant returns(string _author, string _post)
```
#### give posting permission
Sets posting permissions of the address `_newAnnouncer` to `_postingPrivileges` and can also be used to revoke those permissions. The `_posterName` is human friendly author identificator used in the announcement data.
``` js
function givePostingPermission(address _newAnnouncer, bool _postingPrivileges, string _posterName) public onlyOwner returns(bool success)
```
#### can post
Checks if the entity that wants to post an announcement has the posting privilieges.
``` js
modifier canPost{
require(posterData[msg.sender].allowedToPost);
_;
}
```
#### post announcement
Lets user post announcements, but only if they have their posting privileges set to `true`. The announcement is sent in `_message` variable.
``` js
function postAnnouncement(string _message) public canPost
```
#### remove announcement
Removes an announcement with `_messageNumber` announcement identifier and rearranges the mapping so there are no empty slots. The `_removalReason` is used to update users if the issue that caused the announcement is resolved or what are the next steps from the service provider / DAPP development team.
``` js
function removeAnnouncement(uint256 _messageNumber, string _removalReason) public
```
### Events
#### New announcement
MUST trigger when new announcement is created.
Every time there is a new announcement it should be advertised in this event. It holds the information about author `author` and the announcement istelf `message`.
``` js
event NewAnnouncement(string author, string message)
```
#### Removed announcement
MUST trigger when an announcement is removed.
Every time an announcement is removed it should be advertised in this event. It holds the information about author `author`, the announcement itself `message`, the reason for removal or explanation of the solution `reason` and the address of the entity that removed the announcement `remover`.
``` js
event RemovedAnnouncement(string author, string message, string reason, address remover);
```
## 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 solution was designed with UX in mind . It provides mechanics that serve to present the announcements in the user friendly way. It is meant to be deployed as a Solidity smart contract on Ethereum network.
## 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.-->
The proposed version is deployed on Ropsten testnet all of the information can be found [here](https://ropsten.etherscan.io/address/0xb04f67172b9733837e59ebaf03d277279635c8e6#readContract).
## 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/).

152
EIPS/eip-1132.md Normal file
View File

@ -0,0 +1,152 @@
---
eip: 1132
title: Extending ERC20 with token locking capability
author: nitika-goel <nitika@govblocks.io>
type: Standards Track
category: ERC
status: Draft
created: 2018-06-03
discussions-to: https://github.com/ethereum/EIPs/issues/1132
---
## Simple Summary
An extension to the ERC20 standard with methods for time-locking of tokens within a contract.
## Abstract
This proposal provides basic functionality to time-lock tokens within an ERC20 smart contract for multiple utilities without the need of transferring tokens to an external escrow smart contract. It also allows fetching balance of locked and transferable tokens.
Time-locking can also be achieved via staking (#900), but that requires transfer of tokens to an escrow contract / stake manager, resulting in the following six concerns:
1. additional trust on escrow contract / stake manager
2. additional approval process for token transfer
3. increased ops costs due to gas requirements in transfers
4. tough user experience as the user needs to claim the amount back from external escrows
5. inability for the user to track their true token balance / token activity
6. inability for the user to utilize their locked tokens within the token ecosystem.
## Motivation
dApps often require tokens to be time-locked against transfers for letting members 1) adhere to vesting schedules and 2) show skin in the game to comply with the underlying business process. I realized this need while building Nexus Mutual and GovBlocks.
In [Nexus Mutual](https://nexusmutual.io), claim assessors are required to lock their tokens before passing a vote for claims assessment. This is important as it ensures assessors skin in the game. The need here was that once a claim assessor locks his tokens for n days, he should be able to cast multiple votes during that period of n days, which is not feasible with staking mechanism. There are other scenarios like skills/identity verification or participation in gamified token curated registries where time-locked tokens are required as well.
In [GovBlocks](https://govblocks.io), I wanted to allow dApps to lock member tokens for governance, while still allowing members to use those locked tokens for other activities within the dApp business. This is also the case with DGX governance model where theyve proposed quarterly token locking for participation in governance activities of DGX.
In addition to locking functionality, I have proposed a `Lock()` and `Unlock()` event, just like the `Transfer()` event , to track token lock and unlock status. From token holders perspective, it gets tough to manage token holdings if certain tokens are transferred to another account for locking, because whenever `balanceOf()` queries are triggered on token holders account the result does not include locked tokens. A `totalBalanceOf()` function intends to solve this problem.
The intention with this proposal is to enhance the ERC20 standard with token-locking capability so that dApps can time-lock tokens of the members without having to transfer tokens to an escrow / stake manager and at the same time allow members to use the locked tokens for multiple utilities.
## Specification
Ive extended the ERC20 interface with the following enhancements:
### Locking of tokens
```
/**
* @dev Locks a specified amount of tokens against an address,
* for a specified reason and time
* @param _reason The reason to lock tokens
* @param _amount Number of tokens to be locked
* @param _time Lock time in seconds
*/
function lock(bytes32 _reason, uint256 _amount, uint256 _time) public returns (bool)
```
### Fetching number of tokens locked under each utility
```
/**
* @dev Returns tokens locked for a specified address for a
* specified reason
*
* @param _of The address whose tokens are locked
* @param _reason The reason to query the lock tokens for
*/
tokensLocked(address _of, bytes32 _reason) view returns (uint256 amount)
```
### Fetching number of tokens locked under each utility at a future timestamp
```
/**
* @dev Returns tokens locked for a specified address for a
* specified reason at a specific time
*
* @param _of The address whose tokens are locked
* @param _reason The reason to query the lock tokens for
* @param _time The timestamp to query the lock tokens for
*/
function tokensLockedAtTime(address _of, bytes32 _reason, uint256 _time) public view returns (uint256 amount)
```
### Fetching number of tokens held by an address
```
/**
* @dev @dev Returns total tokens held by an address (locked + transferable)
* @param _of The address to query the total balance of
*/
function totalBalanceOf(address _of) view returns (uint256 amount)
```
### Extending lock period
```
/**
* @dev Extends lock for a specified reason and time
* @param _reason The reason to lock tokens
* @param _time Lock extension time in seconds
*/
function extendLock(bytes32 _reason, uint256 _time) public returns (bool)
```
### Increasing number of tokens locked
```
/**
* @dev Increase number of tokens locked for a specified reason
* @param _reason The reason to lock tokens
* @param _amount Number of tokens to be increased
*/
function increaseLockAmount(bytes32 _reason, uint256 _amount) public returns (bool)
```
### Fetching number of unlockable tokens under each utility
```
/**
* @dev Returns unlockable tokens for a specified address for a specified reason
* @param _of The address to query the the unlockable token count of
* @param _reason The reason to query the unlockable tokens for
*/
function tokensUnlockable(address _of, bytes32 _reason) public view returns (uint256 amount)
```
### Fetching number of unlockable tokens
```
/**
* @dev Gets the unlockable tokens of a specified address
* @param _of The address to query the the unlockable token count of
*/
function getUnlockableTokens(address _of) public view returns (uint256 unlockableTokens)
```
### Unlocking tokens
```
/**
* @dev Unlocks the unlockable tokens of a specified address
* @param _of Address of user, claiming back unlockable tokens
*/
function unlock(address _of) public returns (uint256 unlockableTokens)
```
### Lock event recorded in the token contract
`event Lock(address indexed _of, uint256 indexed _reason, uint256 _amount, uint256 _validity)`
### Unlock event recorded in the token contract
`event Unlock(address indexed _of, uint256 indexed _reason, uint256 _amount)`
## Test Cases
Test cases are available at [https://github.com/nitika-goel/lockable-token](https://github.com/nitika-goel/lockable-token).
## Implementation
- Complete implementation available at https://github.com/nitika-goel/lockable-token
- [GovBlocks](https://govblocks.io) Project specific implementation available at https://github.com/somish/govblocks-protocol/blob/Locking/contracts/GBTStandardToken.sol
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

75
EIPS/eip-1153.md Normal file
View File

@ -0,0 +1,75 @@
---
eip: 1153
title: Transient storage opcodes
author: Alexey Akhunov (@AlexeyAkhunov)
discussions-to: https://ethereum-magicians.org/t/eip-transient-storage-opcodes/553
status: Draft
type: Standards Track
category: Core
created: 2018-06-15
---
## Simple Summary
Support for efficient transient storage in EVM. It is like regular storage (SLOAD/SSTORE), but with the lifetime limited to one Ethereum transaction.
Notable use case is efficient reentrancy lock.
## Abstract
This proposal introduces transient storage, which behaves similar to storage,
but the updates will only persist within one Ethereum transaction. Transient storage is accessible to smart contracts via new opcodes: TLOAD and TSTORE (“T” stands for Transient).
## Motivation
Running a transaction in Ethereum can generate multiple nested frames of execution, each created by CALL (or similar) instructions.
Contracts can be re-entered during the same transaction, in which case there are more than one frame belonging to one contract.
Currently, these frames can communicate in two ways - via inputs/outputs passed via CALL instructions, and via storage updates.
If there is an intermediate frame belonging to another contract, communication via inputs/outputs is not secure. Notable example is a reentrancy lock which cannot rely on the intermediate frame to pass through the state of the lock.
Communication via storage (`SSTORE`/`SLOAD`) is costly. Transient storage is a dedicated and gas efficient solution to the problem of inter frame communication.
Language support could be added in relatively easy way. For example, in Solidity, a qualifier “transient” can be introduced (similar to the existing qualifiers “memory” and “storage”). Since addressing scheme of `TSTORE` and `TLOAD` is the same as for `SSTORE` and `SLOAD`, code generation routines that exist for storage variables, can be easily generalised to also support transient storage.
Potential use cases unlocked by this EIP include:
1. Reentrancy lock
2. Passing error codes and messages from the execution frames up the execution stack
3. More generic libraries that use callbacks, for example generalised sorting with functions `Less` and `Swap` defined.
4. Shared memory (borrowed from early draft of similar EIP by @holiman). When implementing contract-proxies using `DELEGATECALL`, all direct arguments are relayed from the caller to the callee via the `CALLDATA`, leaving no room for meta-data between the proxy and the proxee. Also, the proxy must be careful about `storage` access to avoid collision with `target` `storage`-slots. Since `transient storage` would be shared, it would be possible to use `transient storage` to pass information between the `proxy` and the `target`.
## Specification
Two new opcodes are added to EVM, `TLOAD` and `TSTORE`.
They use the same arguments on stack as `SLOAD` and `SSTORE`.
`TLOAD` pops one 32-byte word from the top of the stack, treats this value as the address, fetches 32-byte word from the transient storage at that address, and pops the value on top of the stack.
`TSTORE` pops two 32-byte words from the top of the stack. The word on the top is the address, and the next is the value. TSTORE saves the value at the given address in the transient storage.
Addressing is the same as `SLOAD` and `SSTORE`. i.e. each 32-byte address points to a unique 32-byte word.
Gas cost for both is 8 units of gas, regardless of values stored.
The effects of transient storage are discarded at the end of the transaction.
Transient storage is private to the contract that owns it, in the same way as "regular" storage is. Only owning contract frames may access their transient storage. And when they do, all the frames access the same transient store, in the same way as "regular" storage, but unlike "memory".
When transient storage is used in the context of `DELEGATECALL` or `CALLCODE`, then the owning contract of the transient storage is the contract that issued `DELEGATECALL` or `CALLCODE` instruction (the caller). When transient storage is used in the context of `CALL` or `STATICCALL`, then the owning contract of the transient storage is the contract that is the target of the `CALL` or `STATICCALL` instruction (the callee).
Transient storage does not interact with reverts or invalid transactions, that means if a frame reverts, its effects on the transient storage remain until the end of the transaction.
## Rationale
There is a proposal to alleviate the cost of inter-frame communication by reducing the cost of `SSTORE` when it modifies the same item multiple times within the same transaction (EIP-1087).
Relative cons of the transient storage: new opcodes; new code in the clients; new concept for the yellow paper (more to update); requires separation of concerns (persistence and inter-frame communication) when programming.
Relative pros of the transient storage: cheaper to use; does not change the semantics of the existing operations; very simple gas accounting rules;
## Backwards Compatibility
This EIP requires a hard fork to implement.
Since this EIP does not change semantics of any existing opcodes, it does not pose risk of backwards incompatibility for existing deployed contracts.
## Test Cases
TBD
## Implementation
Most straightforward implementation would be a dictionary (map), similar to what exists for the dirty storage, with the difference that it gets re-initialised at the start of each transaction, and does not get persisted.
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

110
EIPS/eip-1154.md Normal file
View File

@ -0,0 +1,110 @@
---
eip: 1154
title: Oracle Interface
author: Alan Lu (@cag)
discussions-to: https://github.com/ethereum/EIPs/issues/1161
status: Draft
type: Standards Track
category: ERC
created: 2018-06-13
---
## Simple Summary
A standard interface for oracles.
## Abstract
In order for ethereum smart contracts to interact with off-chain systems, oracles must be used. These oracles report values which are normally off-chain, allowing smart contracts to react to the state of off-chain systems. A distinction and a choice is made between push and pull based oracle systems. Furthermore, a standard interface for oracles is described here, allowing different oracle implementations to be interchangeable.
## Motivation
The Ethereum ecosystem currently has many different oracle implementations available, but they do not provide a unified interface. Smart contract systems would be locked into a single set of oracle implementations, or they would require developers to write adapters/ports specific to the oracle system chosen in a given project.
Beyond naming differences, there is also the issue of whether or not an oracle report-resolving transaction _pushes_ state changes by calling affected contracts, or changes the oracle state allowing dependent contracts to _pull_ the updated value from the oracle. These differing system semantics could introduce inefficiencies when adapting between them.
Ultimately, the value in different oracle systems comes from their underlying resolution mechanics, and points where these systems are virtually identical should be standardized.
These oracles may be used for answering questions about "real-world events", where each ID can be correlated with a specification of a question and its answers (so most likely for prediction markets, basically).
Another use case could be for decision-making processes, where the results given by the oracle represent decisions made by the oracle (e.g. futarchies). DAOs may require their use in decision making processes.
Both the ID and the results are intentionally unstructured so that things like time series data (via splitting the ID) and different sorts of results (like one of a few, any subset of up to 256, or some value in a range with up to 256 bits of granularity) can be represented.
## Specification
<dl>
<dt>Oracle</dt>
<dd>An entity which reports data to the blockchain.</dd>
<dt>Oracle consumer</dt>
<dd>A smart contract which receives data from an oracle.</dd>
<dt>ID</dt>
<dd>A way of indexing the data which an oracle reports. May be derived from or tied to a question for which the data provides the answer.</dd>
<dt>Result</dt>
<dd>Data associated with an id which is reported by an oracle. This data oftentimes will be the answer to a question tied to the id. Other equivalent terms that have been used include: answer, data, outcome.</dd>
<dt>Report</dt>
<dd>A pair (ID, result) which an oracle sends to an oracle consumer.</dd>
</dl>
```solidity
interface OracleConsumer {
function receiveResult(bytes32 id, bytes result) external;
}
```
`receiveResult` MUST revert if the `msg.sender` is not an oracle authorized to provide the `result` for that `id`.
`receiveResult` MUST revert if `receiveResult` has been called with the same `id` before.
`receiveResult` MAY revert if the `id` or `result` cannot be handled by the consumer.
Consumers MUST coordinate with oracles to determine how to encode/decode results to and from `bytes`. For example, `abi.encode` and `abi.decode` may be used to implement a codec for results in Solidity. `receiveResult` SHOULD revert if the consumer receives a unexpected result format from the oracle.
The oracle can be any Ethereum account.
## Rationale
The specs are currently very similar to what is implemented by ChainLink (which can use any arbitrarily-named callback) and Oraclize (which uses `__callback`).
With this spec, the oracle _pushes_ state to the consumer, which must react accordingly to the updated state. An alternate _pull_-based interface can be prescribed, as follows:
### Alternate Pull-based Interface
Here are alternate specs loosely based on Gnosis prediction market contracts v1. Reality Check also exposes a similar endpoint (`getFinalAnswer`).
```solidity
interface Oracle {
function resultFor(bytes32 id) external view returns (bytes result);
}
```
`resultFor` MUST revert if the result for an `id` is not available yet.
`resultFor` MUST return the same result for an `id` after that result is available.
### Push vs Pull
Note that push-based interfaces may be adapted into pull-based interfaces. Simply deploy an oracle consumer which stores the result received and implements `resultFor` accordingly.
Similarly, every pull-based system can be adapted into a push-based system: just add a method on the oracle smart contract which takes an oracle consumer address and calls `receiveResult` on that address.
In both cases, an additional transaction would have to be performed, so the choice to go with push or pull should be based on the dominant use case for these oracles.
In the simple case where a single account has the authority to decide the outcome of an oracle question, there is no need to deploy an oracle contract and store the outcome on that oracle contract. Similarly, in the case where the outcome comes down to a vote, existing multisignature wallets can be used as the authorized oracle.
#### Multiple Oracle Consumers
In the case that many oracle consumers depend on a single oracle result and all these consumers expect the result to be pushed to them, the push and pull adaptations mentioned before may be combined if the pushing oracle cannot be trusted to send the same result to every consumer (in a sense, this forwards the trust to the oracle adaptor implementation).
In a pull-based system, each of the consumers would have to be called to pull the result from the oracle contract, but in the proposed push-based system, the adapted oracle would have to be called to push the results to each of the consumers.
Transaction-wise, both systems are roughly equivalent in efficiency in this scenario, but in the push-based system, there's a need for the oracle consumers to store the results again, whereas in the pull-based system, the consumers may continue to refer to the oracle for the results. Although this may be somewhat less efficient, requiring the consumers to store the results can also provide security guarantees, especially with regards to result immutability.
#### Result Immutability
In both the proposed specification and the alternate specification, results are immutable once they are determined. This is due to the expectation that typical consumers will require results to be immutable in order to determine a resulting state consistently. With the proposed push-based system, the consumer enforces the result immutability requirement, whereas in the alternate pull-based system, either the oracle would have to be trusted to implement the spec correctly and enforce the immutability requirement, or the consumer would also have to handle result immutability.
For data which mutates over time, the `id` field may be structured to specify "what" and "when" for the data (using 128 bits to specify "when" is still safe for many millenia).
## Implementation
* [Tidbit](https://github.com/levelkdev/tidbit) tracks this EIP.
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

400
EIPS/eip-1155.md Normal file
View File

@ -0,0 +1,400 @@
---
eip: 1155
title: Crypto Item Standard
author: Witek Radomski <witek@enjin.com>, Andrew Cooke <andrew@enjin.com>
type: Standards Track
category: ERC
status: Draft
created: 2018-06-17
discussions-to: https://github.com/ethereum/EIPs/issues/1155
---
## Simple Summary
A standard interface for multiple item/token definitions in a single deployed contract.
## Abstract
This standard outlines a smart contract interface where one can represent any number of Fungible and Non-Fungible assets in a single contract. Existing standards such as ERC-20 require deployment of separate contracts per token. The ERC-721 standard's Token ID is a single non-fungible index and the group of these non-fungibles is deployed as a single contract with settings for the entire collection. Instead, the ERC-1155 Crypto Item Standard allows for each Item ID to represent a new configurable token type, which may have its own totalSupply value and other such attributes.
The `_id` parameter is contained in each function's parameters and indicates a specific item or item type in a transaction.
## Motivation
Tokens standards like ERC-20 and ERC-721 require a separate contract to be deployed for each fungible or NFT token/collection. This places a lot of redundant bytecode on the Ethereum blockchain and limits certain functionality by the nature of separating each token contract into its own permissioned address. With the rise of crypto games and platforms like [Enjin Coin](https://enjincoin.io/), game developers may be creating tens of thousands of items, and a new type of token standard is needed to support this.
New functionality is possible with this design, such as transferring or approving multiple token types at once, saving on transaction costs. Trading (escrow / atomic swaps) of multiple tokens can be built on top of this standard and it removes the need to "approve" individual tokens separately. It is also easy to describe and mix multiple fungible or non-fungible tokens in a single contract.
## Specification
```solidity
pragma solidity ^0.4.24;
/**
@title ERC-1155 Crypto Items Standard
@dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
Note: the ERC-165 identifier for this interface is 0xf23a6e61.
*/
interface IERC1155 {
/**
@dev MUST trigger on any successful call to approve(address _spender, uint256 _value)
*/
event Approval(address indexed _owner, address indexed _spender, uint256 indexed _id, uint256 _oldValue, uint256 _value);
/**
@dev MUST trigger when tokens are transferred, including zero value transfers
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 NFT (if any) is reset to none.
*/
event Transfer(address _spender, address indexed _from, address indexed _to, uint256 indexed _id, uint256 _value);
/**
@dev Transfers value amount of an _id from the _from address to the _to addresses specified. Each parameter array should be the same length, with each index correlating.
Caller must have a sufficient allowance by _from for the _id/_value pair
@param _from source addresses
@param _to target addresses
@param _id ID of the CryptoItem
@param _value transfer amounts
*/
function transferFrom(address _from, address _to, uint256 _id, uint256 _value) external;
/**
@dev Transfers value amount of an _id from the _from address to the _to addresses specified. Each parameter array should be the same length, with each index correlating.
Caller must have a sufficient allowance by _from for the _id/_value pair
Throws if `_to` is the zero address.
Throws if `_id` 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 `onERC1155Received` on `_to` and throws if the return value is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`.
@param _from source addresses
@param _to target addresses
@param _id ID of the CryptoItem
@param _value transfer amounts
@param _data Additional data with no specified format, sent in call to `_to`
*/
function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes _data) external;
/**
@dev Allow other accounts/contracts to spend tokens on behalf of msg.sender
Also, to minimize the risk of the approve/transferFrom attack vector
(see https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/), this function will throw if the current approved allowance does not equal the expected _currentValue, unless _value is 0
@param _spender Address to approve
@param _id ID of the CryptoItem
@param _currentValue Expected current value of approved allowance.
@param _value Allowance amount
*/
function approve(address _spender, uint256 _id, uint256 _currentValue, uint256 _value) external;
/**
@dev Get the balance of an account's CryptoItems
@param _id ID of the CryptoItem
@param _owner The address of the token holder
@return The _owner's balance of the CryptoItem type requested
*/
function balanceOf(uint256 _id, address _owner) external view returns (uint256);
/**
@dev Queries the spending limit approved for an account
@param _id ID of the CryptoItem
@param _owner The owner allowing the spending
@param _spender The address allowed to spend.
@return The _spender's allowed spending balance of the CryptoItem requested
*/
function allowance(uint256 _id, address _owner, address _spender) external view returns (uint256);
}
```
<details>
<summary>
Simple/Extended Transfers</summary>
```solidity
interface IERC1155Extended {
/**
@dev Send a single type of CryptoItem
@param _to Transfer destination address
@param _id ID of the CryptoItem
@param _value Transfer amount
*/
function transfer(address _to, uint256 _id, uint256 _value) external;
/**
@dev Send a single type of CryptoItem (with safety call)
@param _to Transfer destination address
@param _id ID of the CryptoItem
@param _value Transfer amount
@param _data Additional data with no specified format, sent in call to `_to`
*/
function safeTransfer(address _to, uint256 _id, uint256 _value, bytes _data) external;
}
```
</details>
<details>
<summary>
Batch Transfers</summary>
```solidity
interface IERC1155BatchTransfer {
/**
@dev Send multiple types of CryptoItems from a 3rd party in one transfer
For the purpose of transfer fees, each id/value pair is counted as a transfer
Caller must have a sufficient allowance by _from for each of the _id/_value pairs
Throws on any error rather than return a false flag to minimize user errors
@param _from Source address
@param _to Target address
@param _ids Types of CryptoItems
@param _values Transfer amounts per item type
*/
function batchTransferFrom(address _from, address _to, uint256[] _ids, uint256[] _values) external;
/**
@dev Send multiple types of CryptoItems from a 3rd party in one transfer (with safety call)
For the purpose of transfer fees, each id/value pair is counted as a transfer
Caller must have a sufficient allowance by _from for each of the _id/_value pairs
Throws on any error rather than return a false flag to minimize user errors
@param _from Source address
@param _to Target address
@param _ids Types of CryptoItems
@param _values Transfer amounts per item type
@param _data Additional data with no specified format, sent in call to `_to`
*/
function safeBatchTransferFrom(address _from, address _to, uint256[] _ids, uint256[] _values, bytes _data) external;
/**
@dev Allow other accounts/contracts to spend tokens on behalf of msg.sender
Also, to minimize the risk of the approve/transferFrom attack vector
(see https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/), this function will throw if the current approved allowance does not equal the expected _currentValue, unless _value is 0
@param _spender Address to approve
@param _ids IDs of the CryptoItems
@param _currentValues Expected current values of allowances per item type
@param _values Allowance amounts per item type
*/
function batchApprove(address _spender, uint256[] _ids, uint256[] _currentValues, uint256[] _values) external;
}
```
</details>
<details>
<summary>
Simple/Extended Batch Transfers</summary>
```solidity
interface IERC1155BatchTransferExtended {
/**
@dev Send multiple types of CryptoItems in one transfer
For the purpose of transfer fees, each id/value pair is counted as a transfer
@param _to Transfer destination address
@param _ids IDs of the CryptoItems
@param _values Transfer amounts per item type
*/
function batchTransfer(address _to, uint256[] _ids, uint256[] _values) external;
/**
@dev Send multiple types of CryptoItems in one transfer (with safety call)
For the purpose of transfer fees, each id/value pair is counted as a transfer
@param _to Transfer destination address
@param _ids IDs of the CryptoItems
@param _values Transfer amounts per item type
@param _data Additional data with no specified format, sent in call to `_to`
*/
function safeBatchTransfer(address _to, uint256[] _ids, uint256[] _values, bytes _data) external;
}
```
</details>
<details>
<summary>
Extended Approvals</summary>
```solidity
interface IERC1155Operators {
event OperatorApproval(address indexed _owner, address indexed _operator, uint256 indexed _id, bool _approved);
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
/**
@notice Enable or disable approval for a third party ("operator") to manage
all of `msg.sender`'s assets for a particular CryptoItem types.
@dev Emits the OperatorApproval event
@param _operator Address to add to the set of authorized operators
@param _ids The IDs of the CryptoItems
@param _approved True if the operators is approved, false to revoke approval
*/
function setApproval(address _operator, uint256[] _ids, bool _approved) external;
/**
@dev Queries the approval status of an operator for a given CryptoItem and owner
@param _owner The owner of the CryptoItems
@param _operator Address of authorized operator
@param _id ID of the CryptoItem
@return True if the operator is approved, false if not
*/
function isApproved(address _owner, address _operator, uint256 _id) external view returns (bool);
/**
@notice Enable or disable approval for a third party ("operator") to manage
all of `msg.sender`'s assets.
@dev Emits the OperatorApproval event
@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;
/**
@dev Queries the approval status of an operator for a given CryptoItem and owner
@param _owner The owner of the CryptoItems
@param _operator Address of authorized operator
@return True if the operator is approved, false if not
*/
function isApprovedForAll(address _owner, address _operator) external view returns (bool isOperator);
}
```
</details>
<details>
<summary>
Views</summary>
```solidity
interface IERC1155Views {
/**
@dev Returns how many of a CryptoItem are deemed or expected to exist in circulation
@param _id ID of the CryptoItem
@return The number of CryptoItems in circulation
*/
function totalSupply(uint256 _id) external view returns (uint256);
/**
@dev Returns a human readable string that identifies a CryptoItem, similar to ERC20
@param _id ID of the CryptoItem
@return The name of the CryptoItem type
*/
function name(uint256 _id) external view returns (string);
/**
@dev Returns symbol of a CryptoItem, similar to ERC20 and ERC721
@param _id ID of the CryptoItem
@return The symbol of the CryptoItem
*/
function symbol(uint256 _id) external view returns (string);
/**
@dev Returns the number of decimal places for a CryptoItem, similar to ERC20
@param _id ID of the CryptoItem
@return Number of decimals
*/
function decimals(uint256 _id) external view returns (uint8);
/**
@notice A distinct Uniform Resource Identifier (URI) for a given asset
@dev URIs are defined in RFC 3986
@return URI string
*/
function uri(uint256 _id) external view returns (string);
}
```
</details>
<details>
<summary>
ERC-1155 Token Receiver</summary>
```solidity
interface IERC1155TokenReceiver {
/**
@notice Handle the receipt of an ERC1155 type
@dev The smart contract calls this function on the recipient
after a `safeTransfer`. This function MAY throw to revert and reject the
transfer. Return of other than the magic value MUST result in the
transaction being reverted
Note: the contract address is always the message sender
@param _operator The address which called `safeTransferFrom` function
@param _from The address which previously owned the token
@param _id The identifier of the item being transferred
@param _value The amount of the item being transferred
@param _data Additional data with no specified format
@return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
*/
function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _value, bytes _data) external returns(bytes4);
}
```
</details>
## Non-Fungible Items
An example strategy to mix Fungible and Non-Fungible Items together in the same contract would be to pass the base item ID in the top 128 bits of the uint256 `_itemID` parameter and then use the bottom 128 bits for any extra data you wish to pass to the contract.
Non-Fungible Items can be interacted with using an index based accessor into the contract/item data set. Therefore to access a particular item set within a mixed data contract and particular NFT within that set, `_itemID` could be passed as `<uint128: base item id><uint128: index of NFT>`.
Inside the contract code the two pieces of data needed to access the individual NFT can be extracted with uint128(~0) and the same mask shifted by 128.
### Interface
<details>
<summary>
Optional Non Fungible Interface</summary>
```solidity
interface IERC1155NonFungible {
/**
@notice Find the owner of an NFT
@dev NFTs assigned to zero address are considered invalid, and queries about them do throw
@param _id The identifier for an NFT
@return The address of the owner of the NFT
*/
function ownerOf(uint256 _id) external view returns (address);
/**
@notice Enumerate valid NFs
@dev Throws if `_index` >= `totalSupply()`.
@param _index A counter less than `totalSupply()`
@return The token identifier for the `_index`th NFT (sort order not specified)
*/
function nonFungibleByIndex(uint256 _id, uint128 _index) external view returns (uint256);
/**
@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 nonFungibleOfOwnerByIndex(uint256 _id, address _owner, uint128 _index) external view returns (uint256);
/**
@notice Is this token non fungible?
@dev If this returns true, the token is non-fungible.
@param _id The identifier for a potential non-fungible.
@return True if the token is non-fungible
*/
function isNonFungible(uint256 _id) external view returns (bool);
}
```
</details>
### Example of split ID bits
```solidity
uint256 baseToken = 12345 << 128;
uint128 index = 50;
balanceOf(baseToken, msg.sender); // Get balance of the base token
balanceOf(baseToken + index, msg.sender); // Get balance of the Non-Fungible token index
```
## Implementation
- [ERC-1155 Reference Implementation](https://github.com/enjin/erc-1155)
- [Enjin Coin](https://enjincoin.io) ([github](https://github.com/enjin))
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

125
EIPS/eip-1167.md Normal file
View File

@ -0,0 +1,125 @@
---
eip: 1167
title: Minimal Proxy Contract
author: Peter Murray (@yarrumretep), Nate Welch (@flygoing), Joe Messerman (@JAMesserman)
discussions-to: https://github.com/optionality/clone-factory/issues/10
status: Final
type: Standards Track
category: ERC
created: 2018-06-22
---
<!--You can leave these HTML comments in your merged EIP and delete the visible duplicate text guides, they will not appear and may be helpful to refer to if you edit it again. 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.-->
To simply and cheaply clone contract functionality in an immutable way, this standard specifies a minimal bytecode implementation that delegates all calls to a known, fixed address.
## Abstract
<!--A short (~200 word) description of the technical issue being addressed.-->
By standardizing on a known minimal bytecode redirect implementation, this standard allows users and third party tools (e.g. Etherscan) to (a) simply discover that a contract will always redirect in a known manner and (b) depend on the behavior of the code at the destination contract as the behavior of the redirecting contract. Specifically, tooling can interrogate the bytecode at a redirecting address to determine the location of the code that will run - and can depend on representations about that code (verified source, third-party audits, etc). This implementation forwards all calls and 100% of the gas to the implementation contract and then relays the return value back to the caller. In the case where the implementation reverts, the revert is passed back along with the payload data (for revert with message).
## 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.-->
This standard supports use-cases wherein it is desireable to clone exact contract functionality with a minimum of side effects (e.g. memory slot stomping) and with low gas cost deployment of duplicate proxies.
## 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 (go-ethereum, parity, cpp-ethereum, ethereumj, ethereumjs, and [others](https://github.com/ethereum/wiki/wiki/Clients)).-->
The exact bytecode of the standard clone contract is this: `363d3d373d3d3d363d73bebebebebebebebebebebebebebebebebebebebe5af43d82803e903d91602b57fd5bf3` wherein the bytes at idices 10 - 29 (inclusive) are replaced with the 20 byte address of the master functionality contract.
A reference implementation of this can be found at the [optionality/clone-factory](https://github.com/optionality/clone-factory) github repo.
## 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 goals of this effort have been the following:
- inexpensive deployment (low gas to deploy clones)
- support clone initialization in creation transaction (through factory contract model)
- simple clone bytecode to encourage directly bytecode interrogation (see CloneProbe.sol in the clone-factory project)
- dependable, locked-down behavior - this is not designed to handle upgradability, nor should it as the representation we are seeking is stronger.
- small operational overhead - adds a single call cost to each call
- handles error return bubbling for revert messages
## 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.-->
There are no backwards compatibility issues. There may be some systems that are using earlier versions of the proxy contract bytecode. They will not be compliant with this standard.
## 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 include:
- invocation with no arguments
- invocation with arguments
- invocation with fixed length return values
- invocation with variable length return values
- invocation with revert (confirming reverted payload is transferred)
Tests for these cases are included in the reference implementation project.
## 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.-->
Deployment bytecode is not included in this specification. One approach is defined in the proxy-contract reference implementation.
### Standard Proxy
The disassembly of the standard deployed proxy contract code (from r2 and edited to include stack visualization)
```
| 0x00000000 36 calldatasize cds
| 0x00000001 3d returndatasize 0 cds
| 0x00000002 3d returndatasize 0 0 cds
| 0x00000003 37 calldatacopy
| 0x00000004 3d returndatasize 0
| 0x00000005 3d returndatasize 0 0
| 0x00000006 3d returndatasize 0 0 0
| 0x00000007 36 calldatasize cds 0 0 0
| 0x00000008 3d returndatasize 0 cds 0 0 0
| 0x00000009 73bebebebebe. push20 0xbebebebe 0xbebe 0 cds 0 0 0
| 0x0000001e 5a gas gas 0xbebe 0 cds 0 0 0
| 0x0000001f f4 delegatecall suc 0
| 0x00000020 3d returndatasize rds suc 0
| 0x00000021 82 dup3 0 rds suc 0
| 0x00000022 80 dup1 0 0 rds suc 0
| 0x00000023 3e returndatacopy suc 0
| 0x00000024 90 swap1 0 suc
| 0x00000025 3d returndatasize rds 0 suc
| 0x00000026 91 swap2 suc 0 rds
| 0x00000027 602b push1 0x2b 0x2b suc 0 rds
| ,=< 0x00000029 57 jumpi 0 rds
| | 0x0000002a fd revert
| `-> 0x0000002b 5b jumpdest 0 rds
\ 0x0000002c f3 return
```
NOTE: as an effort to reduce gas costs as much as possible, the above bytecode depends on EIP-211 specification that `returndatasize` returns zero prior to any calls within the call-frame. `returndatasize` uses 1 less gas than `dup*`.
### Vanity Address Optimization
Proxy deployment can be further optimized by installing the master contract at a vanity contract deployment address with leading zero-bytes. By generating a master contract vanity address that includes Z leading 0 bytes in its address, you can shorten the proxy bytecode by replacing the `push20` opcode with `pushN` (where N is 20 - Z) followed by the N non-zero address bytes. The revert jump address is decremented by Z in this case. Here is an example where Z = 4:
```
| 0x00000000 36 calldatasize cds
| 0x00000001 3d returndatasize 0 cds
| 0x00000002 3d returndatasize 0 0 cds
| 0x00000003 37 calldatacopy
| 0x00000004 3d returndatasize 0
| 0x00000005 3d returndatasize 0 0
| 0x00000006 3d returndatasize 0 0 0
| 0x00000007 36 calldatasize cds 0 0 0
| 0x00000008 3d returndatasize 0 cds 0 0 0
| 0x00000009 6fbebebebebe. push16 0xbebebebe 0xbebe 0 cds 0 0 0
| 0x0000001a 5a gas gas 0xbebe 0 cds 0 0 0
| 0x0000001b f4 delegatecall suc 0
| 0x0000001c 3d returndatasize rds suc 0
| 0x0000001d 82 dup3 0 rds suc 0
| 0x0000001e 80 dup1 0 0 rds suc 0
| 0x0000001f 3e returndatacopy suc 0
| 0x00000020 90 swap1 0 suc
| 0x00000021 3d returndatasize rds 0 suc
| 0x00000022 91 swap2 suc 0 rds
| 0x00000023 6027 push1 0x27 0x27 suc 0 rds
| ,=< 0x00000025 57 jumpi 0 rds
| | 0x00000026 fd revert
| `-> 0x00000027 5b jumpdest 0 rds
\ 0x00000028 f3 return
```
This saves 4 bytes of proxy contract size (savings on each deployment) and has zero impact on runtime gas costs.
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

533
EIPS/eip-1175.md Normal file
View File

@ -0,0 +1,533 @@
---
eip: 1175
title: Wallet & shop standard for all tokens (erc20)
author: Jet Lim (@Nitro888)
discussions-to: https://github.com/ethereum/EIPs/issues/1182
status: Draft
type: Standards Track
category: ERC
created: 2018-06-21
requires: 20
---
# All tokens go to heaven
## Simple Summary
Make wallets and shops created from certified contracts make erc20 tokens easy to use for commerce.
![wallet](https://user-images.githubusercontent.com/11692220/41762799-ee17c480-7636-11e8-9930-681be2c59b56.png)
## Abstract
The mutual trust between the wallet and the shop created by the authenticated contract allows you to pay for and purchase items at a simple process.
## Motivation
New standards with improvements have been released, but the majority of tokens currently being developed are erc20 tokens. So I felt I needed a proposal to use old tokens in commerce.
To use various erc20 tokens for trading, you need a custom contract. However, a single wallet with a variety of tokens, and a mutually trusted store, can make transactions that are simple and efficient. The erc20 token is traded through two calls, `approve (address _spender, uint256 _value)` and `transferFrom (address _from, address _to, uint256 _value)`, but when using the wallet contract, `paySafe (address _shop, uint256 _item)`will be traded only in one call.
And if you only reuse the store interface, you can also trade using `payUnsafe (address _shop, uint256 _item)`.
## Specification
![workflow](https://user-images.githubusercontent.com/11692220/41841025-2ed6e024-78a2-11e8-9faf-2b43aeaa2303.png)
## WalletCenter
### Methods
#### createWallet
Create wallet contract and add to list. Returns the address of new wallet.
``` js
function createWallet() public returns (address _wallet)
```
#### isWallet
Returns true or false value for test this address is a created by createWallet.
``` js
function isWallet(address _wallet) public constant returns (bool)
```
#### createShop
Create Shop contract and add to list. Returns the address of new Shop with erc20 token address.
``` js
function createShop(address _erc20) public returns (address _shop)
```
#### isShop
Returns true or false value for test this address is a created by createWallet.
``` js
function isShop(address _shop) public constant returns (bool)
```
### Events
#### Wallet
Search for my wallet.
``` js
event Wallet(address indexed _owner, address indexed _wallet)
```
#### Shop
Search for my shop.
``` js
event Shop(address indexed _owner, address indexed _shop, address indexed _erc20)
```
## Wallet
Wallet must be created by wallet center.
### Methods
#### balanceOf
Returns the account balance of Wallet.
``` js
function balanceOf(address _erc20) public constant returns (uint256 balance)
```
#### withdrawal
withdrawal `_value` amount of `_erc20` token to `_owner`.
``` js
function withdrawal(address _erc20, uint256 _value) onlyOwner public returns (bool success)
```
#### paySafe
Pay for safe shop (created by contract) item with item index `_item`.
``` js
function paySafe(address _shop, uint256 _item) onlyOwner onlyShop(_shop) public payable returns (bool success)
```
#### payUnsafe
Pay for unsafe shop (did not created by contract) item with item index `_item`.
``` js
function payUnsafe(address _shop, uint256 _item) onlyOwner public payable returns (bool success)
```
#### payCancel
Cancel pay and refund. (only weekly model)
``` js
function payCancel(address _shop, uint256 _item) onlyOwner public returns (bool success)
```
#### refund
Refund from shop with item index `_item`.
``` js
function refund(uint256 _item, uint256 _value) public payable returns (bool success)
```
### Events
#### Pay
``` js
event Pay(address indexed _shop, uint256 indexed _item, uint256 indexed _value)
```
#### Refund
``` js
event Refund(address indexed _shop, uint256 indexed _item, uint256 indexed _value)
```
## Shop
Shop is created by wallet center or not. but Shop that created by wallet center is called safe shop.
### Methods
#### balanceOf
Returns the account balance of Shop.
``` js
function balanceOf(address _erc20) public constant returns (uint256 balance)
```
#### withdrawal
withdrawal `_value` amount of `_erc20` token to `_owner`.
``` js
function withdrawal(address _erc20, uint256 _value) onlyOwner public returns (bool success)
```
#### pay
Pay from buyer with item index `_item`.
``` js
function pay(uint256 _item) onlyWallet(msg.sender) public payable returns (bool success)
```
#### refund
refund token to `_to`.
``` js
function refund(address _buyer, uint256 _item, uint256 _value) onlyWallet(_buyer) onlyOwner public payable returns (bool success)
```
#### resister
Listing item for sell.
``` js
function resister(uint8 _category, uint256 _price, uint256 _stock) onlyOwner public returns (uint256 _itemId)
```
#### update
Update item state for sell. (change item `_price` or add item `_stock`)
``` js
function update(uint256 _item, uint256 _price, uint256 _stock) onlyOwner public
```
#### price
Get token address and price from buyer with item index `_item`.
``` js
function price(uint256 _item) public constant returns (address _erc20, uint256 _value)
```
#### canBuy
`_who` can Buy `_item`.
``` js
function canBuy(address _who, uint256 _item) public constant returns (bool _canBuy)
```
#### isBuyer
`_who` is buyer of `_item`.
``` js
function isBuyer(address _who, uint256 _item) public constant returns (bool _buyer)
```
#### info
Set shop information bytes.
``` js
function info(bytes _msgPack)
```
#### upVote
Up vote for this shop.
``` js
function upVote()
```
#### dnVote
Down vote for this shop.
``` js
function dnVote()
```
#### about
Get shop token, up vote and down vote.
``` js
function about() view returns (address _erc20, uint256 _up, uint256 _down)
```
#### infoItem
Set item information bytes.
``` js
function infoItem(uint256 _item, bytes _msgPack)
```
#### upVoteItem
Up vote for this item.
``` js
function upVoteItem(uint256 _item)
```
#### dnVoteItem
Down vote for this item.
``` js
function dnVoteItem(uint256 _item)
```
#### aboutItem
Get Item price, up vote and down vote.
``` js
function aboutItem(uint256 _item) view returns (uint256 _price, uint256 _up, uint256 _down)
```
### Events
#### Pay
``` js
event Pay(address indexed _buyer, uint256 indexed _item, uint256 indexed _value)
```
#### Refund
``` js
event Refund(address indexed _to, uint256 indexed _item, uint256 indexed _value)
```
#### Item
``` js
event Item(uint256 indexed _item, uint256 _price)
```
#### Info
``` js
event Info(bytes _msgPack)
```
#### InfoItem
``` js
event InfoItem(uint256 indexed _item, bytes _msgPack)
```
## Implementation
Sample token contract address is [0x393dd70ce2ae7b30501aec94727968c517f90d52](https://ropsten.etherscan.io/address/0x393dd70ce2ae7b30501aec94727968c517f90d52)
WalletCenter contract address is [0x1fe0862a4a8287d6c23904d61f02507b5044ea31](https://ropsten.etherscan.io/address/0x1fe0862a4a8287d6c23904d61f02507b5044ea31)
WalletCenter create shop contract address is [0x59117730D02Ca3796121b7975796d479A5Fe54B0](https://ropsten.etherscan.io/address/0x59117730D02Ca3796121b7975796d479A5Fe54B0)
WalletCenter create wallet contract address is [0x39da7111844df424e1d0a0226183533dd07bc5c6](https://ropsten.etherscan.io/address/0x39da7111844df424e1d0a0226183533dd07bc5c6)
## Appendix
``` js
pragma solidity ^0.4.24;
contract ERC20Interface {
function totalSupply() public constant returns (uint);
function balanceOf(address tokenOwner) public constant returns (uint balance);
function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
function transfer(address to, uint tokens) public returns (bool success);
function approve(address spender, uint tokens) public returns (bool success);
function transferFrom(address from, address to, uint tokens) public returns (bool success);
event Transfer(address indexed from, address indexed to, uint tokens);
event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}
contract SafeMath {
function safeAdd(uint a, uint b) public pure returns (uint c) {
c = a + b;
require(c >= a);
}
function safeSub(uint a, uint b) public pure returns (uint c) {
require(b <= a);
c = a - b;
}
function safeMul(uint a, uint b) public pure returns (uint c) {
c = a * b;
require(a == 0 || c / a == b);
}
function safeDiv(uint a, uint b) public pure returns (uint c) {
require(b > 0);
c = a / b;
}
}
contract _Base {
address internal owner;
address internal walletCenter;
modifier onlyOwner {
require(owner == msg.sender);
_;
}
modifier onlyWallet(address _addr) {
require(WalletCenter(walletCenter).isWallet(_addr));
_;
}
modifier onlyShop(address _addr) {
require(WalletCenter(walletCenter).isShop(_addr));
_;
}
function balanceOf(address _erc20) public constant returns (uint256 balance) {
if(_erc20==address(0))
return address(this).balance;
return ERC20Interface(_erc20).balanceOf(this);
}
function transfer(address _to, address _erc20, uint256 _value) internal returns (bool success) {
require((_erc20==address(0)?address(this).balance:ERC20Interface(_erc20).balanceOf(this))>=_value);
if(_erc20==address(0))
_to.transfer(_value);
else
ERC20Interface(_erc20).approve(_to,_value);
return true;
}
function withdrawal(address _erc20, uint256 _value) public returns (bool success);
event Pay(address indexed _who, uint256 indexed _item, uint256 indexed _value);
event Refund(address indexed _who, uint256 indexed _item, uint256 indexed _value);
event Prize(address indexed _who, uint256 indexed _item, uint256 indexed _value);
}
contract _Wallet is _Base {
constructor(address _who) public {
owner = _who;
walletCenter = msg.sender;
}
function pay(address _shop, uint256 _item) private {
require(_Shop(_shop).canBuy(this,_item));
address _erc20;
uint256 _value;
(_erc20,_value) = _Shop(_shop).price(_item);
transfer(_shop,_erc20,_value);
_Shop(_shop).pay(_item);
emit Pay(_shop,_item,_value);
}
function paySafe(address _shop, uint256 _item) onlyOwner onlyShop(_shop) public payable returns (bool success) {
pay(_shop,_item);
return true;
}
function payUnsafe(address _shop, uint256 _item) onlyOwner public payable returns (bool success) {
pay(_shop,_item);
return true;
}
function payCancel(address _shop, uint256 _item) onlyOwner public returns (bool success) {
_Shop(_shop).payCancel(_item);
return true;
}
function refund(address _erc20, uint256 _item, uint256 _value) public payable returns (bool success) {
require((_erc20==address(0)?msg.value:ERC20Interface(_erc20).allowance(msg.sender,this))==_value);
if(_erc20!=address(0))
ERC20Interface(_erc20).transferFrom(msg.sender,this,_value);
emit Refund(msg.sender,_item,_value);
return true;
}
function prize(address _erc20, uint256 _item, uint256 _value) public payable returns (bool success) {
require((_erc20==address(0)?msg.value:ERC20Interface(_erc20).allowance(msg.sender,this))==_value);
if(_erc20!=address(0))
ERC20Interface(_erc20).transferFrom(msg.sender,this,_value);
emit Prize(msg.sender,_item,_value);
return true;
}
function withdrawal(address _erc20, uint256 _value) onlyOwner public returns (bool success) {
require((_erc20==address(0)?address(this).balance:ERC20Interface(_erc20).balanceOf(this))>=_value);
if(_erc20==address(0))
owner.transfer(_value);
else
ERC20Interface(_erc20).transfer(owner,_value);
return true;
}
}
contract _Shop is _Base, SafeMath{
address erc20;
constructor(address _who, address _erc20) public {
owner = _who;
walletCenter = msg.sender;
erc20 = _erc20;
}
struct item {
uint8 category; // 0 = disable, 1 = non Stock, non Expire, 2 = can Expire (after 1 week), 3 = stackable
uint256 price;
uint256 stockCount;
mapping(address=>uint256) customer;
}
uint index;
mapping(uint256=>item) items;
function pay(uint256 _item) onlyWallet(msg.sender) public payable returns (bool success) {
require(canBuy(msg.sender, _item));
require((erc20==address(0)?msg.value:ERC20Interface(erc20).allowance(msg.sender,this))==items[_item].price);
if(erc20!=address(0))
ERC20Interface(erc20).transferFrom(msg.sender,this,items[_item].price);
if(items[_item].category==1 || items[_item].category==2 && now > safeAdd(items[_item].customer[msg.sender], 1 weeks))
items[_item].customer[msg.sender] = now;
else if(items[_item].category==2 && now < safeAdd(items[_item].customer[msg.sender], 1 weeks) )
items[_item].customer[msg.sender] = safeAdd(items[_item].customer[msg.sender], 1 weeks);
else if(items[_item].category==3) {
items[_item].customer[msg.sender] = safeAdd(items[_item].customer[msg.sender],1);
items[_item].stockCount = safeSub(items[_item].stockCount,1);
}
emit Pay(msg.sender,_item,items[_item].customer[msg.sender]);
return true;
}
function payCancel(uint256 _item) onlyWallet(msg.sender) public returns (bool success) {
require (items[_item].category==2&&safeAdd(items[_item].customer[msg.sender],2 weeks)>now&&balanceOf(erc20)>=items[_item].price);
items[_item].customer[msg.sender] = safeSub(items[_item].customer[msg.sender],1 weeks);
transfer(msg.sender, erc20, items[_item].price);
_Wallet(msg.sender).refund(erc20,_item,items[_item].price);
emit Refund(msg.sender,_item,items[_item].price);
return true;
}
function refund(address _to, uint256 _item) onlyWallet(_to) onlyOwner public payable returns (bool success) {
require(isBuyer(_to,_item)&&items[_item].category>0&&(items[_item].customer[_to]>0||(items[_item].category==2&&safeAdd(items[_item].customer[_to],2 weeks)>now)));
require((erc20==address(0)?address(this).balance:ERC20Interface(erc20).balanceOf(this))>=items[_item].price);
if(items[_item].category==1)
items[_item].customer[_to] = 0;
else if(items[_item].category==2)
items[_item].customer[_to] = safeSub(items[_item].customer[_to],1 weeks);
else
items[_item].customer[_to] = safeSub(items[_item].customer[_to],1);
transfer(_to, erc20, items[_item].price);
_Wallet(_to).refund(erc20,_item,items[_item].price);
emit Refund(_to,_item,items[_item].price);
return true;
}
event Item(uint256 indexed _item, uint256 _price);
function resister(uint8 _category, uint256 _price, uint256 _stock) onlyOwner public returns (uint256 _itemId) {
require(_category>0&&_category<4);
require(_price>0);
items[index] = item(_category,_price,_stock);
index = safeAdd(index,1);
emit Item(index,_price);
return safeSub(index,1);
}
function update(uint256 _item, uint256 _price, uint256 _stock) onlyOwner public {
require(items[_item].category>0);
require(_price>0);
uint256 temp = items[_item].price;
items[_item].price = _price;
items[_item].stockCount = safeAdd(items[_item].stockCount,_stock);
if(temp!=items[_item].price)
emit Item(index,items[_item].price);
}
function price(uint256 _item) public constant returns (address _erc20, uint256 _value) {
return (erc20,items[_item].price);
}
function canBuy(address _who, uint256 _item) public constant returns (bool _canBuy) {
return (items[_item].category>0) &&
!(items[_item].category==1&&items[_item].customer[_who]>0) &&
(items[_item].stockCount>0);
}
function isBuyer(address _who, uint256 _item) public constant returns (bool _buyer) {
return (items[_item].category==1&&items[_item].customer[_who]>0)||(items[_item].category==2&&safeAdd(items[_item].customer[_who],1 weeks)>now)||(items[_item].category==3&&items[_item].customer[_who]>0);
}
uint lastWithdrawal;
function withdrawal(address _erc20, uint256 _value) onlyOwner public returns (bool success) {
require(safeAdd(lastWithdrawal,1 weeks)<=now);
require((_erc20==address(0)?address(this).balance:ERC20Interface(_erc20).balanceOf(this))>=_value);
if(_erc20==address(0))
owner.transfer(_value);
else
ERC20Interface(_erc20).transfer(owner,_value);
lastWithdrawal = now;
return true;
}
}
contract WalletCenter {
mapping(address=>bool) public wallet;
event Wallet(address indexed _owner, address indexed _wallet);
function createWallet() public returns (address _wallet) {
_wallet = new _Wallet(msg.sender);
wallet[_wallet] = true;
emit Wallet(msg.sender,_wallet);
return _wallet;
}
function isWallet(address _wallet) public constant returns (bool) {
return wallet[_wallet];
}
mapping(address=>bool) public shop;
event Shop(address indexed _owner, address indexed _shop, address indexed _erc20);
function createShop(address _erc20) public returns (address _shop) {
_shop = new _Shop(msg.sender,_erc20);
shop[_shop] = true;
emit Shop(msg.sender,_shop,_erc20);
return _shop;
}
function isShop(address _shop) public constant returns (bool) {
return shop[_shop];
}
}
```
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

164
EIPS/eip-1178.md Normal file
View File

@ -0,0 +1,164 @@
---
eip: 1178
title: Multi-class Token Standard
author: Albert Chon <achon@stanford.edu>
discussions-to: https://github.com/ethereum/EIPs/issues/1179
status: Draft
type: Standards Track
category: ERC
created: 2018-06-22
---
<!--You can leave these HTML comments in your merged EIP and delete the visible duplicate text guides, they will not appear and may be helpful to refer to if you edit it again. 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.-->
A standard interface for multi-class fungible tokens.
## Abstract
<!--A short (~200 word) description of the technical issue being addressed.-->
This standard allows for the implementation of a standard API for multi-class fungible tokens (henceforth referred to as "MCFTs") within smart contracts. This standard provides basic functionality to track and transfer ownership of MCFTs.
## 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.-->
Currently, there is no standard to support tokens that have multiple classes. In the real world, there are many situations in which defining distinct classes of the same token would be fitting (e.g. distinguishing between preferred/common/restricted shares of a company). Yet, such nuance cannot be supported in today's token standards. An ERC-20 token contract defines tokens that are all of one class while an ERC-721 token contract creates a class (defined by token_id) for each individual token. The ERC-1178 token standard proposes a new standard for creating multiple classes of tokens within one token contract.
> Aside: In theory, while it is possible to implement tokens with classes using the properties of token structs in ERC-721 tokens, gas costs of implementing this in practice are prohibitive for any non-trivial application.
## Specification
### ERC-20 Compatibility (partial)
**name**
```solidity
function name() constant returns (string name)
```
*OPTIONAL - It is recommended that this method is implemented for enhanced usability with wallets and exchanges, but interfaces and other contracts MUST NOT depend on the existence of this method.*
Returns the name of the aggregate collection of MCFTs managed by this contract. - e.g. `"My Company Tokens"`.
**class name**
```solidity
function className(uint256 classId) constant returns (string name)
```
*OPTIONAL - It is recommended that this method is implemented for enhanced usability with wallets and exchanges, but interfaces and other contracts MUST NOT depend on the existence of this method.*
Returns the name of the class of MCFT managed by this contract. - e.g. `"My Company Preferred Shares Token"`.
**symbol**
```solidity
function symbol() constant returns (string symbol)
```
*OPTIONAL - It is recommend that this method is implemented for enhanced usability with wallets and exchanges, but interfaces and other contracts MUST NOT depend on the existence of this method.*
Returns a short string symbol referencing the entire collection of MCFT managed in this contract. e.g. "MUL". This symbol SHOULD be short (3-8 characters is recommended), with no whitespace characters or new-lines and SHOULD be limited to the uppercase latin alphabet (i.e. the 26 letters used in English).
**totalSupply**
```solidity
function totalSupply() constant returns (uint256 totalSupply)
```
Returns the total number of all MCFTs currently tracked by this contract.
**individualSupply**
```solidity
function individualSupply(uint256 _classId) constant returns (uint256 individualSupply)
```
Returns the total number of MCFTs of class `_classId` currently tracked by this contract.
**balanceOf**
```solidity
function balanceOf(address _owner, uint256 _classId) constant returns (uint256 balance)
```
Returns the number of MCFTs of token class `_classId` assigned to address `_owner`.
**classesOwned**
```solidity
function classesOwned(address _owner) constant returns (uint256[] classes)
```
Returns an array of `_classId`'s of MCFTs that address `_owner` owns in the contract.
> NOTE: returning an array is supported by `pragma experimental ABIEncoderV2`
## Basic Ownership
**approve**
```solidity
function approve(address _to, uint256 _classId, uint256 quantity)
```
Grants approval for address `_to` to take possession `quantity` amount of the MCFT with ID `_classId`. This method MUST `throw` if `balanceOf(msg.sender, _classId) < quantity`, or if `_classId` does not represent an MCFT class currently tracked by this contract, or if `msg.sender == _to`.
Only one address can "have approval" at any given time for a given address and `_classId`. Calling `approve` with a new address and `_classId` revokes approval for the previous address and `_classId`. Calling this method with 0 as the `_to` argument clears approval for any address and the specified `_classId`.
Successful completion of this method MUST emit an `Approval` event (defined below) unless the caller is attempting to clear approval when there is no pending approval. In particular, an Approval event MUST be fired if the `_to` address is zero and there is some outstanding approval. Additionally, an Approval event MUST be fired if `_to` is already the currently approved address and this call otherwise has no effect. (i.e. An `approve()` call that "reaffirms" an existing approval MUST fire an event.)
<!--
ActionPrior State_to addressNew StateEventClear unset approvalClear0ClearNoneSet new approvalClearXSet to XApproval(owner, X, _classId)Change approvalSet to XYSet to YApproval(owner, Y, _classId)Reaffirm approvalSet to XXSet to XApproval(owner, X, _classId)Clear approvalSet to X0ClearApproval(owner, 0, _classId)
Note: ANY change of ownership of an MCFT whether directly through the `transfer` and `transferFrom` methods defined in this interface, or through any other mechanism defined in the conforming contract MUST clear any and all approvals for the transferred MCFT. The implicit clearing of approval via ownership transfer MUST also fire the event `Approval(0, _classId)` if there was an outstanding approval. (i.e. All actions that transfer ownership must emit the same Approval event, if any, as would emitted by calling `approve(0, _classId)`.)-->
**transfer**
```solidity
function transfer(address _to, uint256 _classId, uint256 quantity)
```
Assigns the ownership of `quantity` MCFT's with ID `_classId` to `_to` if and only if `quantity == balanceOf(msg.sender, _classId)`. A successful transfer MUST fire the `Transfer` event (defined below).
This method MUST transfer ownership to `_to` or `throw`, no other outcomes can be possible. Reasons for failure include (but are not limited to):
* `msg.sender` is not the owner of `quantity` amount of tokens of `_classId`'s.
* `_classId` does not represent an MCFT class currently tracked by this contract
A conforming contract MUST allow the current owner to "transfer" a token to themselves, as a way of affirming ownership in the event stream. (i.e. it is valid for `_to == msg.sender` if `balanceOf(msg.sender, _classId) >= balance`.) This "no-op transfer" MUST be considered a successful transfer, and therefore MUST fire a `Transfer` event (with the same address for `_from` and `_to`).
## Advanced Ownership and Exchange
```solidity
function approveForToken(uint256 classIdHeld, uint256 quantityHeld, uint256 classIdWanted, uint256 quantityWanted)
```
Allows holder of one token to allow another individual (or the smart contract itself) to approve the exchange of their tokens of one class for tokens of another class at their specified exchange rate (see sample implementation for more details). This is equivalent to posting a bid in a marketplace.
```solidity
function exchange(address to, uint256 classIdPosted, uint256 quantityPosted, uint256 classIdWanted, uint256 quantityWanted)
```
Allows an individual to fill an existing bid (see above function) and complete the exchange of their tokens of one class for another. In the sample implementation, this function call should fail unless the callee has already approved the contract to transfer their tokens. Of course, it is possible to create an implementation where calling this function implicitly assumes approval and the transfer is completed in one step.
```solidity
transferFrom(address from, address to, uint256 classId)
```
Allows a third party to initiate a transfer of tokens from `from` to `to` assuming the approvals have been granted.
## Events
**Transfer**
This event MUST trigger when MCFT ownership is transferred via any mechanism.
Additionally, the creation of new MCFTs MUST trigger a Transfer event for each newly created MCFTs, with a `_from` address of 0 and a `_to` address matching the owner of the new MCFT (possibly the smart contract itself). The deletion (or burn) of any MCFT MUST trigger a Transfer event with a `_to` address of 0 and a `_from` address of the owner of the MCFT (now former owner!).
NOTE: A Transfer event with `_from == _to` is valid. See the `transfer()` documentation for details.
```solidity
event Transfer(address indexed _from, address indexed _to, uint256 _classId)
```
**Approval**
This event MUST trigger on any successful call to `approve(_to, _classId, quantity)` (unless the caller is attempting to clear approval when there is no pending approval).
```solidity
event Approval(address indexed _owner, address indexed _approved, uint256 _classId)
```
## 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.-->
### Current Limitations
The design of this project was motivated when I tried to create different classes of fungible ERC-721 tokens (an oxymoron) but ran into gas limits from having to create each tokens individually and maintain them in an efficient data structure for access. Using the maximum gas amount one can send with a transaction on Metamask (a popular web wallet), I was only able to create around 46 ERC-721 tokens before exhausting all gas. This experience motivated the creation of the multi-class fungible token standard.
## 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.-->
Adoption of the MCFT standard proposal would not pose backwards compatibility issues as it defines a new standard for token creation. This standard follows the semantics of ERC-721 as closely as possible, but can't be entirely compatible with it due to the fundamental differences between multi-class fungible and non-fungible tokens. For example, the `ownerOf`, `takeOwnership`, and `tokenOfOwnerByIndex` methods in the ERC-721 token standard cannot be implemented in this standard. Furthermore, the function arguments to `balanceOf`, `approve`, and `transfer` differ as well.
## 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.-->
A sample implementation can be found [here](https://github.com/achon22/ERC-1178/blob/master/erc1178-sample.sol)
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

97
EIPS/eip-1191.md Normal file
View File

@ -0,0 +1,97 @@
---
eip: 1191
title: Add chain id to mixed-case checksum address encoding
author: Juliano Rizzo (@juli)
status: Draft
type: Standards Track
category: ERC
created: 2018-03-18
requires: 55, 155
discussions-to: https://github.com/ethereum/EIPs/issues/1121
---
## Simple Summary
This EIP extends EIP-55 by optionally adding a chain id defined by EIP-155 to the checksum calculation.
## Specification
Convert the address using the same algorithm defined by EIP-55 but if a registered chain id is provided, add it to the input of the hash function. If the chain id passed to the function belongs to a network that opted for using this checksum variant, prefix the address with the chain id and the `0x` separator before calculating the hash. Then convert the address to hexadecimal, but if the ith digit is a letter (ie. it's one of `abcdef`) print it in uppercase if the 4*ith bit of the calculated hash is 1 otherwise print it in lowercase.
## Rationale
Benefits:
- By means of a minimal code change on existing libraries, users are protected from losing funds by mixing addresses of different Ethereum based networks.
## Backwards Compatibility
This proposal is fully backward compatible. The checksum calculation is changed only for new networks that choose to adopt this EIP and add their chain numbers to the Adoption Table included in this document.
## Implementation
```python
#!/usr/bin/python3
from sha3 import keccak_256
import random
"""
addr (str): Hexadecimal address, 40 characters long with 2 characters prefix
chainid (int): chain id from EIP-155 """
def eth_checksum_encode(addr, chainid=1):
adopted_eip1191 = [30, 31]
hash_input = str(chainid) + addr.lower() if chainid in adopted_eip1191 else addr[2:].lower()
hash_output = keccak_256(hash_input.encode('utf8')).hexdigest()
aggregate = zip(addr[2:].lower(),hash_output)
out = addr[:2] + ''.join([c.upper() if int(a,16) >= 8 else c for c,a in aggregate])
return out
```
## Test Cases
```python
eth_mainnet= [
'0x88021160C5C792225E4E5452585947470010289D',
'0x27b1fdb04752bbc536007a920d24acb045561c26',
'0x52908400098527886E0F7030069857D2E4169EE7',
'0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed',
'0x8617E340B3D01FA5F11F306F4090FD50E238070D',
'0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb',
'0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB',
'0xde709f2102306220921060314715629080e2fb77',
'0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359',
]
rsk_mainnet = [
'0x6549F4939460DE12611948B3F82B88C3C8975323',
'0x27b1FdB04752BBc536007A920D24ACB045561c26',
'0x3599689E6292B81B2D85451025146515070129Bb',
'0x52908400098527886E0F7030069857D2E4169ee7',
'0x5aaEB6053f3e94c9b9a09f33669435E7ef1bEAeD',
'0x8617E340b3D01Fa5f11f306f4090fd50E238070D',
'0xD1220A0Cf47c7B9BE7a2e6ba89F429762E7B9adB',
'0xDBF03B407c01E7CD3cBea99509D93F8Dddc8C6FB',
'0xDe709F2102306220921060314715629080e2FB77',
'0xFb6916095cA1Df60bb79ce92cE3EA74c37c5d359',
]
rsk_testnet= [
'0x42712D45473476B98452F434E72461577D686318',
'0x27B1FdB04752BbC536007a920D24acB045561C26',
'0x3599689e6292b81b2D85451025146515070129Bb',
'0x52908400098527886E0F7030069857D2e4169EE7',
'0x5aAeb6053F3e94c9b9A09F33669435E7EF1BEaEd',
'0x66f9664F97F2b50f62d13eA064982F936DE76657',
'0x8617e340b3D01fa5F11f306F4090Fd50e238070d',
'0xDE709F2102306220921060314715629080e2Fb77',
'0xFb6916095CA1dF60bb79CE92ce3Ea74C37c5D359',
'0xd1220a0CF47c7B9Be7A2E6Ba89f429762E7b9adB',
'0xdbF03B407C01E7cd3cbEa99509D93f8dDDc8C6fB',
]
test_cases = {30 : rsk_mainnet, 31 : rsk_testnet, 1 : eth_mainnet}
for chainid, cases in test_cases.items():
for addr in cases:
assert ( addr == eth_checksum_encode(addr,chainid) )
```
## Adoption
### Adoption Table
| Network | Chain id | Supports this EIP |
|--------------|----------|-------------------|
| RSK Mainnet | 30 | Yes |
| RSK Testnet | 31 | Yes |
| Wallet | Implements this EIP|
|--------------|--------------------|
| MyCrypto | In progress |
| Ledger | In progress |
| Trezor | In progress |

499
EIPS/eip-1193.md Normal file
View File

@ -0,0 +1,499 @@
---
eip: 1193
title: Ethereum Provider JavaScript API
author: Ryan Ghods (@ryanio), Marc Garreau (@marcgarreau)
discussions-to: https://ethereum-magicians.org/t/eip-1193-ethereum-provider-javascript-api/640
status: Draft
type: Standards Track
category: Interface
created: 2018-06-30
requires: 1102
---
## Summary
This EIP formalizes an Ethereum Provider JavaScript API for consistency across clients and applications.
The provider is designed to be minimal, containing 4 methods: `enable`, `send`, `subscribe`, and `unsubscribe`. It emits 4 types of events: `connect`, `close`, `networkChanged`, and `accountsChanged`.
It is intended to be available on `window.ethereum`.
## API
### Enable
By default a "read-only" provider is supplied to allow access to the blockchain while preserving user privacy.
A full provider can be requested to allow account-level methods:
```js
ethereum.enable(): Promise<[String]>;
```
Promise resolves with an array of the accounts' public keys, or rejects with `Error`.
### Send
Ethereum API methods can be sent and received:
```js
ethereum.send(method: String, params?: Array<any>): Promise<any>;
```
Promise resolves with `result` or rejects with `Error`.
See the [available methods](https://github.com/ethereum/wiki/wiki/JSON-RPC#json-rpc-methods).
### Subscriptions
#### Subscribe
```js
ethereum.subscribe(subscriptionType: String, params?: Array<any>): Promise<String>;
```
Promise resolves with `subscriptionId: String` or rejects with `Error`.
See the [types of subscriptions](https://github.com/ethereum/go-ethereum/wiki/RPC-PUB-SUB#supported-subscriptions).
Results emit on `subscriptionId` using [EventEmitter](https://nodejs.org/api/events.html). Attach listeners with:
```js
ethereum.on(subscriptionId, listener: (result: any) => void): this;
```
The event emits with `result`, the subscription `result` or an `Error` object.
#### Unsubscribe
```js
ethereum.unsubscribe(subscriptionId: String): Promise<Boolean>;
```
Promise resolves with `success: Boolean` or rejects with `Error`.
All [EventEmitter](https://nodejs.org/api/events.html) listeners on `subscriptionId` will also be removed.
### Events
Events are emitted using [EventEmitter](https://nodejs.org/api/events.html).
#### connect
The provider emits `connect` on connect to a network.
```js
ethereum.on('connect', listener: () => void): this;
```
You can detect which network by sending `net_version`:
```js
const network = await ethereum.send('net_version');
> '1'
```
#### close
The provider emits `close` on disconnect from a network.
```js
ethereum.on('close', listener: (code: Number, reason: String) => void): this;
```
The event emits with `code` and `reason`. The code follows the table of [`CloseEvent` status codes](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes).
#### networkChanged
The provider emits `networkChanged` on connect to a new network.
```js
ethereum.on('networkChanged', listener: (networkId: String) => void): this;
```
The event emits with `networkId`, the new network returned from `net_version`.
#### accountsChanged
The provider emits `accountsChanged` if the accounts returned from the provider (`eth_accounts`) changes.
```js
ethereum.on('accountsChanged', listener: (accounts: Array<String>) => void): this;
```
The event emits with `accounts`, an array of the accounts' public keys.
### Constructor
```js
ethereum.constructor.name;
> 'EthereumProvider'
```
## Examples
```js
const ethereum = window.ethereum;
// A) Primary use case - set provider in web3.js
web3.setProvider(ethereum);
// B) Secondary use case - use provider object directly
// Example 1: Log last block
ethereum
.send('eth_getBlockByNumber', ['latest', 'true'])
.then(block => {
console.log(`Block ${block.number}:\n${block}`);
})
.catch(error => {
console.error(
`Error fetching last block: ${error.message}.
Code: ${error.code}. Data: ${error.data}`
);
});
// Example 2: Enable full provider
ethereum
.enable()
.then(accounts => {
console.log(`Enabled accounts:\n${accounts.join('\n')}`);
})
.catch(error => {
console.error(
`Error enabling provider: ${error.message}.
Code: ${error.code}. Data: ${error.data}`
);
});
// Example 3: Log available accounts
ethereum
.send('eth_accounts')
.then(accounts => {
console.log(`Accounts:\n${accounts.join('\n')}`);
})
.catch(error => {
console.error(
`Error fetching accounts: ${error.message}.
Code: ${error.code}. Data: ${error.data}`
);
});
}
// Example 4: Log new blocks
let subId;
ethereum
.subscribe('newHeads')
.then(subscriptionId => {
subId = subscriptionId;
ethereum.on(subscriptionId, block => {
if (result instanceOf Error) {
const error = result;
console.error(
`Error from newHeads subscription: ${error.message}.
Code: ${error.code}. Data: ${error.data}`
);
} else {
console.log(`New block ${block.number}:\n${block}`);
}
});
})
.catch(error => {
console.error(
`Error making newHeads subscription: ${error.message}.
Code: ${error.code}. Data: ${error.data}`
);
});
// to unsubscribe
ethereum
.unsubscribe(subId)
.then(result => {
console.log(`Unsubscribed newHeads subscription ${subscriptionId}`);
})
.catch(error => {
console.error(
`Error unsubscribing newHeads subscription: ${error.message}.
Code: ${error.code}. Data: ${error.data}`
);
});
// Example 5: Log when accounts change
const logAccounts = accounts => {
console.log(`Accounts:\n${accounts.join('\n')}`);
};
ethereum.on('accountsChanged', logAccounts);
// to unsubscribe
ethereum.removeListener('accountsChanged', logAccounts);
// Example 6: Log if connection ends
ethereum.on('close', (code, reason) => {
console.log(
`Ethereum provider connection closed: ${reason}. Code: ${code}`
);
});
```
## Specification
### Enable
The provider supplied to a new dapp **MUST** be a "read-only" provider: authenticating no accounts by default, returning a blank array for `eth_accounts`, and rejecting any methods that require an account.
If the dapp has been previously authenticated and remembered by the user, then the provider supplied on load **MAY** automatically be enabled with the previously authenticated accounts.
If no accounts are authenticated, the `enable` method **MUST** ask the user which account(s) they would like to authenticate to the dapp. If the request has been previously granted and remembered, the `enable` method **MAY** immediately return with the prior remembered accounts and permissions.
The `enable` method **MUST** return a Promise, resolving with an array of the accounts' public keys, or rejecting with an `Error`. If the accounts enabled by provider change, the `accountsChanged` event **MUST** also emit.
### Send
The `send` method **MUST** send a properly formatted [JSON-RPC request](https://www.jsonrpc.org/specification#request_object).
If the Ethereum JSON-RPC API returns a response object with no error, then the Promise **MUST** resolve with the `response.result` object untouched by the implementing Ethereum Provider.
If the Ethereum JSON-RPC API returns response object that contains an error property then the Promise **MUST** reject with an Error object containing the `response.error.message` as the Error message, `response.error.code` as a code property on the error and `response.error.data` as a data property on the error.
If an error occurs during processing, such as an HTTP error or internal parsing error, then the Promise **MUST** reject with an `Error` object.
If the implementing Ethereum Provider is not talking to an external Ethereum JSON-RPC API provider then it **MUST** resolve with an object that matches the JSON-RPC API object as specified in the [Ethereum JSON-RPC documentation](https://github.com/ethereum/wiki/wiki/JSON-RPC).
If the JSON-RPC request requires an account that is not yet authenticated, the Promise **MUST** reject with an `Error`.
### Subscriptions
The `subscribe` method **MUST** send a properly formatted [JSON-RPC request](https://www.jsonrpc.org/specification#request_object) with method `eth_subscribe` and params `[subscriptionType: String, {...params: Array<any>}]` and **MUST** return a Promise that resolves with `subscriptionId: String` or rejected with an Error object.
The `unsubscribe` method **MUST** send a properly formatted [JSON-RPC request](https://www.jsonrpc.org/specification#request_object) with method `eth_unsubscribe` and params `[subscriptionId: String]` and **MUST** return a Promise that resolves with `result: Boolean` or rejected with an Error object.
If the `unsubscribe` method returns successfully with a `True` result, the implementing provider **MUST** remove all listeners on the `subscriptionId` using `ethereum.removeAllListeners(subscriptionId);`.
If an error occurs during processing of the subscription, such as an HTTP error or internal parsing error then the Promise **MUST** return with an Error object.
The implementing Ethereum Provider **MUST** emit every subscription response `result` with the eventName `subscriptionId`.
If an error occurs or the network changes during the listening of the subscription, the Ethereum Provider **MUST** emit an Error object to the eventName `subscriptionId`.
If the implementing provider does not support subscriptions, then it **MUST** leave the `subscribe` and `unsubscribe` methods undefined.
### Events
If the network connects, the Ethereum Provider **MUST** emit an event named `connect`.
If the network connection closes, the Ethereum Provider **MUST** emit an event named `close` with args `code: Number, reason: String` following the [status codes for `CloseEvent`](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes).
If the network the provider is connected to changes, the provider **MUST** emit an event named `networkChanged` with args `networkId: String` containing the ID of the new network (using the Ethereum JSON-RPC call `net_version`).
If the accounts connected to the Ethereum Provider change, the Ethereum Provider **MUST** send an event with the name `accountsChanged` with args `accounts: Array<String>` containing the accounts' public key(s).
### Class
The name of the constructor of the Ethereum Provider **MUST** be `EthereumProvider`.
### web3.js Provider
The implementing Ethereum Provider **MUST** be compatible as a `web3.js` provider. This is accomplished by providing two methods in the `EthereumProvider`: `sendAsync(payload: Object, callback: (error: any, result: any) => void): void` and `isConnected(): Boolean`.
### Error object and codes
If an Error object is returned, it **MUST** contain a human readable string message describing the error and **SHOULD** populate the `code` and `data` properties on the error object with additional error details.
Appropriate error codes **SHOULD** follow the table of [`CloseEvent` status codes](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes), along with the following table:
| Status code | Name | Description |
| ----------- | ------------------------- | -------------------------------------------------------------------------------------------------------------- |
| 4001 | User Denied Full Provider | User denied the enabling of the full Ethereum Provider by choosing not to authorize any accounts for the dapp. |
| | | |
| | | |
## Sample Class Implementation
```js
class EthereumProvider extends EventEmitter {
constructor() {
// Call super for `this` to be defined
super();
// Init storage
this._isConnected = false;
this._nextJsonrpcId = 0;
this._promises = {};
this._activeSubscriptions = [];
// Fire the connect
this._connect();
// Listen for jsonrpc responses
window.addEventListener('message', this._handleJsonrpcMessage.bind(this));
}
/* Methods */
enable() {
return new Promise((resolve, reject) => {
window.mist
.requestAccounts()
.then(resolve)
.catch(reject);
});
}
send(method, params = []) {
if (!method || typeof method !== 'string') {
return new Error('Method is not a valid string.');
}
if (!(params instanceof Array)) {
return new Error('Params is not a valid array.');
}
const id = this._nextJsonrpcId++;
const jsonrpc = '2.0';
const payload = { jsonrpc, id, method, params };
const promise = new Promise((resolve, reject) => {
this._promises[payload.id] = { resolve, reject };
});
// Send jsonrpc request to Mist
window.postMessage(
{ type: 'mistAPI_ethereum_provider_write', message: payload },
origin
);
return promise;
}
subscribe(subscriptionType, params) {
return this.send('eth_subscribe', [subscriptionType, ...params]).then(
subscriptionId => {
this._activeSubscriptions.push(subscriptionId);
}
);
}
unsubscribe(subscriptionId) {
return this.send('eth_unsubscribe', [subscriptionId]).then(success => {
if (success) {
// Remove subscription
this._activeSubscription = this._activeSubscription.filter(
id => id !== subscriptionId
);
// Remove listeners on subscriptionId
this.removeAllListeners(subscriptionId);
}
});
}
/* Internal methods */
_handleJsonrpcMessage(event) {
// Return if no data to parse
if (!event || !event.data) {
return;
}
let data;
try {
data = JSON.parse(event.data);
} catch (error) {
// Return if we can't parse a valid object
return;
}
// Return if not a jsonrpc response
if (!data || !data.message || !data.message.jsonrpc) {
return;
}
const message = data.message;
const { id, method, error, result } = message;
if (typeof id !== 'undefined') {
const promise = this._promises[id];
if (promise) {
// Handle pending promise
if (data.type === 'error') {
promise.reject(message);
} else if (message.error) {
promise.reject(error);
} else {
promise.resolve(result);
}
delete this._promises[id];
}
} else {
if (method && method.indexOf('_subscription') > -1) {
// Emit subscription result
const { subscription, result } = message.params;
this.emit(subscription, result);
}
}
}
/* Connection handling */
_connect() {
// Send to Mist
window.postMessage({ type: 'mistAPI_ethereum_provider_connect' }, origin);
// Reconnect on close
this.once('close', this._connect.bind(this));
}
/* Events */
_emitConnect() {
this._isConnected = true;
this.emit('connect');
}
_emitClose(code, reason) {
this._isConnected = false;
this.emit('close', code, reason);
// Send Error objects to any open subscriptions
this._activeSubscriptions.forEach(id => {
const error = new Error(
`Provider connection to network closed.
Subscription lost, please subscribe again.`
);
this.emit(id, error);
});
// Clear subscriptions
this._activeSubscriptions = [];
}
_emitNetworkChanged(networkId) {
this.emit('networkChanged', networkId);
}
_emitAccountsChanged(accounts) {
this.emit('accountsChanged', accounts);
}
/* web3.js provider compatibility */
sendAsync(payload, callback) {
return this.send(payload.method, payload.params)
.then(result => {
const response = payload;
response.result = result;
callback(null, response);
})
.catch(error => {
callback(error, null);
// eslint-disable-next-line no-console
console.error(
`Error from EthereumProvider sendAsync ${payload}: ${error}`
);
});
}
isConnected() {
return this._isConnected;
}
}
```
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

296
EIPS/eip-1202.md Normal file
View File

@ -0,0 +1,296 @@
---
eip: 1202
title: Voting Standard
author: Zainan Victor Zhou (@xinbenlv), Evan (@evbots), Yin Xu (@yingogobot)
type: Standards Track
category: ERC
status: Draft
created: 2018-07-08
discussions-to: https://github.com/ethereum/EIPs/issues/1202
---
## Note to Readers
1. We are still open to have co-author to collaborate, in particular, we are looking for co-authors of the
following category:
- standard designers who are experienced in application-layer standard design, or
- developers who have experience with blockchain-based voting system in practice
- researchers with research interest in crypto/zero-knowledge-proof voting
2. We have two discussion destinations:
- [Github Ethereum EIP Issue #1202](https://github.com/ethereum/EIPs/issues/1202) for long and more mature thoughts
- [Telegram Channel t.me/erc1202](https://t.me/erc1202) for real-time and related random chat.
3. We are actively working on updating this draft as many feedbacks have come in since it merged into official EIP repo.
If you are viewing a snapshot of this draft, please be adviced the latest dev version of ERC 1202 can be found [here](https://github.com/xinbenlv/eip-1202-draft/blob/master/EIP-1202.md)
## Simple Summary
Propose a standard interface for voting.
## Abstract
This proposal creates a standard API for implementing voting within smart contract. This standard provides functionalities to voting as well as to view the vote result and set voting status.
## Motivation
Voting is one of the earliest example of EVM programming, and also a key to DAO/organizational governance process. We foresee many DAOs will ultimately need to leverage voting as one of the important part of their governance. By creating a voting standard for smart contract / token, we can have the following benefits
### Benefits
1. Allow general UI and applications to be built on top of a standardized voting to allow more general user to participate, and encourage more DApp and DAO to think about their governance
2. Allow delegate voting / smart contract voting, automatic voting
3. Allow voting results to be recorded on-chain, in a standard way, and allow DAOs and DApps to honor the voting result programmatically.
4. Allow the compatibility with token standard such as [ERC-20](https://eips.ethereum.org/EIPS/eip-20) or other new standards([EIP-777](https://eips.ethereum.org/EIPS/eip-777)) and item standard such as [EIP-721](https://eips.ethereum.org/EIPS/eip-721)
5. Create massive potential for interoperability within Ethereum echo systems and other system.
6. Allow setting voting deadline, allow determine on single or multiple options. Allow requiring voting orders. (trade-off is interface complexity, we might need [ERC-20](https://eips.ethereum.org/EIPS/eip-20) approach and later a [EIP-777](https://eips.ethereum.org/EIPS/eip-777) for advanced voting)
7. Recording the voting with weights with token amount.
8. Possibly allow trust-worthy privacy-safe voting and anonymous voting (with either voter address being un-associated with the vote they cast, given a list of randomized/obfuscated voting options).
8
9. Possibly allow result in reward by voting partitipation or voting result
### Use-cases:
1. Determine on issuing new token, issuing more token or issuing sub-token
2. Determine on creating new item under [EIP-721](https://eips.ethereum.org/EIPS/eip-721)
3. Determine on election on certain person or smart contract to be delegated leader for project or subproject
4. Determine on auditing result ownership allowing migration of smart contract proxy address
## Specifications
### Simple Version
The simple version of specification makes the assumption that each smart contract voting standard is: *Single Issue*, *Single Selection* and *Single Outcome*
```solidity
pragma solidity ^0.4.22;
/**
* - Single issue
* - Single selection
*
* Discussion:
* 1. Each address has a weight determined by other input decided by the actual implementation
* which is suggested to be set upon the initialization
* 2. Is there certain naming convention to follow?
*/
interface ERC1202 {
// Vote with an option. The caller needs to handle success or not
function vote(uint option) external returns (bool success);
function setStatus(bool isOpen) external returns (bool success);
function issueDescription() external view returns (string desc);
function availableOptions() external view returns (uint[] options);
function optionDescription(uint option) external view returns (string desc);
function ballotOf(address addr) external view returns (uint option);
function weightOf(address addr) external view returns (uint weight);
function getStatus() external view returns (bool isOpen);
function weightedVoteCountsOf(uint option) external view returns (uint count);
function winningOption() external view returns (uint option);
event OnVote(address indexed _from, uint _value);
event OnStatusChange(bool newIsOpen);
}
```
### Advanced Version
```solidity
pragma solidity ^0.4.22;
/**
* - Multiple issue
* - Multiple selection
* - Ordered multiple result
* Discussion:
* 1. Each address has a weight determined by other input decided by the actual implementation
* which is suggested to be set upon the initialization
* 2. Is there certain naming convention to follow?
*/
contract AdvancedERC1202 {
// Vote with an option. The caller needs to handle success or not
function vote(uint issueId, uint option) public returns (bool success);
function setStatus(uint issueId, bool isOpen) public returns (bool success);
function issueDescription(uint issueId) public view returns (string desc);
function availableOptions(uint issueId) public view returns (uint[] options);
function optionDescription(uint issueId, uint option) public view returns (string desc);
function ballotOf(uint issueId, address addr) public view returns (uint option);
function weightOf(uint issueId, address addr) public view returns (uint weight);
function getStatus(uint issueId) public view returns (bool isOpen);
function weightedVoteCountsOf(uint issueId, uint option) public view returns (uint count);
function topOptions(uint issueId, uint limit) public view returns (uint[] topOptions_);
event OnVote(uint issueId, address indexed _from, uint _value);
event OnStatusChange(uint issueId, bool newIsOpen);
}
```
## Rationale
We made the following design decisions and here are the rationales.
- **Granularity and Anonymity:**: We created a `view` function `ballotOf` primarily making it easier for people to check the vote from certain address. This has the following assumptions:
* It's possible to check someone's vote directly given an address. If implementor don't want to make it so easiy, they can simply reject all calls to this function. We want to make sure that we support both anonymous voting an non-anonymous voting. However since all calls to a smart contract is logged in block history, there is really no secrecy unless done with cryptography tricks. I am not cryptography-savvy enough to comment on the possibility. Please see "Second Feedback Questions 2018" for related topic.
* It's assumes for each individual address, they can only vote for one decision. They can distribute their available voting power into more granular level. If implementor wants allow this, they ask the user to create another wallet address and grant the new address certain power. For example, a token based voting where voting weight is determined by the amount of token held by a voter, a voter who wants to distribute its voting power in two different option(option set) can transfer some of the tokens to the new account and cast the votes from both accounts.
- **Weight**: We assume there are `weight` of votes and can be checked by calling `weightOf(address addr)`, and the weight distribution is either internally determined or determined by constructor. However we have not been considering updating the weight distribution. Please comment on this design decision as we want to learn how likely an implementor would want to be able to update the voting weight distributions.
### Security and Privacy of Voting
// TODO
## Backward Compatibility
There is no backward compatibility issue we are aware of.
## Interactions with other ERCs
// TODO add interaction discussion for the following ERCs
ERC20, ERC721, ERC735, ERC780, ERC165
## Simple Code Examples
### Example 1: Simplest Version: Single Issue Yes/No Question Per Smart Contract Address Per Non-Weighted Vote
- [Source Code](https://github.com/xinbenlv/eip-1202-draft/blob/master/contracts/simple-version/SimplestVote1202.sol)
- [Deployment (Ropsten)](https://ropsten.etherscan.io/address/0x067e76ddd9c67f7ae606b18d881545512d4b680c#code)
### Example 2: TokenVote with Simple Interface with Weight Assigned by Token and Pre-registered Snapshot of Token-Holders
- [Source Code](https://github.com/xinbenlv/eip-1202-draft/blob/master/contracts/simple-version/TokenVote1202.sol)
- [Deployment (Ropsten)](https://ropsten.etherscan.io/address/0x5bd007a224fe8820b19cc0bce8e241f4752ce74d#code)
### Example 3: TokenVote with Advanced Interface
- [Source Code](https://github.com/xinbenlv/eip-1202-draft/blob/master/contracts/advanced-version/AdvancedTokenVote1202.sol)
- [Deployment (Ropsten)](https://ropsten.etherscan.io/address/0xfd8b3be5f9db4662d1c9269f948345b46e37fd26#code)
## Comprehensive Application Examples
### Example 1: Joint Wallet Account Spending Approval
// TODO
### Example 2: Secret Vote
// TODO
### Example 3: Token Re-issue
// TODO
### Example 4: Multi-input Oracle
// TODO
## Case Study
### Existing Voting Systems in Blockchain World
// TODO
#### Carbon Vote
// TODO
#### PLACE Voting
https://medium.com/@jameson.quinn/how-place-voting-works-617a5e8ac422
#### PLCR Voting
[PLCR Voting: ](https://github.com/ConsenSys/PLCRVoting)
https://medium.com/metax-publication/a-walkthrough-of-plcr-voting-in-solidity-92420bd5b87c
####
### Exiting Voting Systems in Real World
// TODO
#### Simple Majority Vote Requiring Quorum (e.g. Company Board)
// TODO, and a small variant: ZaiGeZaiGu function committee approval (1/2 as quorum, majority vote)
#### Two-tiered Shareholder Vote (e.g. GOOG, FB)
// TODO
#### Jury Decision of US Federal Criminal Court (All Ayle for Guity, 5/5 for Tie)
// TODO
#### US Presidential Election: Different Vote Time, Multi-Reginal, Two-level (General and Editorial(delegate))
// TODO
#### Super-Girl China 2005: Idol Ranking Vote, Multiple Votes Allowed
// TODO
## Summary of Discussions
### Early Feedback Questions (2018-07-08)
Here are a few early questions I'd like to ask people here.
1. Have we had any duplicated EIPs that I overlooked. If not, have anyone attempted to do so, and why it did not continue to exist?
**Answer**: We concluded there is no duplicated efforts working on creating a voting standard.
2. Should each issue have its own smart contract address (like individual item on [EIP-721](https://eips.ethereum.org/EIPS/eip-721)) or should it support multiple items in [EIP-1155](https://eips.ethereum.org/EIPS/eip-1155), or should it support multi-class voting in [EIP-1178](https://eips.ethereum.org/EIPS/eip-1178), [EIP-1203](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1203.md) (e.g. certain issue can override another issue)
**Answer**: We will provide examples of both and seek comments.
3. Should the voting support proxy(e.g [EIP-897](https://eips.ethereum.org/EIPS/eip-897), [EIP-1167](https://eips.ethereum.org/EIPS/eip-1167)) and migration? What are potential security concerns
**Answer**: It shall not be determined by this ERC.
4. Should it be proposed in a single phase standard or multiple separate into multiple phase, with earlier phase supporting easiest and simplest interface, and later phase supporting more advanced interfaces? (I intuitively believe it will be the latter, but not sure if it might be possible to do it all-at once.)
**Answer**: It will unavoidably require upgrade in the future, but supporting multiple issue multiple options will be good enough so far.
1. Should it support or optionally support [EIP-165](https://eips.ethereum.org/EIPS/eip-165)? For public voting, support EIP-165 make it easier to discover, but for secret voting people might not want to disclose a voting for certain issue even exist.
**Answer**: It shall not be determined by this ERC.
### Second Feedback Questions 2018-07-19
1. Is it technically possible to achieve anonymous voting on current Ethereum/EVM setup, is it possible that people either hide their identity, or hide what selection they made in a vote given that for a smart contract the public states are visible from block history directly, and internal private state can be replied in any fullnode?
2. number byte length: for simplicity we are using `uint` anywhere undecided. We need to decided what number byte length should we use for `weights` and `options`.
## Bibliography
### Related EIPs
- [EIP-20: ERC-20 Token Standard (a.k.a. ERC-20)](https://eips.ethereum.org/EIPS/eip-20)
- [EIP-165: Standard Interface Detection](https://eips.ethereum.org/EIPS/eip-165)
- [EIP-721: Non-Fungible Token Standard(a.k.a. ERC-721)](https://eips.ethereum.org/EIPS/eip-721)
- [EIP-735: ERC: Claim Holder](https://github.com/ethereum/EIPs/issues/735)
- [EIP-780: ERC: Ethereum Claims Registry](https://github.com/ethereum/EIPs/issues/780)
- [EIP-777: A New Advanced Token Standard](https://eips.ethereum.org/EIPS/eip-777)
- [EIP-897: ERC DelegateProxy](https://eips.ethereum.org/EIPS/eip-897)
- [EIP-1155: Crypto Item Standard](https://eips.ethereum.org/EIPS/eip-1155)
- [EIP-1178: Multi-class Token Standard](https://eips.ethereum.org/EIPS/eip-1178)
- [EIP-1167: Minimal Proxy Contract](https://eips.ethereum.org/EIPS/eip-1167)
- [EIP-1203: Multi-class Token Standard(ERC-20 Extension)](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1203.md)
### Worthnoting Projects
- [Ethereum DAO: How to build a DEMOCRACY on the blockchain](https://www.ethereum.org/dao)
- [Carbon Vote](http://carbonvote.com/)
- [Paper: A Smart Contract for Boardroom Voting with Maximum Voter Privacy](https://eprint.iacr.org/2017/110.pdf) - *Suggested by @aodhgan*
- [Private Voting for TCR](https://blog.enigma.co/private-voting-for-tcrs-with-enigma-b441b5d4fa7b)
### Worthnoting Academic Papers
## Request for Comment
We kindly request the community for comments, in particular, the following ERC and projects related authors:
- ERC-20: @frozeman, @vbuterin
- ERC-721: @fulldecent, Dieter Shirley, Jacob Evans, Nastassia Sachs
- Carbon Vote: @lgn21st, @Aaaaaashu
- Alex Van de Sande (Mist) and Nick Johnson (ENS) * - suggested by Fabian (@frozeman)*
- Will Warren, 0xProject a project who cares a lot about governance. * - nominated by Evan()@evanbots)*
Your comments and suggestions will be greatly appreciated.
## Acknowledgement
The authors of EIP 1202 greatly appreciate the valuable input from distinguished community members including: @frozeman, @fulldecent, @bingen, @aodhgan.
## EIP Work Logs
- 2018-07-08: (@xinbenlv) Created early feedback request. Asked around discussion channels suggested in [EIP-1](https://eips.ethereum.org/EIPS/eip-1), such as [Ethereum-Magicians](https://ethereum-magicians.org/t/eip-x-voting-standard-early-feedback-wanted/670/2), [Gitter](https://gitter.im/ethereum/EIPs), [Reddit](https://www.reddit.com/r/ethereum/comments/8x6k11/early_feedback_request_for_eipx_voting_standard/)
- 2018-07-09: (@xinbenlv)Added examples outline. Request for co-author.
- 2018-07-17: (@xinbenlv)Added co-author. @evbots, added two simple examples.
- 2018-07-19: (@xinbenlv)Added interface-like specification. Moved content from [issue](https://github.com/ethereum/EIPs/issues/1202) to [xinbenlv's Github repo](https://github.com/xinbenlv/eip-1202-draft/blob/master/EIP-1202.md) . Added TokenVote example.
- 2018-07-20: (@xinbenlv)Added advanced token vote example.
- 2018-07-22: (@xinbenlv)Moved official discussion thread from [github issue](https://github.com/ethereum/EIPs/issues/1202) to [ethereum-magicians](https://ethereum-magicians.org/t/erc-1202-voting-standard-official-discussion-thread/670) - moved back as it's ok to use GitHub issue as official discussion thread.
- 2018-07-23: (@xinbenlv)
- added co-author Yin Xu (@yingogobot)
- added outline for a few applications and case studies for further drafting.
- added citation of ERC-735 and ERC-780
- 2018-07-25: (@xinbenlv) Added input from @fulldecent, @bingen, @aodhgan to mention the privacy casting, PLCR etc, and
added placeholders for related session.
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

230
EIPS/eip-1203.md Normal file
View File

@ -0,0 +1,230 @@
---
eip: 1203
title: ERC-1203 Multi-Class Token Standard (ERC-20 Extension)
author: Jeff Huang <jeffishjeff@gmail.com>, Min Zu <crawlregister@gmail.com>
discussions-to: https://github.com/ethereum/EIPs/issues/1203
status: Draft
type: Standards Track
category: ERC
created: 2018-07-01
---
## Simple Summary
A standard interface for multi-class tokens (MCTs).
## Abstract
The following standard allows for the implementation of a standard API for MCTs within smart contracts. This standard provides basic functionality to track, transfer, and convert MCTs.
## Motivation
This standard is heavily inspired by ERC-20 Token Standard and ERC-721 Non-Fungible Token Standard. However, whereas these standards are chiefly concerned with representation of items/value in a single class, fungible or note, this proposed standard focus on that of a more complexed, multi-class system. It is fair to think of MCTs as a hybrid of fungible tokens (FT) and non-fungible tokens (NFTs), that is tokens are fungible within the same class but non-fungible with that from a different class. And conversions between classes may be optionally supported.
MCTs are useful in representing various structures with heterogeneous components, such as:
- **Abstract Concepts:** A company may have different classes of stocks (e.g. senior preferred, junior preferred, class A common, class B common) that together make up its outstanding equities. A shareholder's position of such company composites of zero or more shares in each class.
- **Virtual Items:** A sandbox computer game may have many types of resources (e.g. rock, wood, berries, cows, meat, knife, etc.) that together make up that virtual world. A player's inventory has any combination and quantity of these resources
- **Physical Items:** A supermarket may have many SKUs it has available for purchase (e.g. eggs, milk, beef jerky, beer, etc.). Things get added or removed from a shopper's cart as it moves down the aisle.
It's sometimes possible, especially with regard to abstract concepts or virtual items, to convert from one class to another, at a specified conversion ratio. When it comes to physical items, such conversion essentially is the implementation of bartering. Though it might generally be easier to introduce a common intermediary class, i.e. money.
## Specification
```solidity
contract ERC20 {
function totalSupply() public view returns (uint256);
function balanceOf(address _owner) public view returns (uint256);
function transfer(address _to, uint256 _value) public returns (bool);
function approve(address _spender, 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);
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}
contract ERC1203 is ERC20 {
function totalSupply(uint256 _class) public view returns (uint256);
function balanceOf(address _owner, uint256 _class) public view returns (uint256);
function transfer(address _to, uint256 _class, uint256 _value) public returns (bool);
function approve(address _spender, uint256 _class, uint256 _value) public returns (bool);
function allowance(address _owner, address _spender, uint256 _class) public view returns (uint256);
function transferFrom(address _from, address _to, uint256 _class, uint256 _value) public returns (bool);
function fullyDilutedTotalSupply() public view returns (uint256);
function fullyDilutedBalanceOf(address _owner) public view returns (uint256);
function fullyDilutedAllowance(address _owner, address _spender) public view returns (uint256);
function convert(uint256 _fromClass, uint256 _toClass, uint256 _value) public returns (bool);
event Transfer(address indexed _from, address indexed _to, uint256 _class, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _class, uint256 _value);
event Convert(uint256 indexed _fromClass, uint256 indexed _toClass, uint256 _value);
}
```
### ERC-20 Methods and Events (fully compatible)
Please see [ERC-20 Token Standard](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) for detailed specifications. Do note that these methods and events only work on the "default" class of an MCT.
```solidity
function totalSupply() public view returns (uint256);
function balanceOf(address _owner) public view returns (uint256);
function transfer(address _to, uint256 _value) public returns (bool);
function approve(address _spender, 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);
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
```
### Tracking and Transferring
**totalSupply**
Returns the total number of tokens in the specified `_class`
```solidity
function totalSupply(uint256 _class) public view returns (uint256);
```
**balanceOf**
Returns the number of tokens of a specified `_class` that the `_owner` has
```solidity
function balanceOf(address _owner, uint256 _class) public view returns (uint256);
```
**transfer**
Transfer `_value` tokens of `_class` to address specified by `_to`, return `true` if successful
```solidity
function transfer(address _to, uint256 _class, uint256 _value) public returns (bool);
```
**approve**
Grant `_spender` the right to transfer `_value` tokens of `_class`, return `true` if successful
```solidity
function approve(address _spender, uint256 _class, uint256 _value) public returns (bool);
```
**allowance**
Return the number of tokens of `_class` that `_spender` is authorized to transfer on the behalf of `_owner`
```solidity
function allowance(address _owner, address _spender, uint256 _class) public view returns (uint256);
```
**transferFrom**
Transfer `_value` tokens of `_class` from address specified by `_from` to address specified by `_to` as previously approved, return `true` if successful
```solidity
function transferFrom(address _from, address _to, uint256 _class, uint256 _value) public returns (bool);
```
**Transfer**
Triggered when tokens are transferred or created, including zero value transfers
```solidity
event Transfer(address indexed _from, address indexed _to, uint256 _class, uint256 _value);
```
**Approval**
Triggered on successful `approve`
```solidity
event Approval(address indexed _owner, address indexed _spender, uint256 _class, uint256 _value);
```
### Conversion and Dilution
**fullyDilutedTotalSupply**
Return the total token supply as if all converted to the lowest common denominator class
```solidity
function fullyDilutedTotalSupply() public view returns (uint256);
```
**fullyDilutedBalanceOf**
Return the total token owned by `_owner` as if all converted to the lowest common denominator class
```solidity
function fullyDilutedBalanceOf(address _owner) public view returns (uint256);
```
**fullyDilutedAllowance**
Return the total token `_spender` is authorized to transfer on behalf of `_owner` as if all converted to the lowest common denominator class
```solidity
function fullyDilutedAllowance(address _owner, address _spender) public view returns (uint256);
```
**convert**
Convert `_value` of `_fromClass` to `_toClass`, return `true` if successful
```solidity
function convert(uint256 _fromClass, uint256 _toClass, uint256 _value) public returns (bool);
```
**Conversion**
Triggered on successful `convert`
```solidity
event Conversion(uint256 indexed _fromClass, uint256 indexed _toClass, uint256 _value);
```
## Rationale
This standard purposely extends ERC-20 Token Standard so that new MCTs following or existing ERC-20 tokens extending this standard are fully compatible with current wallets and exchanges. In addition, new methods and events are kept as closely to ERC-20 conventions as possible for ease of adoption.
We have considered alternative implementations to support the multi-class structure, as discussed below, and we found current token standards incapable or inefficient in deal with such structures.
**Using multiple ERC-20 tokens**
It is certainly possible to create an ERC-20 token for each class, and a separate contract to coordinate potential conversions, but the short coming in this approach is clearly evident. The rationale behind this standard is to have a single contract to manage multiple classes of tokens.
**Shoehorning ERC-721 token**
Treating each token as unique, the non-fungible token standard offers maximum representational flexibility arguably at the expense of convenience. The main challenge of using ERC-721 to represent multi-class token is that separate logic is required to keep track of which tokens belongs to which class, a hacky and unnecessary endeavor.
**Using ERC-1178 token**
We came across ERC-1178 as we were putting final touches on our own proposal. The two ERCs look very similar on the surface but we believe there're a few key advantages this one has over ERC-1178.
- ERC-1178 offers no backward compatibility whereas this proposal is an extension of ERC-20 and therefore fully compatible with all existing wallets and exchanges
- By the same token, existing ERC-20 contracts can extend themselves to adopt this standard and support additional classes without affecting their current behaviors
- This proposal introduces the concept of cross class conversion and dilution, making each token class integral part of a whole system rather than many silos
## Backwards Compatibility
This EIP is fully compatible with the mandatory methods of ERC20 Token Standard so long as the implementation includes a "lowest common denominator" class, which may be class B common/gold coin/money in the abstract/virtual/physical examples above respectively. Where it is not possible to implement such class, then the implementation should specify a default class for tracking or transferring unless otherwise specified, e.g. US dollar is transferred unless other currency is explicitly specified.
We find it contrived to require the optional methods of ERC20 Token Standard, `name()`, `symbol()`, and `decimals()`, but developers are certainly free to implement these as they wish.
## Test Cases
The repository at [jeffishjeff/ERC-1203](https://github.com/jeffishjeff/ERC-1203) contains the [sample test cases](https://github.com/jeffishjeff/ERC-1203/blob/master/token.test.js).
## Implementation
The repository at [jeffishjeff/ERC-1203](https://github.com/jeffishjeff/ERC-1203) contains the [sample implementation](https://github.com/jeffishjeff/ERC-1203/blob/master/token.sol).
## References
- ERC-20 Token Standard. https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
- ERC-721 Non-Fungible Token Standard. https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
- ERC-1178 Multi-class Token Standard. https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1178.md
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

169
EIPS/eip-1207.md Normal file
View File

@ -0,0 +1,169 @@
---
eip: 1207
title: DAuth Access Delegation Standard
author: Xiaoyu Wang (@wxygeek), Bicong Wang (@Wangbicong)
discussions-to: https://github.com/ethereum/EIPs/issues/1207
status: Draft
type: Standards Track
category: ERC
created: 2018-07-10
---
DAuth Access Delegation Standard
=====
## Simple Summary
DAuth is a standard interface for accessing authorization delegation between smart contracts and users.
## Abstract
The DAuth protocol defines a set of standard API allowing identity delegations between smart contracts without the user's private key. Identity delegations include accessing and operating a user's data and assets contained in the delegated contracts.
## Motivation
The inspiration for designing DAuth comes from OAuth protocol that is extensively used in web applications. But unlike the centralized authorization of OAuth, DAuth works in a distributed manner, thus providing much more reliability and generality.
## Specification
![Rationale](../assets/eip-1207/rationale.png)
**Resource owner**: the authorizer
**Resource contract**: the contract providing data and operators
**API**: the resource contract APIs that the grantee contract can invoke
**Client contract**: the grantee contract using authorization to access and operate the data
**Grantee request**: the client contract calls the resource contract with the authorizer authorization
**AuthInfo**
``` js
struct AuthInfo {
string[] funcNames;
uint expireAt;
}
```
Required - The struct contains user authorization information
* `funcNames`: a list of function names callable by the granted contract
* `expireAt`: the authorization expire timestamp in seconds
**userAuth**
``` js
mapping(address => mapping(address => AuthInfo)) userAuth;
```
Required - userAuth maps (authorizer address, grantee contract address) pair to the users authorization AuthInfo object
**callableFuncNames**
``` js
string[] callableFuncNames;
```
Required - All methods that are allowed other contracts to call
* The callable function MUST verify the grantees authorization
**updateCallableFuncNames**
``` js
function updateCallableFuncNames(string _invokes) public returns (bool success);
```
Optional - Update the callable function list for the client contract by the resource contract's administrator
* `_invokes`: the invoke methods that the client contract can call
* return: Whether the callableFuncNames is updated or not
* This method MUST return success or throw, no other outcomes can be possible
**verify**
``` js
function verify(address _authorizer, string _invoke) internal returns (bool success);
```
Required - check the invoke method authority for the client contract
* `_authorizer`: the user address that the client contract agents
* `_invoke`: the invoke method that the client contract wants to call
* return: Whether the grantee request is authorized or not
* This method MUST return success or throw, no other outcomes can be possible
**grant**
``` js
function grant(address _grantee, string _invokes, uint _expireAt) public returns (bool success);
```
Required - delegate a client contract to access the user's resource
* `_grantee`: the client contract address
* `_invokes`: the callable methods that the client contract can access. It is a string which contains all function names split by spaces
* `_expireAt`: the authorization expire timestamp in seconds
* return: Whether the grant is successful or not
* This method MUST return success or throw, no other outcomes can be possible
* A successful grant MUST fire the Grant event(defined below)
**regrant**
``` js
function regrant(address _grantee, string _invokes, uint _expireAt) public returns (bool success);
```
Optional - alter a client contract's delegation
**revoke**
``` js
function revoke(address _grantee) public returns (bool success);
```
Required - delete a client contract's delegation
* `_grantee`: the client contract address
* return: Whether the revoke is successful or not
* A successful revoke MUST fire the Revoke event(defined below).
**Grant**
``` js
event Grant(address _authorizer, address _grantee, string _invokes, uint _expireAt);
```
* This event MUST trigger when the authorizer grant a new authorization when `grant` or `regrant` processes successfully
**Revoke**
``` js
event Revoke(address _authorizer, address _grantee);
```
* This event MUST trigger when the authorizer revoke a specific authorization successfully
**Callable Resource Contract Functions**
All public or external functions that are allowed the grantee to call MUST use overload to implement two functions: The First one is the standard method that the user invokes directly, the second one is the grantee methods of the same function name with one more authorizer address parameter.
Example:
``` js
function approve(address _spender, uint256 _value) public returns (bool success) {
return _approve(msg.sender, _spender, _value);
}
function approve(address _spender, uint256 _value, address _authorizer) public returns (bool success) {
verify(_authorizer, "approve");
return _approve(_authorizer, _spender, _value);
}
function _approve(address sender, address _spender, uint256 _value) internal returns (bool success) {
allowed[sender][_spender] = _value;
emit Approval(sender, _spender, _value);
return true;
}
```
## Rationale
**Current Limitations**
The current design of many smart contracts only considers the user invokes the smart contract functions by themselves using the private key. However, in some case, the user wants to delegate other client smart contracts to access and operate their data or assets in the resource smart contract. There isnt a common protocol to provide a standard delegation approach.
**Rationale**
On the Ethereum platform, all storage is transparent and the `msg.sender` is reliable. Therefore, the DAuth don't need an `access_token` like OAuth. DAuth just recodes the users' authorization for the specific client smart contract's address. It is simple and reliable on the Ethereum platform.
## Backwards Compatibility
This EIP introduces no backward compatibility issues. In the future, the new version protocol has to keep these interfaces.
## Implementation
Following is the DAuth Interface implementation. Furthermore, the example implementations of EIP20 Interface and ERC-DAuth Interface are also provided. Developers can easily implement their own contracts with ERC-DAuth Interface and other EIP.
* ERC-DAuth Interface implementation is available at:
https://github.com/DIA-Network/ERC-DAuth/blob/master/ERC-DAuth-Interface.sol
* Example implementation with EIP20 Interface and ERC-DAuth Interface is available at:
https://github.com/DIA-Network/ERC-DAuth/blob/master/eip20-dauth-example/EIP20DAuth.sol
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

64
EIPS/eip-1227.md Normal file
View File

@ -0,0 +1,64 @@
---
eip: 1227
title: Defuse Difficulty Bomb and Reset Block Reward
author: SmeargleUsedFly (@SmeargleUsedFly)
discussions-to: https://github.com/ethereum/EIPs/issues/1227
status: Draft
type: Standards Track
category: Core
created: 2018-07-18
requires: 649
---
## Simple Summary
This EIP proposes to permanently disable the "difficulty bomb" and reset the block reward to pre-Byzantium levels.
## Abstract
Starting with `FORK_BLKNUM` the client will calculate the difficulty without the additional exponential component. Furthermore, block rewards will be adjusted to a base of 5 ETH, uncle and nephew rewards will be adjusted accordingly.
## Motivation
Due to the "difficulty bomb" (also known as the "ice age"), introduced in EIP [#2](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md), an artificial exponential increase in difficulty until chain freeze, users may find it much more challenging to remain on the unforked chain after a hard-fork. This is a desirable effect of the ice age (in fact, its only stated purpose) in the case of a scheduled network upgrade, but is especially problematic when a hard-fork includes a controversial change.
This situation has already been observed: during the Byzantium hard-fork users were given the "choice" of following the upgraded side of the chain or remaining on the original chain, the latter already experiencing block times greater than 30 seconds. In reality one will find that organizing a disperse and decentralized set of individuals to keep the original, soon-to-be-dead chain alive under such conditions impossible. This is exacerbated when a controversial change, such as EIP [#649](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-649.md), is merged in so close to the hard-fork date, as users cannot be organized to take an educated stance for or against the change on such short notice.
Ultimately, the difficulty bomb serves but a single purpose: make it more difficult to keep the original chain alive after a hard-fork. This is unacceptable if the only way the community can make their voice heard is running/not running client software, and not through the EIP process, since they effectively have no choice and therefore no power. This EIP proposes to completely eliminate the difficulty bomb, returning some measure of power over Ethereum's governance process to the users, to the community.
Given the controversy surrounding the directly relevant EIP [#649](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-649.md), the issuance should also be reset to pre-Byzantium levels. It may be reduced again at a later time via a new hard-fork, only this time users would actually have a meaningful choice in accepting the change or not. Note: the issuance reduction is not the focus of this proposal, and is optional; the defusing of the difficulty bomb is of primary concern.
## Specification
#### Remove Exponential Component of Difficulty Adjustment
For the purposes of `calc_difficulty`, simply remove the exponential difficulty adjustment component, `epsilon`, i.e. the `int(2**((block.number // 100000) - 2))`.
#### Reset Block, Uncle, and Nephew rewards
To ensure a constant Ether issuance, adjust the block reward to `new_block_reward`, where
new_block_reward = 5_000_000_000_000_000_000 if block.number >= FORK_BLKNUM else block.reward
(5E18 wei, or 5,000,000,000,000,000,000 wei, or 5 ETH).
Analogue, if an uncle is included in a block for `block.number >= 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-Byzantium formula for uncle rewards, simply adjusted with `new_block_reward`.
The nephew reward for `block.number >= FORK_BLKNUM` is
new_nephew_reward = new_block_reward / 32
This is the existing pre-Byzantium formula for nephew rewards, simply adjusted with `new_block_reward`.
## Rationale
This will permanently, without further changes, disable the "ice age." It will also reset the block reward to pre-Byzantium levels. Both of these changes are specified similarly to EIP [#649](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-649.md), so they should require only minimal changes from client developers.
## 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. However, it may be controversial in nature among different sections of the userbase&mdash;the very problem this EIP is made to address. Therefore, it should not be included in a scheduled hardfork at a certain block number. It is suggested to implement this EIP in an isolated hard-fork before the second of the two Metropolis hard-forks.
## Test Cases
Forthcoming.
## Implementation
Forthcoming.
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

61
EIPS/eip-1234.md Normal file
View File

@ -0,0 +1,61 @@
---
eip: 1234
title: Constantinople Difficulty Bomb Delay and Block Reward Adjustment
author: Afri Schoedon (@5chdn)
discussions-to: https://ethereum-magicians.org/t/eip-1234-constantinople-difficulty-bomb-delay-and-block-reward-adjustment/833
type: Standards Track
category: Core
status: Accepted
created: 2018-07-19
---
## 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 12 months and to reduce the block rewards with the Constantinople fork, the second part of the Metropolis fork.
## Abstract
Starting with `CNSTNTNPL_FORK_BLKNUM` the client will calculate the difficulty based on a fake block number suggesting the client that the difficulty bomb is adjusting around 5 million blocks later than previously specified with the Homestead fork. Furthermore, block rewards will be adjusted to a base of 2 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 12 months. 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
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 = max(0, block.number - 5_000_000) if block.number >= CNSTNTNPL_FORK_BLKNUM else block.number
#### Adjust Block, Uncle, and Nephew rewards
To ensure a constant Ether issuance, adjust the block reward to `new_block_reward`, where
new_block_reward = 2_000_000_000_000_000_000 if block.number >= CNSTNTNPL_FORK_BLKNUM else block.reward
(2E18 wei, or 2,000,000,000,000,000,000 wei, or 2 ETH).
Analogue, if an uncle is included in a block for `block.number >= CNSTNTNPL_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-Constantinople formula for uncle rewards, simply adjusted with `new_block_reward`.
The nephew reward for `block.number >= CNSTNTNPL_FORK_BLKNUM` is
new_nephew_reward = new_block_reward / 32
This is the existing pre-Constantinople formula for nephew rewards, simply adjusted with `new_block_reward`.
## Rationale
This will delay the ice age by 29 million seconds (approximately 12 months), so the chain would be back at 30 second block times in winter 2019. 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 [#42](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2042.md) and subsequent meetings; and accepted in the Constantinople Session [#1](https://github.com/ethereum/pm/issues/55).
## 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 second Metropolis hard-fork, _Constantinople_.
## Test Cases
Test cases shall be created once the specification is to be accepted by the developers or implemented by the clients.
## Implementation
The implementation in it's logic does not differ from [EIP-649](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-649.md); an implementation for Parity-Ethereum is available in [parity-ethereum#9187](https://github.com/paritytech/parity-ethereum/pull/9187).
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

40
EIPS/eip-1240.md Normal file
View File

@ -0,0 +1,40 @@
---
eip: 1240
title: Remove Difficulty Bomb
author: Micah Zoltu (@MicahZoltu)
discussions-to: https://ethereum-magicians.org/t/difficulty-bomb-removal/832
type: Standards Track
category: Core
status: Draft
created: 2018-07-21
---
## 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 remove the difficulty bomb with the Constantinople fork, the second part of the Metropolis fork.
## Abstract
Starting with `CNSTNTNPL_FORK_BLKNUM` the client will calculate the difficulty without considering the current block number.
## Motivation
The difficulty bomb operates under the assumption that miners decide what code economic participants are running, rather than economic participants deciding for themselves. In reality, miners will mine whatever chain is most profitable and the most profitable chain is the one that economic participants use. If 99% of miners mine a chain that no economic participants use then that chain will have no value and the miners will cease mining of it in favor of some other chain that does have economic participants. Another way to put this is that miners will follow economic participants, not the other way around.
## Specification
#### Remove Difficulty
For the purposes of `calc_difficulty`, if `block.number >= CNSTNTNPL_FORK_BLKNUM` then change the epsilon component to `0` rather than having it be a function of block number.
## Rationale
With the difficulty bomb removed, when Casper is released it will be up to economic participants to decide whether they want the features that Casper enables or not. If they do not want Casper, they are free to continue running unpatched clients and participating in the Ethereum network as it exists today. This freedom of choice is the cornerstone of DLTs and making it hard for people to make that choice (by creating an artificial pressure) does not work towards that goal of freedom of choice. If the development team is not confident that economic participants will want Casper, then they should re-evaluate their priorities rather than trying to force Casper onto users.
Author Personal Note: I think we will see almost all economic participants in Ethereum switch to PoS/Sharding without any extra pressure beyond client defaults.
## 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 second Metropolis hard-fork, _Constantinople_.
## Test Cases
Test cases shall be created once the specification is to be accepted by the developers or implemented by the clients.
## Implementations
The yellow paper implements this change in https://github.com/ethereum/yellowpaper/pull/710
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

247
EIPS/eip-1261.md Normal file
View File

@ -0,0 +1,247 @@
---
eip: 1261
title: Membership Verification Token (MVT)
author: Chaitanya Potti <chaitanya@electus.network>, Partha Bhattacharya <partha@electus.network>
type: Standards Track
category: ERC
status: Draft
created: 2018-07-14
discussions-to: https://github.com/ethereum/EIPs/issues/1261
---
## Simple Summary
A standard interface for Membership Verification Token(MVT).
## Abstract
The following standard allows for the implementation of a standard API for Membership Verification Token within smart contracts(called entities). This standard provides basic functionality to track membership of individuals in certain on-chain organizations. This allows for several use cases like automated compliance, and several forms of governance and membership structures.
We considered use cases of MVTs being assigned to individuals which are non-transferable and revocable by the owner. MVTs can represent proof of recognition, proof of membership, proof of right-to-vote and several such otherwise abstract concepts on the blockchain. The following are some examples of those use cases, and it is possible to come up with several others:
- Voting: Voting is inherently supposed to be a permissioned activity. So far, onchain voting systems are only able to carry out voting with coin balance based polls. This can now change and take various shapes and forms.
- Passport issuance, social benefit distribution, Travel permit issuance, Drivers licence issuance are all applications which can be abstracted into membership, that is belonging of an individual to a small set, recognized by some authority as having certain entitlements, without needing any individual specific information(right to welfare, freedom of movement, authorization to operate vehicles, immigration)
- Investor permissioning: Making regulatory compliance a simple on chain process. Tokenization of securities, that are streamlined to flow only to accredited addresses, tracing and certifying on chain addresses for AML purposes.
- Software licencing: Software companies like game developers can use the protocol to authorize certain hardware units(consoles) to download and use specific software(games)
In general, an individual can have different memberships in his day to day life. The protocol allows for the creation of software that puts everything all at one place. His identity can be verified instantly. Imagine a world where you don't need to carry a wallet full of identity cards (Passport, gym membership, SSN, Company ID etc) and organizations can easily keep track of all its members. Organizations can easily identify and disallow fake identities.
## Motivation
A standard interface allows any user,applications to work with any MVT on Ethereum. We provide for simple ERC-1261 smart contracts. Additional applications are discussed below.
This standard is inspired from the fact that voting on the blockchain is done with token balance weights. This has been greatly detrimental to the formation of flexible governance systems on the blockchain, despite the tremendous governance potential that blockchains offer. The idea was to create a permissioning system that allows organizations to vet people once into the organization on the blockchain, and then gain immense flexibility in the kind of governance that can be carried out.
**Trade-off between trustlessness and usability:**
To truly understand the value of the protocol, it is important to understand the trade-off we are treading on. The MVT contract allows the creator to revoke the token, and essentially confiscate the membership of the member in question. To some, this might seem like an unacceptable flaw, however this is a design choice, and not a flaw.
The choice may seem to place a great amount of trust in the individuals who are managing the entity contract(entity owners). If the interests of the entity owner conflict with the interests of the members, the owner may resort to addition of fake addresses(to dominate consensus) or evicting members(to censor unfavourable decisions). At first glance this appears to be a major shortcomings, because the blockchain space is used to absolute removal of authority in most cases. Even the official definition of a dapp requires the absence of any party that manages the services provided by the application. However, the trust in entity owners is not misplaced, if it can be ensured that the interests of entity owners are aligned with the interests of members.
Another criticism of such a system would be that the standard edge of blockchain intermediation - “you cannot bribe the system if you dont know who to bribe” - no longer holds. It is possible to bribe an entity owner into submission, and get them to censor or fake votes. There are several ways to respond to this argument. First of all, all activities, such as addition of members, and removal of members can be tracked on the blockchain and traces of such activity cannot be removed. It is not difficult to build analytics tools to detect malicious activity(adding 100 fake members suddenly who vote in the direction/sudden removal of a number of members voting in a certain direction). Secondly, the entity owners power is limited to the addition and removal of members. This means that they cannot tamper any votes. They can only alter the counting system to include fake voters or remove real voters. Any sensible auditor can identify the malicious/victim addresses and create an open source audit tool to find out the correct results. The biggest loser in this attack will be the entity owner, who has a reputation to lose.
Finally, one must understand why we are taking a step away from trustlessness in this trade-off. The answer is usability. Introducing a permissioning system expands the scope of products and services that can be delivered through the blockchain, while leveraging other aspects of the blockchain(cheap, immutable, no red-tape, secure). Consider the example of the driver licence issuing agency using the ERC-1300 standard. This is a service that simply cannot be deployed in a completely trustless environment. The introduction of permissioned systems expanded the scope of services on the blockchain to cover this particular service. Sure, they have the power to revoke a persons licence for no reason. But will they? Who stands to lose the most, if the agency acts erratically? The agency itself. Now consider the alternative, the way licences(not necessarily only drivers licence, but say shareholder certificates and so on) are issued, the amount of time consumed, the complete lack of transparency. One could argue that if the legacy systems providing these services really wanted to carry out corruption and nepotism in the execution of these services, the present systems make it much easier to do so. Also, they are not transparent, meaning that there is no way to even detect if they act maliciously.
All that being said, we are very excited to share our proposal with the community and open up to suggestions in this space.
## 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.
**Every ERC-1261 compliant contract must implement the `ERC1261` interface:
```solidity
pragma solidity ^0.4.24;
/// @title ERC-1261 MVT Standard
/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1261.md
interface ERC1261 {
/// @dev This emits when a token is assigned to a member.
event Assigned(address _to);
/// @dev This emits when a membership is revoked
event Revoked(address _to);
/// @dev MVT's 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 membership
/// @return whether the member owns the token
function isCurrentMember(address _to) external view returns (bool);
/// @notice Find the member of an MVT
/// @dev index starts from zero. Useful to query all addresses (past or present)
/// @param _tokenId The index
/// @return The address of the owner of the IVM contract
function getAddressAtIndex(uint256 _index) external view returns (address);
/// @notice Assigns membership of an MVT from owner address to another address
/// @dev Throws if the member already has the token.
/// Throws if `_to` is the zero address.
/// Throws if the `msg.sender` is not an owner.
/// The entity assigns the membership to each individual.
/// When transfer is complete, this function emits the Assigned event.
/// @param _to The member
function assign(address _to) external;
/// @notice Requests membership from any address
/// @dev Throws if the `msg.sender` already has the token.
/// the individual `msg.sender` can request for a membership and if some exisiting criteria are satisfied,
/// the individual `msg.sender` receives the token.
/// When transfer is complete, this function emits the Assigned event.
function assignTo() external payable;
/// @notice Revokes the membership
/// @dev This removes the membership of the user.
/// Throws if the `_from` is not an owner of the token.
/// Throws if the `msg.sender` is not an owner.
/// Throws if `_from` is the zero address.
/// When transaction is complete, this function emits the Revoked event.
/// @param _from The current owner of the MVT
function revoke(address _from) external;
/// @notice Revokes membership from any address
/// @dev Throws if the `msg.sender` already doesn't have the token.
/// the individual `msg.sender` can revoke his/her membership.
/// When transfer is complete, this function emits the Revoked event.
function revokeFrom() external payable;
}
```
The **metadata extension** is OPTIONAL for ERC-1261 smart contracts (see "caveats", below). This allows your smart contract to be interrogated for its name and for details about the organization which your IVM tokens represent.
```solidity
/// @title ERC-1261 IVM Token Standard, optional metadata extension
/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1261.md
interface ERC1261Metadata /* is ERC1261 */ {
/// @notice A descriptive name for a collection of MVTs in this contract
function name() external view returns (string _name);
/// @notice An abbreviated name for MVTs in this contract
function symbol() external view returns (string _symbol);
}
```
This is the "ERC1261 Metadata JSON Schema" referenced above.
```json
{
"title": "Organization Metadata",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Identifies the organization to which this MVT represents",
},
"description": {
"type": "string",
"description": "Describes the organization to which this MVT represents",
}
}
}
```
### Caveats
The 0.4.24 Solidity interface grammar is not expressive enough to document the ERC-1261 standard. A contract which complies with ERC-1261 MUST also abide by the following:
- 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.24 is that you can edit this interface to add stricter mutability before inheriting from your contract.
- Solidity issue #3419: A contract that implements `ERC1261Metadata` SHALL also implement `ERC1261`.
- 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.24, 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 potential uses of Ethereum smart contracts that depend on tracking membership. Examples of existing or planned MVT systems are Vault, a DAICO platform, and Stream, a security token framework. Future uses include the implementation of direct democracy, in-game memberships and badges, licence and travel document issuance, electronic voting machine trails, software licencing and many more.
**MVT Word Choice:**
Since the tokens are non transferable and revocable, they function like membership cards. Hence the word membership verification token.
**Transfer Mechanism**
MVTs can't be transferred. This is a design choice, and one of the features that distinguishes this protocol.
**Assign and Revoke mechanism**
The assign and revoke 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 additional memberships after a condition is met** — Sample contract found on Electus Protocol
- **Blacklist certain address from receiving IVM tokens** — Sample contract found on Electus Protocol
- **Disallow additional memberships after a certain time is reached** — Sample contract found on Electus Protocol
- **Charge a fee to user of a transaction** — require payment when calling `assign` and `revoke` so that condition checks from external sources can be made
**Gas and Complexity** (regarding the enumeration extension)
This specification contemplates implementations that manage a few and *arbitrarily large* numbers of MVTs. If your application is able to grow then avoid using for/while loops in your code. These indicate your contract may be unable to scale and gas costs will rise over time without bound
**Privacy**
Personal information: The protocol does not put any personal information on to the blockchain, so there is no compromise of privacy in that respect.
Membership privacy: The protocol by design, makes it public which addresses are/arent members. Without making that information public, it would not be possible to independently audit governance activity or track admin(entity owner) activity.
**Metadata Choices** (metadata extension)
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 any smart contract can use the same name and symbol as *your* contract. How a client may determine which ERC-1261 smart contracts are well-known (canonical) is outside the scope of this standard.
A mechanism is provided to associate MVTs with URIs. We expect that many implementations will take advantage of this to provide metadata for each MVT system. The URI MAY be mutable (i.e. it changes from time to time). We considered an MVT representing membership of a place, in this case metadata about the organization 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 (not mature enough)*
**Community Consensus**
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
We have adopted `name` and `symbol` semantics from the ERC-20 specification.
Example MVT implementations as of July 2018:
- Electus Protocol(https://github.com/chaitanyapotti/ElectusProtocol/blob/master/Vault/VaultToken.sol)
## Test Cases
Electus Protocol ERC-1261 Token includes test cases written using Truffle.
## Implementations
Electus Protocol ERC1261 -- a reference implementation
- MIT licensed, so you can freely use it for your projects
- Includes test cases
## References
**Standards**
1. ERC-20 Token Standard. https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
1. ERC-173 Owned Standard. https://github.com/ethereum/EIPs/issues/173
1. Ethereum Name Service (ENS). https://ens.domains
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-1261 Issue. https://github.com/ethereum/eips/issues/1261
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
**Discussions**
1. Gitter #EIPs (announcement of first live discussion). https://gitter.im/ethereum/EIPs?at=5b5a1733d2f0934551d37642
1. ERC-1261 (announcement of first live discussion). https://github.com/ethereum/eips/issues/1261
**MVT Implementations and Other Projects**
1. Electus Protocol ERC-1261 Token. https://github.com/chaitanyapotti/ElectusProtocol
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

83
EIPS/eip-1271.md Normal file
View File

@ -0,0 +1,83 @@
---
eip: 1271
title: Standard Signature Validation Method for Contracts
author: Francisco Giordano (@frangio), Matt Condon (@shrugs), Philippe Castonguay (@PhABC)
discussions-to: https://github.com/ethereum/EIPs/issues/1271
status: Draft
type: Standards Track
category: ERC
created: 2018-07-25
---
<!--You can leave these HTML comments in your merged EIP and delete the visible duplicate text guides, they will not appear and may be helpful to refer to if you edit it again. 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.-->
Many blockchain based applications allow users to sign off-chain messages instead of directly requesting users to do an on-chain transaction. This is the case for decentralized exchanges with off-chain orderbooks like [0x](https://0xproject.com/) and [etherdelta](https://etherdelta.com/). These applications usually assume that the message will be signed by the same address that owns the assets. However, one can hold assets directly in their regular account (controlled by a private key) *or* in a smart contract that acts as a wallet (e.g. a multisig contract). The current design of many smart contracts prevent contract based accounts from interacting with them, since contracts do not possess private keys and therefore can not directly sign messages. The proposal here outlines a standard way for contracts to verify if a provided signature is valid when the account is a contract.
## Abstract
<!--A short (~200 word) description of the technical issue being addressed.-->
Externally Owned Accounts (EOA) can sign messages with their associated private keys, but currently contracts cannot. This is a problem for many applications that implement signature based off-chain methods, since contracts can't easily interact with them as they do not possess a private key. Here, we propose a standard way for any contracts to verify whether a signature on a behalf of a given contract is valid.
## 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.-->
In the future, it is likely that many users will hold their assets in a smart contract instead of holding them in their externally owned account directly since contracts can improve user experience significantly while providing extra security. This means that contracts using signature based functions should not assume that a given address can provide ECDSA signatures. Otherwise, identity based contracts and contracts holding assets may not be able to interact with functions requiring ECDSA signatures directly.
Here, we use the term *smart account* to refer to any contract that act as an account, which can include identity based methods (e.g. [ERC-725](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-725.md) & [ERC-1078](https://github.com/alexvandesande/EIPs/blob/ee2347027e94b93708939f2e448447d030ca2d76/EIPS/eip-1078.md)), asset ownership (e.g. Multisigs, proxy contracts) and/or executable signed messages methods (e.g. [ERC-1077)](https://github.com/alexvandesande/EIPs/blob/ee2347027e94b93708939f2e448447d030ca2d76/EIPS/eip-1077.md). This terminology is important for the reader to better distinguish a contract that acts as an account (e.g. a multisig, wallet or [Gnosis Safe](https://github.com/gnosis/safe-contracts) contract) and a contract that does not act as an account but requires signatures.
One example of an application that requires addresses to provide signatures would be decentralized exchanges with off-chain orderbook, where buy/sell orders are signed messages (see [0x](https://0xproject.com/) and [etherdelta](https://etherdelta.com/) for examples). In these applications, EOAs sign orders, signaling their desire to buy/sell a given asset and giving explicit permissions to the exchange smart contracts to conclude a trade via an ECDSA signature. When it comes to contracts however, ECDSA signature is not possible since contracts do not possess a private key. In the first version of the 0x protocol, smart contracts could not generate buy/sell orders for this very reason, as the `maker` needed to both own the assets *and* sign the order via ECDSA method. This was revised in their protocol version 2 (see below).
## 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 (go-ethereum, parity, cpp-ethereum, ethereumj, ethereumjs, and [others](https://github.com/ethereum/wiki/wiki/Clients)).-->
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).
```javascript
/**
* @dev Should return whether the signature provided is valid for the provided data
* @param _data Arbitrary length data signed on the behalf of address(this)
* @param _signature Signature byte array associated with _data
*
* MUST return a bool upon valid or invalid signature with corresponding _data
* MUST take (bytes, bytes) as arguments
* MUST allow external calls
*/
function isValidSignature(
bytes _data,
bytes _signature)
public
view
returns (bool isValid);
```
`isValidSignature` can call arbitrary methods to validate a given signature, which could be context dependent (e.g. time based or state based), EOA dependant (e.g. signers authorization level within smart account), signature scheme Dependant (e.g. ECDSA, multisig, BLS), etc.
## 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.-->
Such a function is important because it allows *other contracts* to validate signed messages on the behalf of the smart account. This is necessary because not all signed messages will first pass by the smart account as in ERC-1077, since signatures can be requested by independent contracts. Action based signed messages do not require this method for external contracts since the action is `Smart Account A -> Contract C` (e.g. owner of smart account `A` wants to transfer tokens `T` to contract `C`), but when the action is in the opposite direction (`Contract A -> SmartAccount`) this external function is necessary (e.g. `contract A` requires smart account `A` to transfer tokens `T` when event `E` is triggered).
We believe the name of the proposed function to be appropriate considering that an *authorized* signers providing proper signatures for a given data would see their signature as "valid" by the smart account. Hence, an signed action message is only valid when the signer is authorized to perform a given action on the behalf of a smart account.
Two arguments are provided for simplicity of separating the data from the signature, but both could be concatenated in a single byte array if community prefers this.
## 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 backward compatible with previous work on signature validation since this method is specific to contract based signatures and not EOA signatures.
## 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.-->
Existing implementations :
* The 0x project [implemented this method](https://github.com/0xProject/0x-monorepo/blob/05b35c0fdcbca7980d4195e96ec791c1c2d13398/packages/contracts/src/2.0.0/protocol/Exchange/MixinSignatureValidator.sol#L187) in their protocol version 2.
* Zeppelin is [in the process](https://github.com/OpenZeppelin/openzeppelin-solidity/issues/1104) of implementing this method.
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

63
EIPS/eip-1276.md Normal file
View File

@ -0,0 +1,63 @@
---
eip: 1276
title: Eliminate Difficulty Bomb and Adjust Block Reward on Constantinople Shift
author: EOS Classic (@eosclassicteam)
discussions-to: https://ethereum-magicians.org/t/eip-1276-eliminate-difficulty-bomb-and-adjust-block-reward-on-constantinople-shift/908
type: Standards Track
category: Core
status: Draft
created: 2018-07-31
---
## Simple Summary
The average block times are increasing due to the factor of difficulty logic well known as difficulty bomb. This EIP proposes to eliminate the difficulty bomb forever and to reduce the block rewards with the Constantinople fork, the second part of the Metropolis fork.
## Abstract
Starting with `CNSTNTNPL_FORK_BLKNUM` the client will calculate the difficulty without considering the current block number. Furthermore, block rewards will be adjusted to a base of 2 ETH, uncle and nephew rewards will be adjusted accordingly.
## Motivation
Block time has been played a most important role on blockchain ecosystem, and it is being adjusted by the logic of mining difficulty calculation that is already implemented on the node client as a part of proof-of-work consensus. Last year, average block time rapidly increased due to the wrong design of difficulty logic that is meant to be changed on the part of Casper upgrade, however, implementation of casper has been delayed therefore it was inevitable to delay the difficulty bomb in order to prevent the significant delay of processing transactions on ethereum network.
Despite of the successful hardfork to delay the activation of difficulty bomb, activation of the difficulty bomb is expected to happen again on the upcoming period before implementing casper protocol on ethereum network. Therefore, completely removing the difficulty bomb is the most proper way to response the block time increase instead of delaying it again.
Also decreasing the block mining reward along with difficulty bomb removal is expected to help the growth of the stable ethereum ecosystem, right now ethereum dominates 92% of the total hashrate share of ethash based chains, and this 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. Reducing the reward also decreases the likelihood of a miner driven chain split as Ethereum approaches proof-of-stake.
## Specification
#### Remove Exponential Component of Difficulty Adjustment
For the purposes of `calc_difficulty`, simply remove the exponential difficulty adjustment component, `epsilon`, i.e. the `int(2**((block.number // 100000) - 2))`.
#### Adjust Block, Uncle, and Nephew rewards
To ensure a constant Ether issuance, adjust the block reward to `new_block_reward`, where
new_block_reward = 2_000_000_000_000_000_000 if block.number >= CNSTNTNPL_FORK_BLKNUM else block.reward
(2E18 wei, or 2,000,000,000,000,000,000 wei, or 2 ETH).
Analogue, if an uncle is included in a block for `block.number >= CNSTNTNPL_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-Constantinople formula for uncle rewards, simply adjusted with `new_block_reward`.
The nephew reward for `block.number >= CNSTNTNPL_FORK_BLKNUM` is
new_nephew_reward = new_block_reward / 32
This is the existing pre-Constantinople formula for nephew rewards, simply adjusted with `new_block_reward`.
## Rationale
This will completely remove the difficulty bomb on difficulty adjustment algorithm without delaying the difficulty bomb again, therefore it is possible to prevent network delay on the beginning of 2019.
This EIP-1276 opposes directly the intent of [EIP-1234](https://github.com/ethereum/EIPs/issues/1234) which should be also considered in discussions.
## 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 second Metropolis hard-fork, _Constantinople_.
## Test Cases
Test cases shall be created once the specification is to be accepted by the developers or implemented by the clients.
## Implementation
The implementation shall be created once the specification is to be accepted by the developers or implemented by the clients.
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

222
EIPS/eip-1283.md Normal file
View File

@ -0,0 +1,222 @@
---
eip: 1283
title: Net gas metering for SSTORE without dirty maps
author: Wei Tang (@sorpaas)
discussions-to: https://github.com/sorpaas/EIPs/issues/1
status: Draft
type: Standards Track
category: Core
created: 2018-08-01
---
## Abstract
This EIP proposes net gas metering changes for SSTORE opcode, as an
alternative for EIP-1087. It tries to be friendlier to implementations
that use different optimization strategies for storage change
caches.
## Motivation
EIP-1087 proposes a way to adjust gas metering for SSTORE opcode,
enabling new usages on these opcodes where it is previously too
expensive. However, EIP-1087 requires keeping a dirty map for storage
changes, and implicitly makes the assumption that a transaction's
storage changes are committed to the storage trie at the end of a
transaction. This works well for some implementations, but not for
others. After EIP-658, an efficient storage cache implementation would
probably use an in-memory trie (without RLP encoding/decoding) or
other immutable data structures to keep track of storage changes, and
only commit changes at the end of a block. For them, it is possible to
know a storage's original value and current value, but it is not
possible to iterate over all storage changes without incurring additional
memory or processing costs.
This EIP proposes an alternative way for gas metering on SSTORE, using
information that is more universally available to most
implementations:
* *Storage slot's original value*.
* *Storage slot's current value*.
* Refund counter.
For the specification provided here:
* We don't suffer from the optimization limitation of EIP-1087, and it
never costs more gas compared with the current scheme.
* It covers all usages for a transient storage. Clients that are easy
to implement EIP-1087 will also be easy to implement this
specification. Some other clients might require a little bit extra
refactoring on this. Nonetheless, no extra memory or processing cost
is needed on runtime.
Usages that benefits from this EIP's gas reduction scheme includes:
* Subsequent storage write operations within the same call frame. This
includes reentry locks, same-contract multi-send, etc.
* Exchange storage information between sub call frame and parent call
frame, where this information does not need to be persistent outside
of a transaction. This includes sub-frame error codes and message
passing, etc.
## Specification
Definitions of terms are as below:
* *Storage slot's original value*: This is the value of the storage if
a reversion happens on the *current transaction*.
* *Storage slot's current value*: This is the value of the storage
before SSTORE operation happens.
* *Storage slot's new value*: This is the value of the storage after
SSTORE operation happens.
Replace SSTORE opcode gas cost calculation (including refunds) with
the following logic:
* If *current value* equals *new value* (this is a no-op), 200 gas is
deducted.
* If *current value* does not equal *new value*
* If *original value* equals *current value* (this storage slot has
not been changed by the current execution context)
* If *original value* is 0, 20000 gas is deducted.
* Otherwise, 5000 gas is deducted. If *new value* is 0, add 15000
gas to refund counter.
* If *original value* does not equal *current value* (this storage
slot is dirty), 200 gas is deducted. Apply both of the following
clauses.
* If *original value* is not 0
* If *current value* is 0 (also means that *new value* is not
0), remove 15000 gas from refund counter. We can prove that
refund counter will never go below 0.
* If *new value* is 0 (also means that *current value* is not
0), add 15000 gas to refund counter.
* If *original value* equals *new value* (this storage slot is
reset)
* If *original value* is 0, add 19800 gas to refund counter.
* Otherwise, add 4800 gas to refund counter.
Refund counter works as before -- it is limited to half of the gas
consumed.
## Explanation
The new gas cost scheme for SSTORE is divided into three different
types:
* **No-op**: the virtual machine does not need to do anything. This is
the case if *current value* equals *new value*.
* **Fresh**: this storage slot has not been changed, or has been reset
to its original value. This is the case if *current value* does not
equal *new value*, and *original value* equals *current value*.
* **Dirty**: this storage slot has already been changed. This is the
case if *current value* does not equal *new value*, and *original
value* does not equal *current value*.
We can see that the above three types cover all possible variations of
*original value*, *current value*, and *new value*.
**No-op** is a trivial operation. Below we only consider cases for
**Fresh** and **Dirty**.
All initial (not-**No-op**) SSTORE on a particular storage slot starts
with **Fresh**. After that, it will become **Dirty** if the value has
been changed. When going from **Fresh** to **Dirty**, we charge the
gas cost the same as current scheme. A **Dirty** storage slot can be
reset back to **Fresh** via a SSTORE opcode. This will trigger a
refund.
When a storage slot remains at **Dirty**, we charge 200 gas. In this
case, we would also need to keep track of `R_SCLEAR` refunds -- if we
already issued the refund but it no longer applies (*current value* is
0), then removes this refund from the refund counter. If we didn't
issue the refund but it applies now (*new value* is 0), then adds this
refund to the refund counter. It is not possible where a refund is not
issued but we remove the refund in the above case, because all storage
slot starts with **Fresh** state.
### State Transition
Below is a graph ([by
@Arachnid](https://github.com/ethereum/EIPs/pull/1283#issuecomment-410229053))
showing possible state transition of gas costs. We ignore **No-op**
state because that is trivial:
![State Transition](../assets/eip-1283/state.png)
Below is table version of the above diagram. Vertical shows the *new
value* being set, and horizontal shows the state of *original value*
and *current value*.
When *original value* is 0:
| | A (`current=orig=0`) | B (`current!=orig`) |
|----|----------------------|--------------------------|
| ~0 | B; 20k gas | B; 200 gas |
| 0 | A; 200 gas | A; 200 gas, 19.8k refund |
When *original value* is not 0:
| | X (`current=orig!=0`) | Y (`current!=orig`) | Z (`current=0`) |
|-------------|-----------------------|-------------------------|---------------------------|
| `orig` | X; 200 gas | X; 200 gas, 4.8k refund | X; 200 gas, -10.2k refund |
| `~orig, ~0` | Y; 5k gas | Y; 200 gas | Y; 200 gas, -15k refund |
| 0 | Z; 5k gas, 15k refund | Z; 200 gas, 15k refund | Z; 200 gas |
## Rationale
This EIP mostly archives what a transient storage tries to do
(EIP-1087 and EIP-1153), but without the complexity of introducing the
concept of "dirty maps", or an extra storage struct.
* For *absolute gas used* (that is, actual *gas used* minus *refund*),
this EIP is equivalent to EIP-1087 for all cases.
* For one particular case, where a storage slot is changed, reset to
its original value, and then changed again, EIP-1283 would move more
gases to refund counter compared with EIP-1087.
Examine examples provided in EIP-1087's Motivation:
* If a contract with empty storage sets slot 0 to 1, then back to 0,
it will be charged `20000 + 200 - 19800 = 400` gas.
* A contract with empty storage that increments slot 0 5 times will be
charged `20000 + 5 * 200 = 21000` gas.
* A balance transfer from account A to account B followed by a
transfer from B to C, with all accounts having nonzero starting and
ending balances, it will cost `5000 * 3 + 200 - 4800 = 10400` gas.
## Backwards Compatibility
This EIP requires a hard fork to implement. No gas cost increase is
anticipated, and many contracts will see gas reduction.
## Test Cases
Below we provide 17 test cases. 15 of them covering consecutive two
`SSTORE` operations are based on work [by
@chfast](https://github.com/ethereum/tests/issues/483). Two additional
case with three `SSTORE` operations is used to test the case when a
slot is reset and then set again.
| Code | Used Gas | Refund | Original | 1st | 2nd | 3rd |
|------------------------------------|----------|--------|----------|-----|-----|-----|
| `0x60006000556000600055` | 412 | 0 | 0 | 0 | 0 | |
| `0x60006000556001600055` | 20212 | 0 | 0 | 0 | 1 | |
| `0x60016000556000600055` | 20212 | 19800 | 0 | 1 | 0 | |
| `0x60016000556002600055` | 20212 | 0 | 0 | 1 | 2 | |
| `0x60016000556001600055` | 20212 | 0 | 0 | 1 | 1 | |
| `0x60006000556000600055` | 5212 | 15000 | 1 | 0 | 0 | |
| `0x60006000556001600055` | 5212 | 4800 | 1 | 0 | 1 | |
| `0x60006000556002600055` | 5212 | 0 | 1 | 0 | 2 | |
| `0x60026000556000600055` | 5212 | 15000 | 1 | 2 | 0 | |
| `0x60026000556003600055` | 5212 | 0 | 1 | 2 | 3 | |
| `0x60026000556001600055` | 5212 | 4800 | 1 | 2 | 1 | |
| `0x60026000556002600055` | 5212 | 0 | 1 | 2 | 2 | |
| `0x60016000556000600055` | 5212 | 15000 | 1 | 1 | 0 | |
| `0x60016000556002600055` | 5212 | 0 | 1 | 1 | 2 | |
| `0x60016000556001600055` | 412 | 0 | 1 | 1 | 1 | |
| `0x600160005560006000556001600055` | 40218 | 19800 | 0 | 1 | 0 | 1 |
| `0x600060005560016000556000600055` | 10218 | 19800 | 1 | 0 | 1 | 0 |
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

48
EIPS/eip-1285.md Normal file
View File

@ -0,0 +1,48 @@
---
eip: 1285
title: Increase Gcallstipend gas in the CALL OPCODE
author: Ben Kaufman <ben@daostack.io>, Adam Levi <adam@daostack.io>
discussions-to: https://ethereum-magicians.org/t/eip-1285-increase-gcallstipend-gas-in-the-call-opcode/941
status: Draft
type: Standards Track
category: Core
created: 2018-08-01
---
## 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.-->
Increase the ``Gcallstipend`` fee parameter in the ``CALL`` OPCODE from ``2,300`` to ``3,500`` gas units.
## Abstract
<!--A short (~200 word) description of the technical issue being addressed.-->
Currently, the ``CALL`` OPCODE forwards a stipend of ``2,300`` gas units for a non zero value ``CALL`` operations where a contract is called. This stipend is given to the contract to allow execution of its ``fallback`` function. The stipend given is intentionally small in order to prevent the called contract from spending the call gas or performing an attack (like re-entrancy).
While the stipend is small it should still give the sufficient gas required for some cheap OPCODES like ``LOG``, but it's not enough for some more complex and modern logics to be implemented.
This EIP proposes to increase the given stipend from ``2,300`` to ``3,500`` to increase the usability of the ``fallback`` function.
## 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 main motivation behind this EIP is to allow simple fallback functions to be implemented for contracts following the ``"Proxy"`` pattern. Simply explained, a ``"Proxy Contract"`` is a contract which use ``DELEGATECALL`` in its ``fallback`` function to behave according to the logic of another contract and serve as an independent instance for the logic of the contract it points to.
This pattern is very useful for saving gas per deployment (as Proxy contracts are very lean) and it opens the ability to experiment with upgradability of contracts.
On average, the ``DELEGATECALL`` functionality of a proxy contract costs about ``1,000`` gas units.
When a contract transfers ETH to a proxy contract, the proxy logic will consume about ``1,000`` gas units before the ``fallback`` function of the logic contract will be executed. This leaves merely about 1,300 gas units for the execution of the logic. This is a severe limitation as it is not enough for an average ``LOG`` operation (it might be enough for a ``LOG`` with one parameter).
By slightly increasing the gas units given in the stipend we allow proxy contracts have proper ``fallback`` logic without increasing the attack surface of the calling contract.
## 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 (go-ethereum, parity, cpp-ethereum, ethereumj, ethereumjs, and [others](https://github.com/ethereum/wiki/wiki/Clients)).-->
Increase the ``Gcallstipend`` fee parameter in the ``CALL`` OPCODE from ``2,300`` to ``3,500`` gas unit.
The actual change to the Ethereum clients would be to change the ``CallStipend`` they store as a constant.
For an implementation example you can find a Geth client implementation linked [here](https://github.com/ben-kaufman/go-ethereum/tree/eip-1285). The actual change to the code can be found [here](https://github.com/ben-kaufman/go-ethereum/blob/eip-1285/params/protocol_params.go#L41).
## 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 rational for increasing the ``Gcallstipend`` gas parameter by ``1,200`` gas units comes from the cost of performing ``DELEGATECALL`` and ``SLOAD`` with a small margin for some small additional operations. All while still keeping the stipend relatively small and insufficient for accessing the storage or changing the state.
## 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 requires a backwards incompatible change for the ``Gcallstipend`` gas parameter in the ``CALL`` OPCODE.
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

98
EIPS/eip-1295.md Normal file
View File

@ -0,0 +1,98 @@
---
eip: 1295
title: Modify Ethereum PoW Incentive Structure and Delay Difficulty Bomb
author: Brian Venturo (@atlanticcrypto)
discussions-to: https://github.com/atlanticcrypto/Discussion/issues/1
status: Draft
type: Standards Track
category: Core
created: 2018-08-05
---
<!--You can leave these HTML comments in your merged EIP and delete the visible duplicate text guides, they will not appear and may be helpful to refer to if you edit it again. 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.-->
Network security and overall ecosystem maturity warrants the continued incentivization of Proof of Work participation but may allow for a reduction in ancillary ETH issuance and the delay of the Difficulty Bomb. This EIP proposes a reduction of Uncle and removal of Nephew rewards while delaying the Difficulty Bomb with the Constantinople hard fork.
## Abstract
<!--A short (~200 word) description of the technical issue being addressed.-->
Starting with CNSTNTNPL_FORK_BLKNUM the client will calculate the difficulty based on a fake block number suggesting the client that the difficulty bomb is adjusting around 6 million blocks later than previously specified with the Homestead fork.
Furthermore, Uncle rewards will be adjusted and Nephew rewards will be removed to eliminate excess ancillary ETH issuance. The current ETH block reward of 3 ETH will remain constant.
## 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.-->
Network scalability and security are at the forefront of risks to the Ethereum protocol. With great strides being made towards on and off chain scalability, the existence of an artificial throughput limiting device in the protocol is not warranted. Removing the risk of reducing throughput through the initialization of the Difficulty Bomb is "low-hanging-fruit" to ensure continued operation at a minimum of current throughput through the next major hard fork (scheduled for late 2019).
The security layer of the Ethereum network is and should remain robust. Incentives for continued operation of the security of the growing ecosystem are paramount.
At the same time, the ancillary issuance benefits of the Ethereum protocol can be adjusted to reduce the overall issuance profile. Aggressively adjusting Uncle and removing Nephew rewards will reduce the inflationary aspect of ETH issuance, while keeping the current block reward constant at 3 ETH will ensure top line incentives stay in place.
## 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 (go-ethereum, parity, cpp-ethereum, ethereumj, ethereumjs, and [others](https://github.com/ethereum/wiki/wiki/Clients)).-->
#### 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 = max(0, block.number - 6_000_000) if block.number >= CNSTNTNPL_FORK_BLKNUM else block.number
#### Adjust Uncle and Nephew rewards
If an uncle is included in a block for `block.number >= CNSTNTNPL_FORK_BLKNUM` such that `block.number - uncle.number = k`, the uncle reward is
new_uncle_reward = (3 - k) * new_block_reward / 8
This is the existing pre-Constantinople formula for uncle rewards, adjusted to reward 2 levels of Uncles at a reduced rate.
The nephew reward for `block.number >= CNSTNTNPL_FORK_BLKNUM` is
new_nephew_reward = 0
This is a removal of all rewards for Nephew blocks.
## 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 security layer of the Ethereum network is and should remain robust. Incentives for continued operation of the growing ecosystems security are paramount.
At the same time, the ancillary issuance benefits of the Ethereum protocol can be adjusted to reduce the overall issuance profile. Aggressively adjusting Uncle and removing Nephew rewards will reduce the inflationary aspect of ETH issuance, while keeping the current block reward constant at 3 ETH will ensure top line incentives stay in place.
The Difficulty Bomb was instituted as a type of planned obsolescence to force the implementation of network upgrades with regular frequency. With the focus on scalability for the protocol, delaying a mechanism whereby the throughput of the network can be limited artificially, due to any circumstance, is a logical step to ensure continued minimum network operation at the current throughput level. We believe the existence of the Difficulty Bomb has allowed for the inclusion of protocol upgrades in forced hard-forks, and will continue to do so.
Through August 4th, the 2018 year to date reward issued to Uncle blocks totaled over 635,000 ETH. The average reward per Uncle totals 2.27 ETH. The year to date average Uncle rate is 22.49%. Using the year to date metrics, the ongoing average ETH paid as an Uncle reward per block is 0.51 ETH plus the Uncle inclusion reward of 0.021 ETH (0.09375 ETH * .2249), total Uncle related reward per block being over 0.53 ETH. With total year to date block rewards totaling approximately 3,730,000 ETH, the network has paid an additional 17pct in Uncle rewards. This is issuance that can be reduced while still maintaining the overall integrity and incentivization of network security.
Reducing the issuance of ETH in rewarding Uncle blocks (forked blocks caused by latency in propagation, a multi-faceted problem) should directly incentivize the investment in technologies and efficiencies to reduce block propagation latency which may lead to a reduction in Network wide Uncle rates, reducing ancillary issuance further.
Reducing the Uncle rewards from the current specification to the proposed will yield two levels of ancillary ETH issuance for Uncles:
Level 1 Uncle -> 0.75 ETH
Level 2 Uncle -> 0.375 ETH
These levels are sufficient to continue incentivizing decentralized participation, while also providing an immediate economic incentive for the upgrade of the Ethereum node network and its tangential infrastructure.
We believe that the ETH network has been subsidizing transaction inclusion through the robust Uncle Reward structure since inception. We also believe that a removal of the set subsidy will create a dynamic response mechanism whereby Miners and transaction senders will minimize total costs of transaction inclusion. This dynamic response structure may limit unnecessary layer 1 transaction throughput while providing incentives for layer 2 scaling solutions.
The Nephew reward structure should be entirely eliminated.
Due to current market conditions, and the likelihood of a further USD denominated price decline (50%), we believe that any top line reduction to security incentives will put the Ethereum network at undue risk. Unlike the time of the Byzantium hard fork, current USD denominated economics for securing the Ethereum network threaten the participation of the most decentralized Miner community (at home miners), which we believe make up the largest proportion of the overall network hashrate. We believe eliminating this portion of the community will increase centralization and the probability of an organized network attack.
For a technology so new and with so much potential, we find it extremely irresponsible to increase the likelihood of a network attack by reducing ETH Issuance past this proposals level.
With a reduction to the Uncle and removal of the Nephew reward, ancillary ETH issuance should drop (under normal market conditions, i.e. 22.49% uncle rate) by over 75pct and total ETH issuance from the successful sealing and mining of valid blocks should drop over 10pct.
Paired with the diffusal of the Difficulty Bomb, this proposal strikes a balance between ensuring status quo network throughput, reducing overall ETH issuance, and continuing top line incentives for investment in infrastructure and efficiencies to continue operating the Ethereum networks security layer.
## 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, 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 second Metropolis hard-fork, Constantinople.
## 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 shall be created once the specification is to be accepted by the developers or implemented by the clients.
## 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.-->
Forthcoming.
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

160
EIPS/eip-1319.md Normal file
View File

@ -0,0 +1,160 @@
---
eip: 1319
title: Smart Contract Package Registry Interface
author: Piper Merriam <piper@ethereum.org>, Christopher Gewecke <christophergewecke@gmail.com>, g. nicholas d'andrea <nick.dandrea@consensys.net>
type: Standards Track
category: ERC
status: Draft
created: 2018-08-13
discussions-to: https://github.com/ethereum/EIPs/issues/1319
---
## Simple Summary
A standard interface for smart contract package registries.
## Abstract
This EIP specifies an interface for publishing to and retrieving assets from smart contract package registries. It is a companion EIP to [1123](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1123.md) which defines a standard for smart contract package manifests.
## Motivation
The goal is to establish a framework that allows smart contract publishers to design and deploy code registries with arbitrary business logic while exposing a set of common endpoints that tooling can use to retrieve assets for contract consumers.
A clear standard would help the existing EthPM Package Registry evolve from a centralized, single-project community resource into a decentralized multi-registry system whose constituents are bound together by the proposed interface. In turn, these registries could be ENS name-spaced, enabling installation conventions familiar to users of `npm` and other package managers.
**Examples**
```shell
$ ethpm install packages.zeppelin.eth/Ownership
```
```javascript
const SimpleToken = await web3.packaging
.registry('packages.ethpm.eth')
.getPackage('simple-token')
.getVersion('^1.1.5');
```
## Specification
The specification describes a small read/write API whose components are mandatory. It allows registries to manage versioned releases using the conventions of [semver](https://semver.org/) without imposing this as a requirement. It assumes registries will share the following structure and conventions:
+ a **registry** is a deployed contract which manages a collection of **packages**.
+ a **package** is a collection of **releases**
+ a **package** is identified by a unique string name and unique bytes32 **packageId** within a given **registry**
+ a **release** is identified by a `bytes32` **releaseId** which must be unique for a given package name and release version string pair.
+ a **releaseId** maps to a set of data that includes a **manifestURI** string which describes the location of an [EIP 1123 package manifest](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1123.md). This manifest contains data about the release including the location of its component code assets.
+ a **manifestURI** is a URI as defined by [RFC3986](https://tools.ietf.org/html/rfc3986) which can be used to retrieve the contents of the package manifest. In addition to validation against RFC3986, each **manifestURI** must also contain a hash of the content as specified in the [EIP 1123](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1123.md).
### Examples
**Package Names / Release Versions**
```shell
"simple-token" # package name
"1.0.1" # version string
```
**Release IDs**
Implementations are free to choose any scheme for generating a **releaseId**. A common approach would be to hash the strings together as below:
```solidity
// Hashes package name and a release version string
function generateReleaseId(string packageName, string version)
public
view
returns (bytes32)
{
return keccak256(abi.encodePacked(packageName, version));
}
```
Implementations **must** expose this id generation logic as part of their public `read` API so
tooling can easily map a string based release query to the registry's unique identifier for that release.
**Manifest URIs**
Any IPFS or Swarm URI meets the definition of **manifestURI**.
Another example is content on GitHub addressed by its SHA-1 hash. The Base64 encoded content at this hash can be obtained by running:
```shell
$ curl https://api.github.com/repos/:owner/:repo/git/blobs/:file_sha
# Example
$ curl https://api.github.com/repos/rstallman/hello/git/blobs/ce013625030ba8dba906f756967f9e9ca394464a
```
The string "hello" can have its GitHub SHA-1 hash independently verified by comparing it to the output of:
```shell
$ printf "blob 6\000hello\n" | sha1sum
> ce013625030ba8dba906f756967f9e9ca394464a
```
### Write API Specification
The write API consists of a single method, `release`. It passes the registry the package name, a
version identifier for the release, and a URI specifying the location of a manifest which
details the contents of the release.
```solidity
function release(string packageName, string version, string manifestURI) public
returns (bytes32 releaseId);
```
### Read API Specification
The read API consists of a set of methods that allows tooling to extract all consumable data from a registry.
```solidity
// Retrieves a slice of the list of all unique package identifiers in a registry.
// `offset` and `limit` enable paginated responses / retrieval of the complete set. (See note below)
function getAllPackageIds(uint offset, uint limit) public view
returns (
bytes32 packageIds,
uint offset
);
// Retrieves the unique string `name` associated with a package's id.
function getPackageName(bytes32 packageId) public view returns (string name);
// Retrieves the registry's unique identifier for an existing release of a package.
function getReleaseId(string packageName, string version) public view returns (bytes32);
// Retrieves a slice of the list of all release ids for a package.
// `offset` and `limit` enable paginated responses / retrieval of the complete set. (See note below)
function getAllReleaseIds(string packageName, uint offset, uint limit) public view
returns (
bytes32[] ids,
uint offset
);
// Retrieves package name, release version and URI location data for a release id.
function getReleaseData(bytes32 releaseId) public view
returns (
string packageName,
string version,
string manifestURI
);
// Retrieves the release id a registry *would* generate for a package name and version pair
// when executing a release.
function generateReleaseId(string packageName, string version)
public
view
returns (bytes32);
```
**Pagination**
`getAllPackageIds` and `getAllReleaseIds` support paginated requests because it's possible that the return values for these methods could become quite large. The methods should return an `offset` that is a pointer to the next available item in a list of all items such that a caller can use it to pick up from where the previous request left off. (See [here](https://mixmax.com/blog/api-paging-built-the-right-way) for a discussion of the merits and demerits of various pagination strategies.) The `limit` parameter defines the maximum number of items a registry should return per request.
## Rationale
The proposal hopes to accomplish the following:
+ Define the smallest set of inputs necessary to allow registries to map package names to a set of
release versions while allowing them to use any versioning schema they choose.
+ Provide the minimum set of getter methods needed to retrieve package data from a registry so that registry aggregators can read all of their data.
+ Define a standard query that synthesizes a release identifier from a package name and version pair so that tooling can resolve specific package version requests without needing to query a registry about all of a package's releases.
Registries may offer more complex `read` APIs that manage requests for packages within a semver range or at `latest` etc. This EIP is agnostic about how tooling or registries might implement these. It recommends that registries implement [EIP 165](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md) and avail themselves of resources to publish more complex interfaces such as [EIP 926](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-926.md).
## Backwards Compatibility
No existing standard exists for package registries. The package registry currently deployed by EthPM would not comply with the standard since it implements only one of the method signatures described in the specification.
## Implementation
A reference implementation of this proposal is in active development at the EthPM organization on Github [here](https://github.com/ethpm/escape-truffle).
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

55
EIPS/eip-1328.md Normal file
View File

@ -0,0 +1,55 @@
---
eip: 1328
title: WalletConnect Standard URI Format
author: ligi <ligi@ligi.de>, Pedro Gomes <pedrouid@protonmail.com>
type: Standards Track
category: ERC
status: Draft
created: 2018-08-15
discussions-to: https://ethereum-magicians.org/t/wallet-connect-eip/850
requires: 831
---
## Simple Summary
A standard to create WalletConnect URIs for establishing connections between wallets and applications.
## Abstract
This standard defines how the data to connect some application and a wallet can be encoded with a URI. This URI can then be shown either as a QR code or for mobile to mobile as a link.
## Specification
### Syntax
Function call URIs follow the ERC-831 URI format, with the following parameters:
request = "ethereum" ":" [ "wc-" ]sessionId [ "@" version ][ "?" parameters ]
sessionId = STRING
version = 1*DIGIT
parameters = parameter *( "&" parameter )
parameter = key "=" value
key = "name" / "bridge" / "symKey"
value = NUMBER / STRING
### Semantics
Required parameters are dependent on the WalletConnect standard version which currently is specified to only include mobile-to-desktop connection sessions which only require `name` which describes the dapp name, `bridge` which includes the bridge URL, `symKey` which includes the symmetric key in base64.
### Example
```
ethereum:wc-8a5e5bdc-a0e4-4702-ba63-8f1a5655744f@1?name=DappExample&bridge=https://bridge.example.com&symKey=KzpSTk1pezg5eTJRNmhWJmoxdFo6UDk2WlhaOyQ5N0U=
```
## Rationale
The need for this ERC stems from the discussion to move away from JSON format used in current beta version of the WalletConnect standard which makes for very inneficient parsing of the intent of the QR code, making it easier to create better QR code parsers APIs for Wallets to implement for other compatible EIPs using the ERC-831 URI format for Ethereum. Also by using a URI instead of a JSON inside the QR-Code the Android Intent system can be leveraged.
## References
1. ERC-831, http://eips.ethereum.org/EIPS/eip-831
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

40
EIPS/eip-1352.md Normal file
View File

@ -0,0 +1,40 @@
---
eip: 1352
title: Specify restricted address range for precompiles/system contracts
author: Alex Beregszaszi (@axic)
discussions-to: https://ethereum-magicians.org/t/eip-1352-specify-restricted-address-range-for-precompiles-system-contracts/1151
status: Draft
type: Standards Track
category: Core
created: 2018-07-27
---
## Simple Summary
Specify an Ethereum address range occupied by precompiles and future system contracts. Regular accounts and contracts cannot obtain such an address.
## Abstract
The address range between 0x0000000000000000000000000000000000000000 and 0x000000000000000000000000000000000000ffff is reserved for precompiles and system contracts.
## Motivation
This will simplify certain future features where unless this is implemented, several exceptions must be specified.
## Specification
The address range between 0x0000000000000000000000000000000000000000 and 0x000000000000000000000000000000000000ffff is reserved for precompiles and system contracts.
Due to the extremely low probability (and lack of adequate testing possibilities) no explicit checks should be added to ensure that external transaction signing or
the invoking of the `CREATE` instruction can result in a precompile address.
## Rationale
N/A
## Backwards Compatibility
No contracts on the main network have been created at the specified addresses. As a result it should pose no backwards compatibility problems.
## Test Cases
N/A
## Implementation
N/A
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

52
EIPS/eip-1355.md Normal file
View File

@ -0,0 +1,52 @@
---
eip: 1355
title: Ethash 1a
author: Paweł Bylica <pawel@ethereum.org>, Jean M. Cyr [@jean-m-cyr](https://github.com/jean-m-cyr)
discussions-to: https://ethereum-magicians.org/t/eip-1355-ethash-1a/1167
status: Draft
type: Standards Track
category: Core
created: 2018-08-26
---
## Motivation
Provide minimal set of changes to Ethash algorithm to hinder and delay the adoption of ASIC based mining.
## Specification
1. Define hash function `fnv1a()` as
```python
def fnv1a(v1, v2):
return ((v1 ^ v2) * FNV1A_PRIME) % 2**32
```
where `FNV1A_PRIME` is 16777499 or 16777639.
2. Change the hash function that determines the DAG item index in Ethash algorithm from `fnv()` to new `fnv1a()`.
In [Main Loop](https://github.com/ethereum/wiki/wiki/Ethash#main-loop) change
```python
p = fnv(i ^ s[0], mix[i % w]) % (n // mixhashes) * mixhashes
```
to
```python
p = fnv1a(i ^ s[0], mix[i % w]) % (n // mixhashes) * mixhashes
```
## Rationale
The usual argument for decentralization and network security.
Unless programmable, an ASIC is hardwired to perform sequential operations in a given order. fnv1a changes the order in which an exclusive-or and a multiply are applied, effectively disabling the current wave of ASICS. A second objective is minimize ethash changes to be the least disruptive, to facilitate rapid development, and to lower the analysis and test requirements. Minimizing changes to ethash reduces risk associated with updating all affected network components, and also reduces the risk of detuning existing GPUs. It's expected that this specific change would have no effect on existing GPU performance.
Changing fnv to fnv1a has no cryptographic implications. It is merely an efficient hash function with good dispersion characteristics used to scramble DAG indexing. We remain focused on risk mitigation by reducing the need for rigorous cryptographic analysis.
### FNV Primes
The 16777639 satisfies all requirements from [Wikipedia](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV_prime).
The 16777499 is preferred by FNV authors but not used in the reference FNV implementation because of historical reasons.
See [A few remarks on FNV primes](http://www.isthe.com/chongo/tech/comp/fnv/index.html#fnv-prime).
## Copyright
This work is licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-nc-sa/4.0/).

View File

@ -61,7 +61,7 @@ var resolver = ens.resolver(node);
Then, ask the resolver for the address for the contract:
```
var hash = resolver.addr(node);
var address = 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.

57
EIPS/eip-1380.md Normal file
View File

@ -0,0 +1,57 @@
---
eip: 1380
title: Reduced gas cost for call to self
author: Alex Beregszaszi (@axic), Jacques Wagener (@jacqueswww)
discussions-to: https://ethereum-magicians.org/t/eip-1380-reduced-gas-cost-for-call-to-self/1242
status: Draft
type: Standards Track
category: Core
created: 2018-08-31
requires: 150
---
## Abstract
Reduce the gas cost for call instructions, when the goal is to run a new instance of the currently loaded contract.
## Motivation
The current gas cost of 700 for all call types (`CALL`, `DELEGATECALL`, `CALLCODE` and `STATICCALL`) does not take into account that a call to a contract itself
does not need to perform additional I/O operations, because the current contract code has already been loaded into memory.
Reducing the call-to-self gas cost would greatly benefit smart contract languages, such as Solidity and Vyper, who would then be able to utilise `CALL` instead
of `JUMP` opcodes for internal function calls. While languages can already utilise `CALL` for internal function calls, they are discouraged to do so due to the
gas costs associated with it.
Using `JUMP` comes at a considerable cost in complexity to the implementation of a smart contract language and/or compiler. The context (including stack and memory)
must be swapped in and out of the calling functions context. A desired feature is having *pure* functions, which do not modify the state of memory, and realising
them through `JUMP` requires a bigger effort from the compiler as opposed to being able to use `CALL`s.
Using call-to-self provides the guarentee that when making an internal call the function can rely on a clear reset state of memory or context, benefiting both
contract writers and contract consumers against potentially undetetected edge cases were memory could poison the context of the internal function.
Because of the `JUMP` usage for internal functions a smart contract languages are also at risk of reaching the stack depth limit considerbly faster, if nested
function calls with many in and/or outputs are required.
Reducing the gas cost, and thereby incentivising of using call-to-self instead of `JUMP`s for the internal function implementation will also benefit static
analyzers and tracers.
## Specification
If `block.number >= FORK_BLKNUM`, then decrease the cost of `CALL`, `DELEGATECALL`, `CALLCODE` and `STATICCALL` from 700 to 40,
if and only if, the destination address of the call equals to the address of the caller.
## Rationale
EIP150 has increased the cost of these instructions from 40 to 700 to more fairly charge for loading new contracts from disk, e.g. to reflect the I/O charge more closely.
By assuming that 660 is the cost of loading a contract from disk, one can assume that the original 40 gas is a fair cost of creating a new VM instance of an already loaded contract code.
## Backwards Compatibility
This should pose no risk to backwards compatibility. Currently existing contracts should not notice the difference, just see cheaper execution.
With EIP150 contract (and language) developers had a lesson that relying on strict gas costs is not feasible as costs may change.
The impact of this EIP is even less that of EIP150 because the costs are changing downwards and not upwards.
## Test Cases
TBA
## Implementation
TBA
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

View File

@ -1,7 +1,7 @@
---
eip: 140
title: REVERT instruction
author: Alex Beregszaszi, Nikolai Mushegian <nikolai@nexusdev.us>
author: Alex Beregszaszi (@axic), Nikolai Mushegian <nikolai@nexusdev.us>
type: Standards Track
category: Core
status: Final

View File

@ -1,7 +1,7 @@
---
eip: 141
title: Designated invalid EVM instruction
author: Alex Beregszaszi
author: Alex Beregszaszi (@axic)
type: Standards Track
category: Core
status: Final

View File

@ -1,7 +1,7 @@
---
eip: 145
title: Bitwise shifting instructions in EVM
author: Alex Beregszaszi, Paweł Bylica
author: Alex Beregszaszi (@axic), Paweł Bylica
type: Standards Track
category: Core
status: Accepted

View File

@ -62,4 +62,5 @@ This would provide a way to send transactions that work on Ethereum without work
| 42 | Kovan |
| 61 | Ethereum Classic mainnet |
| 62 | Ethereum Classic testnet |
| 66 | ewasm testnet |
| 1337 | Geth private chains (default) |

View File

@ -23,7 +23,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 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.
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 standardizes the concept of interfaces and standardizes the identification (naming) of interfaces.
## Specification

111
EIPS/eip-173.md Normal file
View File

@ -0,0 +1,111 @@
---
eip: 173
title: ERC-173 Contract Ownership Standard
author: Nick Mudge <nick@perfectabstractions.com>, Dan Finlay <dan@danfinlay.com>
discussions-to: https://github.com/ethereum/EIPs/issues/173
type: Standards Track
category: ERC
status: Draft
created: 2018-06-07
---
## Simple Summary
A standard interface for ownership of contracts.
## Abstract
The following standard allows for the implementation of a standard API for getting the owner address of a contract and transferring contract ownership to a different address.
Key factors influencing the standard:
- Keeping the number of functions in the interface to a minimum to prevent contract bloat.
- Backwards compatibility with existing contracts.
- Simplicity
- Gas efficient
## Motivation
Many smart contracts require that they be owned or controlled in some way. For example to withdraw funds or perform administrative actions. It is so common that the contract interface used to handle contract ownership should be standardized to allow compatibility with contracts that manage contracts.
Here are some examples of kinds of contracts and applications that can benefit from this standard:
1. Exchanges that buy/sell/auction ethereum contracts. This is only widely possible if there is a standard for getting the owner of a contract and transferring ownership.
2. Contract wallets that hold the ownership of contracts and that can transfer the ownership of contracts.
3. Contract registries. It makes sense for some registries to only allow the owners of contracts to add/remove their contracts. A standard must exist for these contract registries to verify that a contract is being submitted by the owner of it before accepting it.
## 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.
Every ERC-173 compliant contract must implement the `ERC173` interface. Contracts that inherit from OpenZeppelin's `Ownable` contract are compliant with ERC-173. However future contracts should also implement `ERC165` for the ERC-173 interface.
```solidity
pragma solidity ^0.4.24;
/// @title ERC-173 Contract Ownership Standard
/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-173.md
/// Note: the ERC-165 identifier for this interface is 0x7f5828d0
interface ERC173 /* is ERC165 */ {
/// @dev This emits when ownership of a contract changes.
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/// @notice Get the address of the owner
/// @return The address of the owner.
function owner() view external;
/// @notice Set the address of the new owner of the contract
/// @param _newOwner The address of the new owner of the contract
function transferOwnership(address _newOwner) external;
}
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.
/// @return `true` if the contract implements `interfaceID` and
/// `interfaceID` is not 0xffffffff, `false` otherwise
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
```
The `owner()` function may be implemented as `pure` or `view`.
The `transferOwnership(address _newOwner)` function may be implemented as `public` or `external`.
The OwnershipTransferred event does not have to be emitted when a contract is created.
## Rationale
Several ownership schemes were considered. The scheme chosen in this standard was chosen because of its simplicity, low gas cost and backwards compatibility with OpenZeppelin's implementation of the Ownable contract which is in active use.
Here are other schemes that were considered:
1. **Associating an Ethereum Name Service (ENS) domain name with a contract.** A contract's `owner()` function could look up the owner address of a particular ENS name and use that as the owning address of the contract. Using this scheme a contract could be transferred by transferring the ownership of the ENS domain name to a different address. Short comings to this approach are that it is not backwards compatible with existing contracts and requires gas to make external calls to ENS related contracts to get the owner address.
2. **Associating an ERC721-based non-fungible token (NFT) with a contract.** Ownership of a contract could be tied to the ownership of an NFT. The benefit of this approach is that the existing ERC721-based infrastructure could be used to sell/buy/auction contracts. Short comings to this approach are additional complexity and infrastructure required. A contract could be associated with a particular NFT but the NFT would not track that it had ownership of a contract unless it was programmed to track contracts. In addition handling ownership of contracts this way is not backwards compatible.
This standard does not exclude the above ownership schemes or other schemes from also being implemented in the same contract. For example a contract could implement this standard and also implement the other schemes so that ownership could be managed and transferred in multiple ways. This standard does provide a simple ownership scheme that is backwards compatible, is light-weight and simple to implement, and can be widely adopted and depended on.
## Backwards Compatibility
OpenZeppelin's Ownable contract is actively being used in contracts. Contracts that inherit Ownable are in compliance with this standard.
However future contracts should also implement `ERC165` for the ERC-173 interface.
## Implementations
OpenZeppelin's implementation is here: https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/ownership/Ownable.sol
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

View File

@ -46,6 +46,17 @@ Additionally, `0x19` has been chosen because since ethereum/go-ethereum#2940 , t
Using `0x19` thus makes it possible to extend the scheme by defining a version `0x45` (`E`) to handle these kinds of signatures.
### Registry of version bytes
| Version byte | EIP | Description
| ------------ | -------------- | -----------
| `0x00` | [191][eip-191] | Data with intended validator
| `0x01` | [712][eip-712] | Structured data
| `0x45` | [191][eip-191] | `personal_sign` messages
[eip-191]: https://eips.ethereum.org/EIPS/eip-191
[eip-712]: https://eips.ethereum.org/EIPS/eip-712
### Example
function submitTransactionPreSigned(address destination, uint value, bytes data, uint nonce, uint8 v, bytes32 r, bytes32 s)

69
EIPS/eip-205.md Normal file
View File

@ -0,0 +1,69 @@
---
eip: 205
title: ENS support for contract ABIs
author: Nick Johnson <nick@ethereum.org>
type: Standards Track
category: ERC
status: Draft
created: 2017-02-06
requires: 137, 181
---
## Simple Summary
This EIP proposes a mechanism for storing ABI definitions in ENS, for easy lookup of contract interfaces by callers.
## Abstract
ABIs are important metadata required for interacting with most contracts. At present, they are typically supplied out-of-band, which adds an additional burden to interacting with contracts, particularly on a one-off basis or where the ABI may be updated over time. The small size of ABIs permits an alternative solution, storing them in ENS, permitting name lookup and ABI discovery via the same process.
ABIs are typically quite compact; the largest in-use ABI we could find, that for the DAO, is 9450 bytes uncompressed JSON, 6920 bytes uncompressed CBOR, and 1128 bytes when the JSON form is compressed with zlib. Further gains on CBOR encoding are possible using a CBOR extension that permits eliminating repeated strings, which feature extensively in ABIs. Most ABIs, however, are far shorter than this, consisting of only a few hundred bytes of uncompressed JSON.
This EIP defines a resolver profile for retrieving contract ABIs, as well as encoding standards for storing ABIs for different applications, allowing the user to select between different representations based on their need for compactness and other considerations such as onchain access.
## Specification
### ABI encodings
In order to allow for different tradeoffs between onchain size and accessibility, several ABI encodings are defined. Each ABI encoding is defined by a unique constant with only a single bit set, allowing for the specification of 256 unique encodings in a single uint.
The currently recognised encodings are:
| ID | Description |
|----|----------------------|
| 1 | JSON |
| 2 | zlib-compressed JSON |
| 4 | CBOR |
| 8 | URI |
This table may be extended in future through the EIP process.
Encoding type 1 specifies plaintext JSON, uncompressed; this is the standard format in which ABIs are typically encoded, but also the bulkiest, and is not easily parseable onchain.
Encoding type 2 specifies zlib-compressed JSON. This is significantly smaller than uncompressed JSON, and is straightforward to decode offchain. However, it is impracticalfor onchain consumers to use.
Encoding type 4 is [CBOR](http://cbor.io/). CBOR is a binary encoding format that is a superset of JSON, and is both more compact and easier to parse in limited environments such as the EVM. Consumers that support CBOR are strongly encouraged to also support the [stringref extension](http://cbor.schmorp.de/stringref) to CBOR, which provides significant additional reduction in encoded size.
Encoding type 8 indicates that the ABI can be found elsewhere, at the specified URI. This is typically the most compact of the supported forms, but also adds external dependencies for implementers. The specified URI may use any schema, but HTTP, IPFS, and Swarm are expected to be the most common.
### Resolver profile
A new resolver interface is defined, consisting of the following method:
function ABI(bytes32 node, uint256 contentType) constant returns (uint256, bytes);
The interface ID of this interface is 0x2203ab56.
contentType is a bitfield, and is the bitwise OR of all the encoding types the caller will accept. Resolvers that implement this interface must return an ABI encoded using one of the requested formats, or `(0, "")` if they do not have an ABI for this function, or do not support any of the requested formats.
The `abi` resolver profile is valid on both forward and reverse records.
### ABI lookup process
When attempting to fetch an ABI based on an ENS name, implementers should first attempt an ABI lookup on the name itself. If that lookup returns no results, they should attempt a reverse lookup on the Ethereum address the name resolves to.
Implementers should support as many of the ABI encoding formats as practical.
## Rationale
Storing ABIs onchain avoids the need to introduce additional dependencies for applications wishing to fetch them, such as swarm or HTTP access. Given the typical compactness of ABIs, we believe this is a worthwhile tradeoff in many cases.
The two-step resolution process permits different names to provide different ABIs for the same contract, such as in the case where it's useful to provide a minimal ABI to some callers, as well as specifying ABIs for contracts that did not specify one of their own. The fallback to looking up an ABI on the reverse record permits contracts to specify their own canonical ABI, and prevents the need for duplication when multiple names reference the same contract without the need for different ABIs.
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

35
EIPS/eip-233.md Normal file
View File

@ -0,0 +1,35 @@
---
eip: 233
title: Formal process of hard forks
author: Alex Beregszaszi (@axic)
discussions-to: https://ethereum-magicians.org/t/eip-233-formal-process-of-hard-forks/1387
type: Meta
status: Draft
created: 2017-03-23
---
## Abstract
To describe the formal process of preparing and activating hard forks.
## Motivation
Today discussions about hard forks happen at various forums and sometimes in ad-hoc ways.
## Specification
A Meta EIP should be created and merged as a *Draft* as soon as a new hard fork is planned. This EIP should contain:
- the desired codename of the hard fork,
- list of all the EIPs included in the hard fork and
- activation block number once decided and
- the **Requires** header should point to the previous hard fork meta EIP.
The draft shall be updated with summaries of the decisions around the hard fork. It should move in to the `Accepted` state once the changes are frozen (i.e. all referenced EIPs are in the `Accepted` state) and in to the `Final` state once the hard fork has been activated.
## Rationale
A meta EIP for coordinating the hard fork should help in visibility and traceability of the scope of changes as well as provide a simple name and/or number for referring to the proposed fork.
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

View File

@ -40,9 +40,7 @@ The only potential issue here is the `fromBlock` and `toBlock` fields. It would
## Implementation
- [ ] Geth
- [ ] Parity
- [ ] EthereumJ
- [x] [Geth](https://github.com/ethereum/go-ethereum/pull/16734)
## Copyright

View File

@ -2,10 +2,11 @@
eip: 5
title: Gas Usage for `RETURN` and `CALL*`
author: Christian Reitwiessner <c@ethdev.com>
status: Draft
status: Superseded
type: Standards Track
category: Core
created: 2015-11-22
superseded-by: 211
---
### Abstract

View File

@ -1,7 +1,7 @@
---
eip: 606
title: "Hardfork Meta: Homestead"
author: Alex Beregszaszi
author: Alex Beregszaszi (@axic)
type: Meta
status: Final
created: 2017-04-23

View File

@ -1,7 +1,7 @@
---
eip: 607
title: "Hardfork Meta: Spurious Dragon"
author: Alex Beregszaszi
author: Alex Beregszaszi (@axic)
type: Meta
status: Final
created: 2017-04-23

View File

@ -1,7 +1,7 @@
---
eip: 608
title: "Hardfork Meta: Tangerine Whistle"
author: Alex Beregszaszi
author: Alex Beregszaszi (@axic)
type: Meta
status: Final
created: 2017-04-23

View File

@ -1,7 +1,7 @@
---
eip: 609
title: "Hardfork Meta: Byzantium"
author: Alex Beregszaszi
author: Alex Beregszaszi (@axic)
type: Meta
status: Final
created: 2017-04-23

View File

@ -1,7 +1,8 @@
---
eip: 649
title: Metropolis Difficulty Bomb Delay and Block Reward Reduction
author: Afri Schoedon, Vitalik Buterin
author: Afri Schoedon (@5chdn), Vitalik Buterin (@vbuterin)
discussions-to: https://github.com/ethereum/EIPs/issues/649
type: Standards Track
category: Core
status: Final

View File

@ -2,7 +2,7 @@
eip: 689
title: Address Collision of Contract Address Causes Exceptional Halt
author: Yoichi Hirai <i@yoichihirai.com>
type: Standard Track
type: Standards Track
category: Core
status: Draft
created: 2017-08-15

451
EIPS/eip-712.md Normal file
View File

@ -0,0 +1,451 @@
---
eip: 712
title: Ethereum typed structured data hashing and signing
author: Remco Bloemen <remco@wicked.ventures>,
Leonid Logvinov <logvinov.leon@gmail.com>,
Jacob Evans <jacob@dekz.net>
discussions-to: https://ethereum-magicians.org/t/eip-712-eth-signtypeddata-as-a-standard-for-machine-verifiable-and-human-readable-typed-data-signing/397
status: Draft
type: Standards Track
category: Interface
created: 2017-09-12
requires: 155, 191
---
<!--
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. -->
Signing data is a solved problem if all we care about are bytestrings. Unfortunately in the real world we care about complex meaningful messages. Hashing structured data is non-trivial and errors result in loss of the security properties of the system.
As such, the adage "don't roll your own crypto" applies. Instead, a peer-reviewed well-tested standard method needs to be used. This EIP aims to be that standard.
## Abstract
<!-- A short (~200 word) description of the technical issue being addressed. -->
This is a standard for hashing and signing of typed structured data as opposed to just bytestrings. It includes a
* theoretical framework for correctness of encoding functions,
* specification of structured data similar to and compatible with Solidity structs,
* safe hashing algorithm for instances of those structures,
* safe inclusion of those instances in the set of signable messages,
* an extensible mechanism for domain separation,
* new RPC call `eth_signTypedData`, and
* an optimized implementation of the hashing algorithm in EVM.
It does not include replay protection.
## 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. -->
This EIP aims to improve the usability of off-chain message signing for use on-chain. We are seeing growing adoption of off-chain message signing as it saves gas and reduces the number of transactions on the blockchain. Currently signed messages are an opaque hex string displayed to the user with little context about the items that make up the message.
<img src="https://github.com/ethereum/EIPs/blob/master/assets/eip-712/eth_sign.png?raw=true" style="padding-bottom: 20px; padding-top: 20px" width="60%" />
Here we outline a scheme to encode data along with its structure which allows it to be displayed to the user for verification when signing. Below is an example of what a user could be shown when signing an EIP712 message.
<img src="https://github.com/ethereum/EIPs/blob/master/assets/eip-712/eth_signTypedData.png?raw=true" style="padding-bottom: 20px; padding-top: 20px" width="60%" />
### Signatures and Hashing overview
A signature scheme consists of hashing algorithm and a signing algorithm. The signing algorithm of choice in Ethereum is `secp256k1`. The hashing algorithm of choice is `keccak256`, this is a function from bytestrings, 𝔹⁸ⁿ, to 256-bit strings, 𝔹²⁵⁶.
A good hashing algorithm should satisfy security properties such as determinism, second pre-image resistance and collision resistance. The `keccak256` function satisfies the above criteria _when applied to bytestrings_. If we want to apply it to other sets we first need to map this set to bytestrings. It is critically important that this encoding function is [deterministic][deterministic] and [injective][injective]. If it is not deterministic then the hash might differ from the moment of signing to the moment of verifying, causing the signature to incorrectly be rejected. If it is not injective then there are two different elements in our input set that hash to the same value, causing a signature to be valid for a different unrelated message.
[deterministic]: https://en.wikipedia.org/wiki/Deterministic_algorithm
[injective]: https://en.wikipedia.org/wiki/Injective_function
### Transactions and bytestrings
An illustrative example of the above breakage can be found in Ethereum. Ethereum has two kinds of messages, transactions `𝕋` and bytestrings `𝔹⁸ⁿ`. These are signed using `eth_sendTransaction` and `eth_sign` respectively. Originally the encoding function `encode : 𝕋 𝔹⁸ⁿ → 𝔹⁸ⁿ` was as defined as follows:
* `encode(t : 𝕋) = RLP_encode(t)`
* `encode(b : 𝔹⁸ⁿ) = b`
While individually they satisfy the required properties, together they do not. If we take `b = RLP_encode(t)` we have a collision. This is mitigated in Geth [PR 2940][geth-pr] by modifying the second leg of the encoding function:
[geth-pr]: https://github.com/ethereum/go-ethereum/pull/2940
* `encode(b : 𝔹⁸ⁿ) = "\x19Ethereum Signed Message:\n" ‖ len(b) ‖ b` where `len(b)` is the ascii-decimal encoding of the number of bytes in `b`.
This solves the collision between the legs since `RLP_encode(t : 𝕋)` never starts with `\x19`. There is still the risk of the new encoding function not being deterministic or injective. It is instructive to consider those in detail.
As is, the definition above is not deterministic. For a 4-byte string `b` both encodings with `len(b) = "4"` and `len(b) = "004"` are valid. This can be solved by further requiring that the decimal encoding of the length has no leading zeros and `len("") = "0"`.
The above definition is not obviously collision free. Does a bytestring starting with `"\x19Ethereum Signed Message:\n42a…"` mean a 42-byte string starting with `a` or a 4-byte string starting with `2a`?. This was pointed out in [Geth issue #14794][geth-issue-14794] and motivated Trezor to [not implement the standard][trezor] as-is. Fortunately this does not lead to actual collisions as the total length of the encoded bytestring provides sufficient information to disambiguate the cases.
[geth-issue-14794]: https://github.com/ethereum/go-ethereum/issues/14794
[trezor]: https://github.com/trezor/trezor-mcu/issues/163
Both determinism and injectiveness would be trivially true if `len(b)` was left out entirely. The point is, it is difficult to map arbitrary sets to bytestrings without introducing security issues in the encoding function. Yet the current design of `eth_sign` still takes a bytestring as input and expects implementors to come up with an encoding.
### Arbitrary messages
The `eth_sign` call assumes messages to be bytestrings. In practice we are not hashing bytestrings but the collection of all semantically different messages of all different DApps `𝕄`. Unfortunately, this set is impossible to formalize. Instead we approximate it with the set of typed named structures `𝕊`. This standard formalizes the set `𝕊` and provides a deterministic injective encoding function for it.
Just encoding structs is not enough. It is likely that two different DApps use identical structs. When this happens, a signed message intended for one DApp would also be valid for the other. The signatures are compatible. This can be intended behaviour, in which case everything is fine as long as the DApps took replay attacks into consideration. If it is not intended, there is a security problem.
The way to solve this is by introducing a domain separator, a 256-bit number. This is a value unique to each domain that is 'mixed in' the signature. It makes signatures from different domains incompatible. The domain separator is designed to include bits of DApp unique information such as the name of the DApp, the intended validator contract address, the expected DApp domain name, etc. The user and user-agent can use this information to mitigate phishing attacks, where a malicious DApp tries to trick the user into signing a message for another DApp.
### Note on replay attacks
This standard is only about signing messages and verifying signatures. In many practical applications, signed messages are used to authorize an action, for example an exchange of tokens. It is _very important_ that implementers make sure the application behaves correctly when it sees the same signed message twice. For example, the repeated message should be rejected or the authorized action should be idempotent. How this is implemented is specific to the application and out of scope for this standard.
## 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 set of signable messages is extended from transactions and bytestrings `𝕋 𝔹⁸ⁿ` to also include structured data `𝕊`. The new set of signable messages is thus `𝕋 𝔹⁸ⁿ 𝕊`. They are encoded to bytestrings suitable for hashing and signing as follows:
* `encode(transaction : 𝕋) = RLP_encode(transaction)`
* `encode(message : 𝔹⁸ⁿ) = "\x19Ethereum Signed Message:\n" ‖ len(message) ‖ message` where `len(message)` is the _non-zero-padded_ ascii-decimal encoding of the number of bytes in `message`.
* `encode(domainSeparator : 𝔹²⁵⁶, message : 𝕊) = "\x19\x01" ‖ domainSeparator ‖ hashStruct(message)` where `domainSeparator` and `hashStruct(message)` are defined below.
This encoding is deterministic because the individual components are. The encoding is injective because the three cases always differ in first byte. (`RLP_encode(transaction)` does not start with `\x19`.)
The encoding is compliant with [EIP-191][eip191]. The 'version byte' is fixed to `0x01`, the 'version specific data' is the 32-byte domain separator `domainSeparator` and the 'data to sign' is the 32-byte `hashStruct(message)`.
[eip191]: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-191.md
### Definition of typed structured data `𝕊`
To define the set of all structured data, we start with defining acceptable types. Like ABIv2 these are closely related to Solidity types. It is illustrative to adopt Solidity notation to explain the definitions. The standard is specific to the Ethereum Virtual Machine, but aims to be agnostic to higher level languages. Example:
```Solidity
struct Mail {
address from;
address to;
string contents;
}
```
**Definition**: A _struct type_ has valid identifier as name and contains zero or more member variables. Member variables have a member type and a name.
**Definition**: A _member type_ can be either an atomic type, a dynamic type or a reference type.
**Definition**: The _atomic types_ are `bytes1` to `bytes32`, `uint8` to `uint256`, `int8` to `int256`, `bool` and `address`. These correspond to their definition in Solidity. Note that there are no aliases `uint` and `int`. Note that contract addresses are always plain `address`. Fixed point numbers are not supported by the standard. Future versions of this standard may add new atomic types.
**Definition**: The _dynamic types_ are `bytes` and `string`. These are like the atomic types for the purposed of type declaration, but their treatment in encoding is different.
**Definition**: The _reference types_ are arrays and structs. Arrays are either fixed size or dynamic and denoted by `Type[n]` or `Type[]` respectively. Structs are references to other structs by their name. The standard supports recursive struct types.
**Definition**: The set of structured typed data `𝕊` contains all the instances of all the struct types.
### Definition of `hashStruct`
The `hashStruct` function is defined as
* `hashStruct(s : 𝕊) = keccak256(typeHash ‖ encodeData(s))` where `typeHash = keccak256(encodeType(typeOf(s)))`
**Note**: The `typeHash` is a constant for a given struct type and does not need to be runtime computed.
### Definition of `encodeType`
The type of a struct is encoded as `name ‖ "(" ‖ member₁ ‖ "," ‖ member₂ ‖ "," ‖ … ‖ memberₙ ")"` where each member is written as `type ‖ " " ‖ name`. For example, the above `Mail` struct is encoded as `Mail(address from,address to,string contents)`.
If the struct type references other struct types (and these in turn reference even more struct types), then the set of referenced struct types is collected, sorted by name and appended to the encoding. An example encoding is `Transaction(Person from,Person to,Asset tx)Asset(address token,uint256 amount)Person(address wallet,string name)`.
### Definition of `encodeData`
The encoding of a struct instance is `enc(value₁) ‖ enc(value₂) ‖ … ‖ enc(valueₙ)`, i.e. the concatenation of the encoded of the member values in the order that they apear in the type. Each encoded member value is exactly 32-byte long.
The atomic values are encoded as follows: Boolean `false` and `true` are encoded as `uint256` values `0` and `1` respectively. Addresses are encoded as `uint160`. Integer values are sign-extended to 256-bit and encoded in big endian order. `bytes1` to `bytes31` are arrays with a beginning (index `0`) and an end (index `length - 1`), they are zero-padded at the end to `bytes32` and encoded in beginning to end order. This corresponds to their encoding in ABI v1 and v2.
The dynamic values `bytes` and `string` are encoded as a `keccak256` hash of their contents.
The array values are encoded as the `keccak256` hash of the concatenated `encodeData` of their contents (i.e. the encoding of `SomeType[5]` is identical to that of a struct containing five members of type `SomeType`).
The struct values are encoded recursively as `hashStruct(value)`. This is undefined for cyclical data.
### Definition of `domainSeparator`
```Solidity
domainSeparator = hashStruct(eip712Domain)
```
where the type of `eip712Domain` is a struct named `EIP712Domain` with one or more of the below fields. Protocol designers only need to include the fields that make sense for their signing domain. Unused fields are left out of the struct type.
* `string name` the user readable name of signing domain, i.e. the name of the DApp or the protocol.
* `string version` the current major version of the signing domain. Signatures from different versions are not compatible.
* `uint256 chainId` the [EIP-155][eip155] chain id. The user-agent *should* refuse signing if it does not match the currently active chain.
* `address verifyingContract` the address of the contract that will verify the signature. The user-agent *may* do contract specific phishing prevention.
* `bytes32 salt` an disambiguating salt for the protocol. This can be used as a domain separator of last resort.
[eip155]: https://eips.ethereum.org/EIPS/eip-155
Future extensions to this standard can add new fields with new user-agent behaviour constraints. User-agents are free to use the provided information to inform/warn users or refuse signing.
### Specification of the `eth_signTypedData` JSON RPC
The method `eth_signTypedData` is added to the [Ethereum JSON-RPC][json-rpc]. The method parallels `eth_sign`.
[json-rpc]: https://github.com/ethereum/wiki/wiki/JSON-RPC
#### eth_signTypedData
The sign method calculates an Ethereum specific signature with: `sign(keccak256("\x19Ethereum Signed Message:\n" + len(message) + message)))`.
By adding a prefix to the message makes the calculated signature recognisable as an Ethereum specific signature. This prevents misuse where a malicious DApp can sign arbitrary data (e.g. transaction) and use the signature to impersonate the victim.
**Note** the address to sign with must be unlocked.
##### Parameters
1. `Address` - 20 Bytes - Address of the account that will sign the messages.
2. `TypedData` - Typed structured data to be signed.
Typed data is a JSON object containing type information, domain seprator parameters and the message object. Below is the [json-schema][jsons] definition for `TypedData` param.
[jsons]: http://json-schema.org/
```JavaScript
{
type: 'object',
properties: {
types: {
type: 'object',
properties: {
EIP712Domain: {type: 'array'},
},
additionalProperties: {
type: 'array',
items: {
type: 'object',
properties: {
name: {type: 'string'},
type: {type: 'string'}
},
required: ['name', 'type']
}
},
required: ['EIP712Domain']
},
primaryType: {type: 'string'},
domain: {type: 'object'},
message: {type: 'object'}
},
required: ['types', 'primaryType', 'domain', 'message']
}
```
##### Returns
`DATA`: Signature. As in `eth_sign` it is a hex encoded 129 byte array starting with `0x`. It encodes the `r`, `s` and `v` parameters from appendix F of the [yellow paper][yellow] in big-endian format. Bytes 0...64 contain the `r` parameter, bytes 64...128 the `s` parameter and the last byte the `v` parameter. Note that the `v` parameter includes the chain id as specified in [EIP-155][eip-155].
[yellow]: https://ethereum.github.io/yellowpaper/paper.pdf
[eip-155]: https://eips.ethereum.org/EIPS/eip-155
##### Example
Request:
```shell
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_signTypedData","params":["0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", {"types":{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],"Person":[{"name":"name","type":"string"},{"name":"wallet","type":"address"}],"Mail":[{"name":"from","type":"Person"},{"name":"to","type":"Person"},{"name":"contents","type":"string"}]},"primaryType":"Mail","domain":{"name":"Ether Mail","version":"1","chainId":1,"verifyingContract":"0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"},"message":{"from":{"name":"Cow","wallet":"0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"},"to":{"name":"Bob","wallet":"0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"},"contents":"Hello, Bob!"}}],"id":1}'
```
Result:
```JavaScript
{
"id":1,
"jsonrpc": "2.0",
"result": "0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b915621c"
}
```
An example how to use solidity ecrecover to verify the signature calculated with `eth_signTypedData` can be found in the EIP712 [Example.js][example-js]. The contract is deployed on the testnet Ropsten and Rinkeby.
[example-js]: https://github.com/ethereum/EIPs/blob/master/assets/eip-712/Example.js
#### personal_signTypedData
There also should be a corresponding `personal_signTypedData` method which accepts the password for an account as the last argument.
### Specification of the Web3 API
Two methods are added to [Web 3 version 1][web3-1] that parallel the `web3.eth.sign` and `web3.eth.personal.sign` methods.
[web3-1]: http://web3js.readthedocs.io/en/1.0/index.html
#### web3.eth.signTypedData
```JavaScript
web3.eth.signTypedData(typedData, address [, callback])
```
Signs typed data using a specific account. This account needs to be unlocked.
##### Parameters
1. ``Object`` - Domain separator and typed data to sign. Structured according to the JSON-Schema specified above in the `eth_signTypedData` JSON RPC call.
2. ``String|Number`` - Address to sign data with. Or an address or index of a local wallet in :ref:`web3.eth.accounts.wallet <eth_accounts_wallet>`.
3. ``Function`` - (optional) Optional callback, returns an error object as first parameter and the result as second.
----
**Note** The 2. ``address`` parameter can also be an address or index from the `web3.eth.accounts.wallet <eth_accounts_wallet>`. It will then sign locally using the private key of this account.
----
##### Returns
``Promise`` returns ``String`` - The signature as returned by `eth_signTypedData`.
##### Example
See the `eth_signTypedData` JSON-API example above for the value of `typedData`.
```JavaScript
web3.eth.signTypedData(typedData, "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826")
.then(console.log);
> "0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b915621c"
```
#### web3.eth.personal.signTypedData
```JavaScript
web3.eth.personal.signTypedData(typedData, address, password [, callback])
```
Identical to `web3.eth.signTypedData` except for an additional `password` parameter analogous to `web3.eth.personal.sign`.
## 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 `encode` function is extended with a new case for the new types. The first byte of the encoding distinguishes the cases. For the same reason it is not safe to start immediately with the domain separator or a `typeHash`. While hard, it may be possible to construct a `typeHash` that also happens to be a prefix of a valid RLP encoded transaction.
The domain separator prevents collision of otherwise identical structures. It is possible that two DApps come up with an identical structure like `Transfer(address from,address to,uint256 amount)` that should not be compatible. By introducing a domain separator the DApp developers are guaranteed that there can be no signature collision.
The domain separator also allows for multiple distinct signatures use-cases on the same struct instance within a given DApp. In the previous example, perhaps signatures from both `from` and `to` are required. By providing two distinct domain separators these signatures can be distinguished from each other.
**Alternative 1**: Use the target contract address as domain separator. This solves the first problem, contracts coming up with identical types, but does not address second use-case. The standard does suggest implementors to use the target contract address where this is appropriate.
The function `hashStruct` starts with a `typeHash` to separate types. By giving different types a different prefix the `encodeData` function only has to be injective for within a given type. It is okay for `encodeData(a)` to equal `encodeData(b)` as long as `typeOf(a)` is not `typeOf(b)`.
### Rationale for `typeHash`
The `typeHash` is designed to turn into a compile time constant in Solidity. For example:
```Solidity
bytes32 constant MAIL_TYPEHASH = keccak256(
"Mail(address from,address to,string contents)");
```
For the type hash several alternatives where considered and rejected for the reasons:
**Alternative 2**: Use ABIv2 function signatures. `bytes4` is not enough to be collision resistant. Unlike function signatures, there is negligible runtime cost incurred by using longer hashes.
**Alternative 3**: ABIv2 function signatures modified to be 256-bit. While this captures type info, it does not capture any of the semantics other than the function. This is already causing a practical collision between ERC20's and ERC721's `transfer(address,uint256)`, where in the former the `uint256` revers to an amount and the latter to a unique id. In general ABIv2 favors compatibility where a hashing standard should prefer incompatibility.
**Alternative 4**: 256-bit ABIv2 signatures extended with parameter names and struct names. The `Mail` example from a above would be encoded as `Mail(Person(string name,address wallet) from,Person(string name,address wallet) to,string contents)`. This is longer than the proposed solution. And indeed, the length of the string can grow exponentially in the length of the input (consider `struct A{B a;B b;}; struct B {C a;C b;}; …`). It also does not allow a recursive struct type (consider `struct List {uint256 value; List next;}`).
**Alternative 5**: Include natspec documentation. This would include even more semantic information in the schemaHash and further reduces chances of collision. It makes extending and amending documentation a breaking changes, which contradicts common assumptions. It also makes the schemaHash mechanism very verbose.
### Rationale for `encodeData`
The `encodeData` is designed to allow easy implementation of `hashStruct` in Solidity:
```Solidity
function hashStruct(Mail memory mail) pure returns (bytes32 hash) {
return keccak256(abi.encode(
MAIL_TYPEHASH,
mail.from,
mail.to,
keccak256(mail.contents)
));
}
```
it also allows for an efficient in-place implementation in EVM
```Solidity
function hashStruct(Mail memory mail) pure returns (bytes32 hash) {
// Compute sub-hashes
bytes32 typeHash = MAIL_TYPEHASH;
bytes32 contentsHash = keccak256(mail.contents);
assembly {
// Back up select memory
let temp1 := mload(sub(mail, 32))
let temp2 := mload(add(mail, 128))
// Write typeHash and sub-hashes
mstore(sub(mail, 32), typeHash)
mstore(add(mail, 64), contentsHash)
// Compute hash
hash := keccak256(sub(mail, 32), 128)
// Restore memory
mstore(sub(mail, 32), temp1)
mstore(add(mail, 64), temp2)
}
}
```
The in-place implementation makes strong but reasonable assumptions on the memory layout of structs in memory. Specifically it assume structs are not allocated below address 32, that members are stored in order, that all values are padded to 32-byte boundaries, and that dynamic and reference types are stored as a 32-byte pointers.
**Alternative 6**: Tight packing. This is the default behaviour in Soldity when calling `keccak256` with multiple arguments. It minimizes the number of bytes to be hashed but requires complicated packing instructions in EVM to do so. It does not allow in-place computation.
**Alternative 7**: ABIv2 encoding. Especially with the upcoming `abi.encode` it should be easy to use `abi.encode` as the `encodeData` function. The ABIv2 standard by itself fails the determinism security criteria. There are several valid ABIv2 encodings of the same data. ABIv2 does not allow in-place computation.
**Alternative 8**: Leave `typeHash` out of `hashStruct` and instead combine it with the domain separator. This is more efficient, but then the semantics of the Solidity `keccak256` hash function are not injective.
**Alternative 9**: Support cyclical data structures. The current standard is optimized for tree-like data structures and undefined for cyclical data structures. To support cyclical data a stack containing the path to the current node needs to be maintained and a stack offset substituted when a cycle is detected. This is prohibitively more complex to specify and implement. It also breaks composability where the hashes of the member values are used to construct the hash of the struct (the hash of the member values would dependent on the path). It is possible to extend the standard in a compatible way to define hashes of cyclical data.
Similarly, a straightforward implementation is sub-optimal for directed acyclic graphs. A simple recursion through the members can visit the same node twice. Memoization can optimize this.
## Rationale for `domainSeparator`
Since different domains have different needs, an extensible scheme is used where the DApp specifies a `EIP712Domain` struct type and an instance `eip712Domain` which it passes to the user-agent. The user-agent can then apply different verification measures depending on the fields that are there.
A field `string eip719dsl` can added and be rejected if the value does not match the hash of the [EIP-719][eip719] DSL interface string.
[eip719]: https://github.com/ethereum/EIPs/issues/719
## 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 RPC calls, web3 methods and `SomeStruct.typeHash` parameter are currently undefined. Defining them should not affect the behaviour of existing DApps.
The Solidity expression `keccak256(someInstance)` for an instance `someInstance` of a struct type `SomeStruct` is valid syntax. It currently evaluates to the `keccak256` hash of the memory address of the instance. This behaviour should be considered dangerous. In some scenarios it will appear to work correctly but in others it will fail determinism and/or injectiveness. DApps that depend on the current behaviour should be considered dangerously broken.
## 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. -->
An example contract can be found in [Example.sol][ex-sol] and an example implementation of signing in Javascrtip in [Example.js][ex-js]
[ex-sol]: https://github.com/ethereum/EIPs/blob/master/assets/eip-712/Example.sol
[ex-js]: https://github.com/ethereum/EIPs/blob/master/assets/eip-712/Example.js
## 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. -->
To be done before this EIP can be considered accepted:
* [x] Finalize specification of structure hashing
* [x] Domain separators
* [x] Add test vectors
* [ ] Review specification
To be done before this EIP can be considered "Final":
* [ ] Implement `eth_signTypedData` in major RPC providers.
* [ ] Implement `web3.eth.signTypedData` in Web3 providers.
* [ ] Implement `keccak256` struct hashing in Solidity.
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

View File

@ -4,8 +4,7 @@ title: ERC-721 Non-Fungible Token Standard
author: William Entriken <github.com@phor.net>, Dieter Shirley <dete@axiomzen.co>, Jacob Evans <jacob@dekz.net>, Nastassia Sachs <nastassia.sachs@protonmail.com>
type: Standards Track
category: ERC
status: Last Call
review-period-end: 2018-06-18
status: Final
created: 2018-01-24
requires: 165
---
@ -45,7 +44,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 0x80ac58cd
/// 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
@ -85,7 +84,7 @@ interface ERC721 /* is ERC165 */ {
/// `_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
/// `onERC721Received` on `_to` and throws if the return value is not
/// `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`.
/// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
/// @param _from The current owner of the NFT
/// @param _to The new owner
/// @param _tokenId The NFT to transfer
@ -94,7 +93,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
@ -112,24 +111,24 @@ interface ERC721 /* is ERC165 */ {
/// @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
/// @notice Change 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 NFT owner, or an authorized
/// 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 of `msg.sender`'s assets.
/// all of `msg.sender`'s assets
/// @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 _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;
/// @notice Get the approved address for a single NFT
/// @dev Throws if `_tokenId` is not a valid 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) external view returns (address);
@ -155,7 +154,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
/// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02.
interface ERC721TokenReceiver {
/// @notice Handle the receipt of an NFT
/// @dev The ERC721 smart contract calls this function on the recipient
@ -163,12 +162,13 @@ interface ERC721TokenReceiver {
/// transfer. 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 NFT identifier which is being transfered
/// @param data Additional data with no specified format
/// @return `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`
/// @param _operator The address which called `safeTransferFrom` function
/// @param _from The address which previously owned the token
/// @param _tokenId The NFT identifier which is being transferred
/// @param _data Additional data with no specified format
/// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
/// unless throwing
function onERC721Received(address _from, uint256 _tokenId, bytes data) external returns(bytes4);
function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external returns(bytes4);
}
```
@ -177,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 0x5b5e139f
/// 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 view returns (string _name);
@ -221,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 0x780e9d63
/// 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
@ -295,6 +295,8 @@ Failed transactions will throw, a best practice identified in ERC-223, ERC-677,
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.
We questioned if the `operator` parameter on `onERC721Received` was necessary. In all cases we could imagine, if the operator was important then that operator could transfer the token to themself and then send it -- then they would be the `from` address. This seems contrived because we consider the operator to be a temporary owner of the token (and transferring to themself is redundant). When the operator sends the token, it is the operator acting on their own accord, NOT the operator acting on behalf of the token holder. This is why the operator and the previous token owner are both significant to the token recipient.
*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**

View File

@ -10,14 +10,14 @@ created: 2017-10-02
---
## Simple Summary
Proxy contract for key management and execution, to establish a Blockchain identity.
A proxy contract for key management and execution, to establish a Blockchain identity.
## Abstract
The following describes standard functions for a unique identity for humans, groups, objects and machines.
This identity can hold keys to sign actions (transactions, documents, logins, access, etc), and claims, which are attested from third parties (issuers) and self attested ([#ERC735](https://github.com/ethereum/EIPs/issues/735)), as well as a proxy function to act directly on the blockchain.
This identity can hold keys to sign actions (transactions, documents, logins, access, etc), and claims, which are attested from third parties (issuers) and self-attested ([#ERC735](https://github.com/ethereum/EIPs/issues/735)), as well as a proxy function, to act directly on the blockchain.
## Motivation
This standardised identity interface will allow Dapps, smart contracts and thirdparties to check the validity of a person, organisation, object or machine through 2 steps as described in the function XXX. Trust is here transfered to the issuers of claims.
This standardized identity interface will allow Dapps, smart contracts and third parties to check the validity of a person, organization, object or machine through 2 steps as described in the function XXX. Trust is here transferred to the issuers of claims.
The most important functions to verify an identity are: `XXX`
@ -26,7 +26,7 @@ The most important functions to manage an identity are: `XXX`
## Definitions
- `keys`: Keys are public keys from either external accounts, or contract addresses.
- `keys`: Keys are public keys from either external accounts, or contracts' addresses.
- `claim issuer`: is another smart contract or external account, which issues claims about this identity. The claim issuer can be an identity contract itself.
- `claim`: For details about claims see [#ERC735](https://github.com/ethereum/EIPs/issues/735)
@ -64,7 +64,7 @@ function getKey(bytes32 _key) constant returns(uint256[] purposes, uint256 keyTy
#### keyHasPurpose
Returns the `TRUE` if a key has is present and has the given purpose. If key is not present it returns `FALSE`.
Returns the `TRUE` if a key has is present and has the given purpose. If the key is not present it returns `FALSE`.
``` js
function keyHasPurpose(bytes32 _key, uint256 purpose) constant returns(bool exists);
@ -82,11 +82,11 @@ function getKeysByPurpose(uint256 _purpose) constant returns(bytes32[] keys);
#### addKey
Adds a `_key` to the identity. The `_purpose` specifies the purpose of key. Initially we propose four purposes:
Adds a `_key` to the identity. The `_purpose` specifies the purpose of the key. Initially, we propose four purposes:
- `1`: MANAGEMENT keys, which can manage the identity
- `2`: ACTION keys, which perform actions in this identities name (signing, logins, transactions, etc.)
- `3`: CLAIM signer keys, used to sign claims on other identities which need to be revokable.
- `3`: CLAIM signer keys, used to sign claims on other identities which need to be revocable.
- `4`: ENCRYPTION keys, used to encrypt data e.g. hold in claims.
MUST only be done by keys of purpose `1`, or the identity itself. If its the identity itself, the approval process will determine its approval.
@ -121,9 +121,9 @@ function removeKey(bytes32 _key, uint256 _purpose) returns (bool success)
Executes an action on other contracts, or itself, or a transfer of ether.
SHOULD require `approve` to be called with one or more keys of purpose `1` or `2` to approve this execution.
Execute COULD be used as the only accessors for `addKey`, `removeKey` and `replaceKey` and `removeClaim`.
Execute COULD be used as the only accessor for `addKey`, `removeKey` and `replaceKey` and `removeClaim`.
**Returns `executionId`:** SHOULD be send to the `approve` function, to approve or reject this execution.
**Returns `executionId`:** SHOULD be sent to the `approve` function, to approve or reject this execution.
**Triggers Event:** [ExecutionRequested](#executionrequested)
**Triggers on direct execution Event:** [Executed](#executed)
@ -136,8 +136,8 @@ function execute(address _to, uint256 _value, bytes _data) returns (uint256 exec
#### approve
Approves an execution or claim addition.
This SHOULD require `n` of `m` approvals of keys purpose `1`, if the `_to` of the execution is the identity contract itself, to successfull approve an execution.
And COULD require `n` of `m` approvals of keys purpose `2`, if the `_to` of the execution is another contract, to successfull approve an execution.
This SHOULD require `n` of `m` approvals of keys purpose `1`, if the `_to` of the execution is the identity contract itself, to successfully approve an execution.
And COULD require `n` of `m` approvals of keys purpose `2`, if the `_to` of the execution is another contract, to successfully approve an execution.
**Triggers Event:** [Approved](#approved)
**Triggers on successfull execution Event:** [Executed](#executed)
@ -159,7 +159,7 @@ Requires: [ERC 735](https://github.com/ethereum/EIPs/issues/735)
#### addClaim
This SHOULD create a pending claim, which SHOULD to be approved or rejected by `n` of `m` `approve` calls from keys of purpose `1`.
This SHOULD create a pending claim, which SHOULD be approved or rejected by `n` of `m` `approve` calls from keys of purpose `1`.
Only Events:
**Triggers if the claim is new Event and approval process exists:** [ClaimRequested](#claimrequested)
@ -241,13 +241,13 @@ MUST be triggered when `approve` was called and the claim was successfully added
## Rationale
This specification was chosen to allow most flexibility and experimention around identity. By having each identity in a separate contract it allows for cross idenity compatibility, but at the same time extra and altered functionality for new use cases.
This specification was chosen to allow most flexibility and experimentation around identity. By having each identity in a separate contract it allows for cross identity compatibility, but at the same time extra and altered functionality for new use cases.
The main critic of this standard is the verification where each identity that issues a claim, also should have a separate CLAIM signing key attached. While [#ERC780](https://github.com/ethereum/EIPs/issues/780) uses a standardised registry to assign claims to addresses.
The main critic of this standard is the verification where each identity that issues a claim, also should have a separate CLAIM signing key attached. While [#ERC780](https://github.com/ethereum/EIPs/issues/780) uses a standardized registry to assign claims to addresses.
Both systems could work in conjunction and should be explored.
While also off-chain claims using DID verifiable claims and merkle tries can be added as claims and should be explored.
The rationale of this standard is to function as an open and veryf flexible container for idenity.
The rationale of this standard is to function as an open and very flexible container for identity.
## Implementation
@ -281,9 +281,10 @@ contract ERC725 {
}
function getKey(bytes32 _key) public constant returns(uint256[] purposes, uint256 keyType, bytes32 key);
function keyHasPurpose(bytes32 _key, uint256 purpose) constant returns(bool exists);
function getKeysByPurpose(uint256 _purpose) public constant returns(bytes32[] keys);
function keyHasPurpose(bytes32 _key, uint256 _purpose) public constant returns (bool exists);
function getKeysByPurpose(uint256 _purpose) public constant returns (bytes32[] keys);
function addKey(bytes32 _key, uint256 _purpose, uint256 _keyType) public returns (bool success);
function removeKey(bytes32 _key, uint256 _purpose) public returns (bool success);
function execute(address _to, uint256 _value, bytes _data) public returns (uint256 executionId);
function approve(uint256 _id, bool _approve) public returns (bool success);
}
@ -299,4 +300,4 @@ contract ERC725 {
- [Sovrin Foundation Self Sovereign Identity](https://sovrin.org/wp-content/uploads/2017/06/The-Inevitable-Rise-of-Self-Sovereign-Identity.pdf)
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

View File

@ -1,6 +1,6 @@
---
eip: 758
title: Subscriptions and filters for transaction return data
title: Subscriptions and filters for completed transactions
author: Jack Peterson <jack@tinybike.net>
type: Standards Track
category: Interface
@ -9,30 +9,50 @@ created: 2017-11-09
---
## Simple Summary
Provide a way for external callers to access the return data of functions executed during Ethereum transactions.
Provide a way for external callers to be notified of completed transactions, and access the return data of functions executed when a transaction is mined.
## 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 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.
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) completed transactions. The Ethereum node sends the return data to the caller when the transactions are sealed.
## Motivation
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.
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. While implementing the original version of this EIP, it was decided to expand this functionality slightly to allow for external callers to be notified of their completed transactions even in the case where there is *no* return data. This could be either because the method called doesn't return a value, or because the transaction is a simple transfer of value.
## Specification
### Subscription
A caller who wants to be notified of return data for their transactions sends an `eth_subscribe` RPC request with the parameter `"returnData"`:
A caller who wants to be notified when transactions of theirs complete sends an `eth_subscribe` RPC request with the first parameter `"completedTransaction"`:
```json
{"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["returnData"]}
{"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["completedTransaction", filter]}
```
The Ethereum node responds with a subscription ID:
The `filter` parameter is a dictionary containing 3 optional named arguments: `from`, `to`, and `hasReturnData`. `from` and `to` can each either be single addresses, or a list of addresses. They are used to filter out any transactions not sent from an address in the `from` list and sent to an address in the to list. `hasReturnData` is a boolean--if it is specified and `true`, then notifications will be received only for completed transactions containing returnData.
For example, to restrict results to contract creations originating from either of two addresses (0x3f7d39bDBf1f5cE649c194571aEd3D2BbB2F85ce or 0x7097f41F1C1847D52407C629d0E0ae0fDD24fd58):
```json
filter = { "from" : ["0x3f7d39bDBf1f5cE649c194571aEd3D2BbB2F85ce",
"0x7097f41F1C1847D52407C629d0E0ae0fDD24fd58"],
"to" : "0x0"
}
```
To restrict results to method calls on contract address 0xD9Cb531aB97A652c8fC60dcF6D263fcA2F5764e9:
```json
filter = { "to" : "0xD9Cb531aB97A652c8fC60dcF6D263fcA2F5764e9", "hasReturnData" : true }
```
Or to be notified of any transactions submitted by this rpc client when they complete, with no further restrictions:
```json
filter = {}
```
After the request is recieved, the Ethereum node responds with a subscription ID:
```json
{"jsonrpc": "2.0", "id": 1, "result": "0x00000000000000000000000000000b0b"}
```
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:
Suppose the caller then 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 pushes a notification to the caller. If the transaction is a method call on a contract, this will include the return value (eg. `"0x000000000000000000000000000000000000000000000000000000000000002a"`) of the called function:
```json
{
@ -48,17 +68,17 @@ 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. 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:
The caller receives notifications about their transactions 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. If `from`, `to`, or `hasReturnData` is specified, then only those matching the filter criteria will generate notificaitons. 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_newReturnDataFilter` request:
Push notifications require full duplex connections (i.e., websocket or IPC). Instead of subscribing, callers using HTTP send an `eth_newCompletedTransactionFilter` request:
```json
{"jsonrpc": "2.0", "id": 1, "method": "eth_newReturnDataFilter"}
{"jsonrpc": "2.0", "id": 1, "method": "eth_newCompletedTransactionFilter", "params": [filter] }
```
The Ethereum node responds with a filter ID:
@ -67,7 +87,7 @@ The Ethereum node responds with a filter ID:
{"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`:
When a transaction is submitted, the Ethereum node pushes the transaction notification, including return value, into a queue which is emptied when the caller polls using `eth_getFilterChanges`:
```json
{"jsonrpc": "2.0", "id": 2, "method": "eth_getFilterChanges", "params": ["0x1"]}
@ -86,7 +106,7 @@ 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_newReturnDataFilter` request are included in this array.
All transactions that were sealed _after_ the initial `eth_newCompletedTransactionFilter` request are included in this array. Again, if the `filter` param is a non-empty dictinary (contains either `from`, `to`, or `hasReturnData`) then only transactions matching the filter criteria generate notifications. Note that in the polling case, there is no way for the Ethereum node to be sure that an RPC client which submits a transaction was the same as the one who created the filter, so there is no restriction based on where the transaction was submitted.
## Rationale

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -95,11 +95,11 @@ NOTE: Callers MUST handle false from returns (bool success). Callers MUST NOT as
##### __targetExchangeCallback
This function is called by the intermediate exchange service contract. This function should add `_amount` tokens of the target contract to the exchangers address for exchange to be completed successfully.
s
NOTE: It is required that only the exchange service contract has the authority to call this function.
``` js
function __targetExchangeCallback (uint _amount) public returns(bool success)
function __targetExchangeCallback (uint _to, uint _amount) public returns(bool success)
```
##### __targetExchangeAndSpendCallback
@ -108,7 +108,7 @@ This function is called by the intermediate exchange service contract. This func
NOTE: It is required that only the exchange service contract has the authority to call this function.
``` js
function __targetExchangeAndSpendCallback (address _to,uint _amount) public returns(bool success)
function __targetExchangeAndSpendCallback (address _from, address _to, uint _amount) public returns(bool success)
```
#### Events
@ -156,7 +156,7 @@ function registerToken(address _token) public returns(bool success)
This function is called by the token holder who wants to exchange his token with the `_targetContract` tokens. This function queries the exchange rate, calculates the converted amount, calls `__exchangerCallback` and calls the `__targetExchangeCallback`. It takes address of the target contract and amount to exchange as parameter and returns boolean `success` and amount credited.
``` js
function exchangeToken(address _targetContract, uint _amount) public returns(bool success, uint creditedAmount)
function exchangeToken(address _targetContract, uint _amount, address _from) public returns(bool success, uint creditedAmount)
```
##### exchangeAndSpend
@ -164,7 +164,7 @@ function exchangeToken(address _targetContract, uint _amount) public returns(boo
This function is called by the token holder who wants to exchange his token with the `_targetContract` tokens. This function queries the exchange rate, calculates the converted amount, calls `__exchangerCallback` and calls the `__targetExchangeAndSpendCallback`. It takes address of the target contract and amount to exchange as parameter and returns boolean `success` and amount credited.
``` js
function exchangeAndSpend(address _targetContract, uint _amount,address _to) public returns(bool success)
function exchangeAndSpend(address _targetContract, uint _amount, address _from, address _to) public returns(bool success)
```
#### Events

View File

@ -1,6 +1,6 @@
---
eip: 858
title: Reduce block reward
title: Reduce block reward and delay difficulty bomb
author: Carl Larson <cslarson@gmail.com>
type: Standards Track
category: Core
@ -9,30 +9,34 @@ created: 2018-01-29
---
## Simple Summary
Reduce the block reward to 1 ETH.
Reduce the block reward to 1 ETH and delay the difficulty bomb.
## 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.
Recent research developments also now time the switch to POS as sometime in 2019 and as a result there is need to further delay the difficulty bomb so the network doesn't grind to a halt.
## 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](../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.
The current public Ethereum network has a hashrate of 296 TH/s. This hashrate corresponds to a power usage of roughly [1 TW](../assets/eip-858/calculations.md) and yearly energy consumption of 8.8 TWh (roughly 0.04% 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.
If any resulting hard forks need a name for that name to maybe be Perinthos.
Delay difficulty bomb by 2,000,000 blocks
Adjust block, uncle, and nephew rewards to reflect a new block reward of 1 ETH.
## Rationale
partly TBD
This will delay the difficulty bomb by roughly a year. The difficulty bomb remains a community supported mechanism to aid a future transition to POS.
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.
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. In addition, the difficulty bomb would be delayed - ensuring the network would not grind to a halt.
## 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.
No implementation including both block reward and difficulty adjustment is currently available.
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

View File

@ -2,7 +2,7 @@
eip: 884
title: 'DGCL Token'
author: 'Dave Sag <davesag@gmail.com>'
type: Standard Track
type: Standards Track
category: ERC
status: Draft
created: 2018-02-14

View File

@ -18,7 +18,7 @@ This specification describes a method for initially locking tokens within a toke
### Motivation
Token distribution via the ICO model and it's derivatives is susceptable to illicit behavior by human actors. Furthermore, new token projects are centralized because a single entity must handle and control all of the initial coins and all of the the raised ICO money. By distributing tokens via an 'Initial Mining Offering' (or IMO), the ownership of the token contract no longer belongs with the deployer at all and the deployer is 'just another user.' As a result, investor risk exposure utilizing a mined token distribution model is significantly diminished. This standard is intended to be standalone, allowing maximum interoperability with ERC20, ERC721, and others.
Token distribution via the ICO model and it's derivatives is susceptible to illicit behavior by human actors. Furthermore, new token projects are centralized because a single entity must handle and control all of the initial coins and all of the raised ICO money. By distributing tokens via an 'Initial Mining Offering' (or IMO), the ownership of the token contract no longer belongs with the deployer at all and the deployer is 'just another user.' As a result, investor risk exposure utilizing a mined token distribution model is significantly diminished. This standard is intended to be standalone, allowing maximum interoperability with ERC20, ERC721, and others.
### Specification
@ -216,8 +216,7 @@ function getChallengeNumber() public view returns (bytes32);
#### getMiningDifficulty
The number of digits that the digest of the PoW solution requires which typically auto adjusts during reward generation.Return the current reward amount. Depending on the algorithm, typically rewards are divided every reward era as tokens are mined to provide scarcity.
The number of digits that the digest of the PoW solution requires which typically auto adjusts during reward generation.
``` js
function getMiningDifficulty() public view returns (uint)
@ -246,7 +245,7 @@ Once the nonce and hash1 are found, these are used to call the mint() function o
### Rationale
A keccak256 algoritm does not have to be used, but it is recommended since it is a cost effective one-way algorithm to perform in the EVM and simple to perform in solidity. The nonce is the solution that miners try to find and so it is part of the hashing algorithm. A challengeNumber is also part of the hash so that future blocks cannot be mined since it acts like a random piece of data that is not revealed until a mining round starts. The msg.sender address is part of the hash so that a nonce solution is valid only for a particular Ethereum account and so the solution is not susceptible to man-in-the-middle attacks. This also allows pools to operate without being easily cheated by the miners since pools can force miners to mine using the pool's address in the hash algo.
A keccak256 algorithm does not have to be used, but it is recommended since it is a cost effective one-way algorithm to perform in the EVM and simple to perform in solidity. The nonce is the solution that miners try to find and so it is part of the hashing algorithm. A challengeNumber is also part of the hash so that future blocks cannot be mined since it acts like a random piece of data that is not revealed until a mining round starts. The msg.sender address is part of the hash so that a nonce solution is valid only for a particular Ethereum account and so the solution is not susceptible to man-in-the-middle attacks. This also allows pools to operate without being easily cheated by the miners since pools can force miners to mine using the pool's address in the hash algo.
The economics of transferring electricity and hardware into mined token assets offers a flourishing community of decentralized miners the option to be involved in the Ethereum token economy directly. By voting with hashpower, an economically pegged asset to real-world resources, miners are incentivized to participate in early token trade to revamp initial costs, providing a bootstrapped stimulus mechanism between miners and early investors.

View File

@ -2,7 +2,7 @@
eip: 926
title: Address metadata registry
author: Nick Johnson <nick@ethereum.org>
type: Standards track
type: Standards Track
category: ERC
status: Draft
created: 2018-03-12

View File

@ -2,7 +2,7 @@
eip: 927
title: Generalised authorisations
author: Nick Johnson <nick@ethereum.org>
type: Standards track
type: Standards Track
category: ERC
status: Draft
created: 2018-03-12

1341
EIPS/eip-998.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,7 @@ GEM
commonmarker (0.17.9)
ruby-enum (~> 0.5)
concurrent-ruby (1.0.5)
eip_validator (0.4.0)
eip_validator (0.8.0)
activemodel
front_matter_parser (~> 0.1.1)
ethon (0.11.0)
@ -257,7 +257,7 @@ PLATFORMS
ruby
DEPENDENCIES
eip_validator (>= 0.4.0)
eip_validator (>= 0.8.0)
github-pages
html-proofer (>= 3.3.1)
jekyll (~> 3.6.2)

View File

@ -21,8 +21,14 @@ When you believe your EIP is mature and ready to progress past the draft phase,
- **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.
* **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).
# EIP Status Terms
* **Draft** - an EIP that is undergoing rapid iteration and changes
* **Last Call** - an EIP that is done with its initial iteration and ready for review by a wide audience
* **Accepted** - a core EIP that has been in Last Call for at least 2 weeks and any technical changes that were requested have been addressed by the author
* **Final (non-Core)** - an EIP that has been in Last Call for at least 2 weeks and any technical changes that were requested have been addressed by the author.
* **Final (Core)** - an EIP that the Core Devs have decide to implement and release in a future hard fork or has already been released in a hard fork
* **Deferred** - an EIP that is not being considered for immediate adoption. May be reconsidered in the future for a subsequent hard fork.
# Preferred Citation Format
The canonical URL for a EIP that has achieved draft status at any point is at https://eips.ethereum.org/. For example, the canonical URL for ERC-165 is https://eips.ethereum.org/EIPS/eip-165.

View File

@ -29,6 +29,9 @@ header_pages:
- erc.html
- informational.html
- meta.html
twitter:
card: summary
username: ethereum
# Build settings
markdown: kramdown

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
assets/eip-1283/state.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

148
assets/eip-712/Example.js Normal file
View File

@ -0,0 +1,148 @@
const ethUtil = require('ethereumjs-util');
const abi = require('ethereumjs-abi');
const chai = require('chai');
const typedData = {
types: {
EIP712Domain: [
{ name: 'name', type: 'string' },
{ name: 'version', type: 'string' },
{ name: 'chainId', type: 'uint256' },
{ name: 'verifyingContract', type: 'address' },
],
Person: [
{ name: 'name', type: 'string' },
{ name: 'wallet', type: 'address' }
],
Mail: [
{ name: 'from', type: 'Person' },
{ name: 'to', type: 'Person' },
{ name: 'contents', type: 'string' }
],
},
primaryType: 'Mail',
domain: {
name: 'Ether Mail',
version: '1',
chainId: 1,
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
},
message: {
from: {
name: 'Cow',
wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
},
to: {
name: 'Bob',
wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
},
contents: 'Hello, Bob!',
},
};
const types = typedData.types;
// Recursively finds all the dependencies of a type
function dependencies(primaryType, found = []) {
if (found.includes(primaryType)) {
return found;
}
if (types[primaryType] === undefined) {
return found;
}
found.push(primaryType);
for (let field of types[primaryType]) {
for (let dep of dependencies(field.type, found)) {
if (!found.includes(dep)) {
found.push(dep);
}
}
}
return found;
}
function encodeType(primaryType) {
// Get dependencies primary first, then alphabetical
let deps = dependencies(primaryType);
deps = deps.filter(t => t != primaryType);
deps = [primaryType].concat(deps.sort());
// Format as a string with fields
let result = '';
for (let type of deps) {
result += `${type}(${types[type].map(({ name, type }) => `${type} ${name}`).join(',')})`;
}
return result;
}
function typeHash(primaryType) {
return ethUtil.sha3(encodeType(primaryType));
}
function encodeData(primaryType, data) {
let encTypes = [];
let encValues = [];
// Add typehash
encTypes.push('bytes32');
encValues.push(typeHash(primaryType));
// Add field contents
for (let field of types[primaryType]) {
let value = data[field.name];
if (field.type == 'string' || field.type == 'bytes') {
encTypes.push('bytes32');
value = ethUtil.sha3(value);
encValues.push(value);
} else if (types[field.type] !== undefined) {
encTypes.push('bytes32');
value = ethUtil.sha3(encodeData(field.type, value));
encValues.push(value);
} else if (field.type.lastIndexOf(']') === field.type.length - 1) {
throw 'TODO: Arrays currently unimplemented in encodeData';
} else {
encTypes.push(field.type);
encValues.push(value);
}
}
return abi.rawEncode(encTypes, encValues);
}
function structHash(primaryType, data) {
return ethUtil.sha3(encodeData(primaryType, data));
}
function signHash() {
return ethUtil.sha3(
Buffer.concat([
Buffer.from('1901', 'hex'),
structHash('EIP712Domain', typedData.domain),
structHash(typedData.primaryType, typedData.message),
]),
);
}
const privateKey = ethUtil.sha3('cow');
const address = ethUtil.privateToAddress(privateKey);
const sig = ethUtil.ecsign(signHash(), privateKey);
const expect = chai.expect;
expect(encodeType('Mail')).to.equal('Mail(Person from,Person to,string contents)Person(string name,address wallet)');
expect(ethUtil.bufferToHex(typeHash('Mail'))).to.equal(
'0xa0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2',
);
expect(ethUtil.bufferToHex(encodeData(typedData.primaryType, typedData.message))).to.equal(
'0xa0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8',
);
expect(ethUtil.bufferToHex(structHash(typedData.primaryType, typedData.message))).to.equal(
'0xc52c0ee5d84264471806290a3f2c4cecfc5490626bf912d01f240d7a274b371e',
);
expect(ethUtil.bufferToHex(structHash('EIP712Domain', typedData.domain))).to.equal(
'0xf2cee375fa42b42143804025fc449deafd50cc031ca257e0b194a650a912090f',
);
expect(ethUtil.bufferToHex(signHash())).to.equal('0xbe609aee343fb3c4b28e1df9e632fca64fcfaede20f02e86244efddf30957bd2');
expect(ethUtil.bufferToHex(address)).to.equal('0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826');
expect(sig.v).to.equal(28);
expect(ethUtil.bufferToHex(sig.r)).to.equal('0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d');
expect(ethUtil.bufferToHex(sig.s)).to.equal('0x07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b91562');

106
assets/eip-712/Example.sol Normal file
View File

@ -0,0 +1,106 @@
pragma solidity ^0.4.24;
contract Example {
struct EIP712Domain {
string name;
string version;
uint256 chainId;
address verifyingContract;
}
struct Person {
string name;
address wallet;
}
struct Mail {
Person from;
Person to;
string contents;
}
bytes32 constant EIP712DOMAIN_TYPEHASH = keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
);
bytes32 constant PERSON_TYPEHASH = keccak256(
"Person(string name,address wallet)"
);
bytes32 constant MAIL_TYPEHASH = keccak256(
"Mail(Person from,Person to,string contents)Person(string name,address wallet)"
);
bytes32 DOMAIN_SEPARATOR;
constructor () public {
DOMAIN_SEPARATOR = hash(EIP712Domain({
name: "Ether Mail",
version: '1',
chainId: 1,
// verifyingContract: this
verifyingContract: 0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC
}));
}
function hash(EIP712Domain eip712Domain) internal pure returns (bytes32) {
return keccak256(abi.encode(
EIP712DOMAIN_TYPEHASH,
keccak256(bytes(eip712Domain.name)),
keccak256(bytes(eip712Domain.version)),
eip712Domain.chainId,
eip712Domain.verifyingContract
));
}
function hash(Person person) internal pure returns (bytes32) {
return keccak256(abi.encode(
PERSON_TYPEHASH,
keccak256(bytes(person.name)),
person.wallet
));
}
function hash(Mail mail) internal pure returns (bytes32) {
return keccak256(abi.encode(
MAIL_TYPEHASH,
hash(mail.from),
hash(mail.to),
keccak256(bytes(mail.contents))
));
}
function verify(Mail mail, uint8 v, bytes32 r, bytes32 s) internal view returns (bool) {
// Note: we need to use `encodePacked` here instead of `encode`.
bytes32 digest = keccak256(abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR,
hash(mail)
));
return ecrecover(digest, v, r, s) == mail.from.wallet;
}
function test() public view returns (bool) {
// Example signed message
Mail memory mail = Mail({
from: Person({
name: "Cow",
wallet: 0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826
}),
to: Person({
name: "Bob",
wallet: 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB
}),
contents: "Hello, Bob!"
});
uint8 v = 28;
bytes32 r = 0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d;
bytes32 s = 0x07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b91562;
assert(DOMAIN_SEPARATOR == 0xf2cee375fa42b42143804025fc449deafd50cc031ca257e0b194a650a912090f);
assert(hash(mail) == 0xc52c0ee5d84264471806290a3f2c4cecfc5490626bf912d01f240d7a274b371e);
assert(verify(mail, v, r, s));
return true;
}
}

BIN
assets/eip-712/eth_sign.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

View File

@ -1,6 +1,6 @@
| Variable | Symbol | Value | Unit | Source |
| -------------------|--------------|---------------|---------------|--------|
| Network Hashrate |H<sub>N</sub> | 232001 | GH/s | https://etherscan.io/chart/hashrate |
| Network Hashrate |H<sub>N</sub> | 296000 | GH/s | https://etherscan.io/chart/hashrate |
| GPU Hashrate |H<sub>M</sub> | 31.2 | MH/s | http://www.legitreviews.com/geforce-gtx-1070-ethereum-mining-small-tweaks-great-hashrate-low-power_195451 |
| GPU Power |P<sub>M</sub> | 110.6 | W | https://www.reddit.com/r/ethereum/comments/7vewys/10000_tons_co2_per_day_and_climbing_eip_858/dtrswyz/ |
@ -11,20 +11,14 @@ A baseline value for network power consumption can be found by multiplying the t
> P<sub>N</sub> = H<sub>N</sub> x P<sub>M</sub> / H<sub>M</sub>
>
> P<sub>N</sub> = 232001 (GH/s) x 110.6 (W) x 1000 (MH/GH) / ( 31.2 (MH/s) x 10^6 (W/MW) )
> P<sub>N</sub> = 296000 (GH/s) x 110.6 (W) x 1000 (MH/GH) / ( 31.2 (MH/s) x 10^6 (W/MW) )
>
> P<sub>N</sub> = 821 MW
> P<sub>N</sub> = 1049 MW
As a side note, people often confuse power (W) and energy (power x time, eg. Wh). For instance, assuming an average daily P<sub>Nd</sub> of 821 MW we can calculate that days Energy consumption by multiplying by the number of hours in a day.
As a side note, people often confuse power (W) and energy (power x time, eg. Wh). For instance, assuming an average daily P<sub>Nd</sub> of 1049 MW we can calculate that days Energy consumption by multiplying by the number of hours in a day.
> E<sub>Nd</sub> = P<sub>Nd</sub> x T<sub>d</sub>
>
> E<sub>Nd</sub> = 821 (MW) x 24 (h/d) / 1000 (GW/MW)
> E<sub>Nd</sub> = 1049 (MW) x 24 (h/d) / 1000 (GW/MW)
>
> E<sub>Nd</sub> = 19.7 GWh
## Network CO2 contribution
Work in progress

View File

@ -2,7 +2,7 @@
eip: <to be assigned>
title: <EIP title>
author: <a list of the author's or authors' name(s) and/or username(s), or name(s) and email(s), e.g. (use with the parentheses or triangular brackets): FirstName LastName (@GitHubUsername), FirstName LastName <foo@bar.com>, FirstName (@GitHubUsername) and GitHubUsername (@GitHubUsername)>
discussions-to: <email address>
discussions-to: <URL>
status: Draft
type: <Standards Track (Core, Networking, Interface, ERC) | Informational | Meta>
category (*only required for Standard Track): <Core | Networking | Interface | ERC>