mirror of https://github.com/status-im/EIPs.git
Merge branch 'master' into eip665
This commit is contained in:
commit
b2e0f8c575
|
@ -3,13 +3,16 @@ set -e # halt script on error
|
|||
|
||||
HTMLPROOFER_OPTIONS="./_site --internal-domains=eips.ethereum.org --check-html --check-opengraph --report-missing-names --log-level=:debug --assume-extension --empty-alt-ignore --url-ignore=/EIPS/eip-1,EIPS/eip-1,/EIPS/eip-107,/EIPS/eip-858"
|
||||
|
||||
bundle exec jekyll doctor
|
||||
bundle exec jekyll build
|
||||
|
||||
if [[ $TASK = 'htmlproofer' ]]; then
|
||||
bundle exec jekyll doctor
|
||||
bundle exec jekyll build
|
||||
bundle exec htmlproofer $HTMLPROOFER_OPTIONS --disable-external
|
||||
elif [[ $TASK = 'htmlproofer-external' ]]; then
|
||||
bundle exec jekyll doctor
|
||||
bundle exec jekyll build
|
||||
bundle exec htmlproofer $HTMLPROOFER_OPTIONS --external_only
|
||||
elif [[ $TASK = 'eip-validator' ]]; then
|
||||
bundle exec eip_validator EIPS/*.md
|
||||
fi
|
||||
|
||||
# Validate GH Pages DNS setup
|
||||
|
|
|
@ -20,6 +20,8 @@ matrix:
|
|||
env: TASK='htmlproofer'
|
||||
- rvm: 2.2.5
|
||||
env: TASK='htmlproofer-external'
|
||||
- rvm: 2.2.5
|
||||
env: TASK='eip-validator'
|
||||
allow_failures:
|
||||
- rvm: 2.2.5
|
||||
env: TASK='htmlproofer-external'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
eip: 162
|
||||
title: Initial ENS Hash Registrar
|
||||
author: Maurelian and Nick Johnson
|
||||
author: Maurelian, Nick Johnson <nick@ethereum.org>, Alex Van de Sande <avsa@ethereum.org>
|
||||
status: Final
|
||||
type: Standards Track
|
||||
category: ERC
|
||||
|
@ -39,7 +39,7 @@ For more background, refer to [EIP 137](https://github.com/ethereum/EIPs/issues/
|
|||
|
||||
A well designed and governed registrar is essential to the success of the ENS described in EIP 137, but is described separately in this document as it is external to the core ENS protocol.
|
||||
|
||||
In order to maximize utility and adoption of a new namespace, the registrar should mitigate speculation and "name squatting", however the best approach for mitigation is unclear. Thus an "initial" registrar is proposed, which implements a simple approach to name allocation. During the initial period, the available namespace will be significantly restricted to the `.eth` top level domain, and subdomain shorter than 7 characters in length disallowed. This specification largely describes @alexvandesande and @arachnid's [hash registrar implementation](https://github.com/Arachnid/ens/blob/master/HashRegistrarSimplified.sol) in order to facilitate discussion.
|
||||
In order to maximize utility and adoption of a new namespace, the registrar should mitigate speculation and "name squatting", however the best approach for mitigation is unclear. Thus an "initial" registrar is proposed, which implements a simple approach to name allocation. During the initial period, the available namespace will be significantly restricted to the `.eth` top level domain, and subdomain shorter than 7 characters in length disallowed. This specification largely describes @alexvandesande and @arachnid's [hash registrar implementation](https://github.com/ethereum/ens/blob/mainnet/contracts/HashRegistrarSimplified.sol) in order to facilitate discussion.
|
||||
|
||||
The intent is to replace the Initial Registrar contract with a permanent registrar contract. The Permanent Registrar will increase the available namespace, and incorporate lessons learned from the performance of the Initial Registrar. This upgrade is expected to take place within approximately 2 years of initial deployment.
|
||||
|
||||
|
@ -237,7 +237,7 @@ This approach is simpler than the familiar model of requiring owners to make rec
|
|||
This document borrows heavily from several sources:
|
||||
- [EIP 137](https://github.com/ethereum/EIPs/issues/137) outlines the initial implementation of the Registry Contract (ENS.sol) and associated Resolver contracts.
|
||||
- [ERC 26](https://github.com/ethereum/EIPs/issues/26) was the first ERC to propose a name service at the contract layer
|
||||
- @alexvandesande's current implementation of the [HashRegistrar](https://github.com/Arachnid/ens/blob/master/HashRegistrarSimplified.sol)
|
||||
- @alexvandesande's current implementation of the [HashRegistrar](https://github.com/ethereum/ens/blob/mainnet/contracts/HashRegistrarSimplified.sol)
|
||||
|
||||
### Edits:
|
||||
- 2016-10-26 Added link Alex's design in abstract
|
||||
|
|
|
@ -93,4 +93,4 @@ Support for ERC190 is either implemented or in progress for the following:
|
|||
* [Dapple](http://dapple.readthedocs.io/en/master/)
|
||||
* [Eris PM](https://github.com/eris-ltd/eris-cli)
|
||||
* [Embark](https://github.com/iurimatias/embark-framework)
|
||||
* [Browser Solidity](https://github.com/ethereum/browser-solidity/issues/386)
|
||||
* [Browser Solidity](https://github.com/ethereum/remix-ide/issues/386)
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
---
|
||||
eip: 198
|
||||
title: Big integer modular exponentiation
|
||||
author: Vitalik Buterin <v@buterin.com>
|
||||
status: Final
|
||||
type: Standards Track
|
||||
category: Core
|
||||
created: 2017-01-30
|
||||
---
|
||||
|
||||
# Parameters
|
||||
|
||||
* `GQUADDIVISOR: 20`
|
||||
|
||||
# Specification
|
||||
|
||||
At address 0x00......05, add a precompile that expects input in the following format:
|
||||
|
||||
<length_of_BASE> <length_of_EXPONENT> <length_of_MODULUS> <BASE> <EXPONENT> <MODULUS>
|
||||
|
||||
Where every length is a 32-byte left-padded integer representing the number of bytes to be taken up by the next value. Call data is assumed to be infinitely right-padded with zero bytes, and excess data is ignored. Consumes `floor(mult_complexity(max(length_of_MODULUS, length_of_BASE)) * max(ADJUSTED_EXPONENT_LENGTH, 1) / GQUADDIVISOR)` gas, and if there is enough gas, returns an output `(BASE**EXPONENT) % MODULUS` as a byte array with the same length as the modulus.
|
||||
|
||||
`ADJUSTED_EXPONENT_LENGTH` is defined as follows.
|
||||
|
||||
* If `length_of_EXPONENT <= 32`, and all bits in `EXPONENT` are 0, return 0
|
||||
* If `length_of_EXPONENT <= 32`, then return the index of the highest bit in `EXPONENT` (eg. 1 -> 0, 2 -> 1, 3 -> 1, 255 -> 7, 256 -> 8).
|
||||
* If `length_of_EXPONENT > 32`, then return `8 * (length_of_EXPONENT - 32)` plus the index of the highest bit in the first 32 bytes of `EXPONENT` (eg. if `EXPONENT = \x00\x00\x01\x00.....\x00`, with one hundred bytes, then the result is 8 * (100 - 32) + 253 = 797). If all of the first 32 bytes of `EXPONENT` are zero, return exactly `8 * (length_of_EXPONENT - 32)`.
|
||||
|
||||
`mult_complexity` is a function intended to approximate the difficulty of Karatsuba multiplication (used in all major bigint libraries) and is defined as follows.
|
||||
|
||||
```
|
||||
def mult_complexity(x):
|
||||
if x <= 64: return x ** 2
|
||||
elif x <= 1024: return x ** 2 // 4 + 96 * x - 3072
|
||||
else: return x ** 2 // 16 + 480 * x - 199680
|
||||
```
|
||||
|
||||
For example, the input data:
|
||||
|
||||
0000000000000000000000000000000000000000000000000000000000000001
|
||||
0000000000000000000000000000000000000000000000000000000000000020
|
||||
0000000000000000000000000000000000000000000000000000000000000020
|
||||
03
|
||||
fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e
|
||||
fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
|
||||
|
||||
Represents the exponent `3**(2**256 - 2**32 - 978) % (2**256 - 2**32 - 977)`. By Fermat's little theorem, this equals 1, so the result is:
|
||||
|
||||
0000000000000000000000000000000000000000000000000000000000000001
|
||||
|
||||
Returned as 32 bytes because the modulus length was 32 bytes. The `ADJUSTED_EXPONENT_LENGTH` would be 255, and the gas cost would be `mult_complexity(32) * 255 / 20 = 13056` gas (note that this is ~8 times the cost of using the EXP opcode to compute a 32-byte exponent). A 4096-bit RSA exponentiation would cost `mult_complexity(512) * 4095 / 100 = 22853376` gas in the worst case, though RSA verification in practice usually uses an exponent of 3 or 65537, which would reduce the gas consumption to 5580 or 89292, respectively.
|
||||
|
||||
This input data:
|
||||
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000020
|
||||
0000000000000000000000000000000000000000000000000000000000000020
|
||||
fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e
|
||||
fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
|
||||
|
||||
Would be parsed as a base of 0, exponent of `2**256 - 2**32 - 978` and modulus of `2**256 - 2**32 - 977`, and so would return 0. Notice how if the length_of_BASE is 0, then it does not interpret _any_ data as the base, instead immediately interpreting the next 32 bytes as EXPONENT.
|
||||
|
||||
This input data:
|
||||
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000020
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe
|
||||
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd
|
||||
|
||||
Would parse a base length of 0, a exponent length of 32, and an exponent length of `2**256 - 1`, where the base is empty, the exponent is `2**256 - 2` and the modulus is `(2**256 - 3) * 256**(2**256 - 33)` (yes, that's a really big number). It would then immediately fail, as it's not possible to provide enough gas to make that computation.
|
||||
|
||||
This input data:
|
||||
|
||||
0000000000000000000000000000000000000000000000000000000000000001
|
||||
0000000000000000000000000000000000000000000000000000000000000002
|
||||
0000000000000000000000000000000000000000000000000000000000000020
|
||||
03
|
||||
ffff
|
||||
8000000000000000000000000000000000000000000000000000000000000000
|
||||
07
|
||||
|
||||
Would parse as a base of 3, an exponent of 65535, and a modulus of `2**255`, and it would ignore the remaining 0x07 byte.
|
||||
|
||||
This input data:
|
||||
|
||||
0000000000000000000000000000000000000000000000000000000000000001
|
||||
0000000000000000000000000000000000000000000000000000000000000002
|
||||
0000000000000000000000000000000000000000000000000000000000000020
|
||||
03
|
||||
ffff
|
||||
80
|
||||
|
||||
Would also parse as a base of 3, an exponent of 65535 and a modulus of `2**255`, as it attempts to grab 32 bytes for the modulus starting from 0x80, but then there is no further data so it right pads it with 31 zeroes.
|
||||
|
||||
# Rationale
|
||||
|
||||
This allows for efficient RSA verification inside of the EVM, as well as other forms of number theory-based cryptography. Note that adding precompiles for addition and subtraction is not required, as the in-EVM algorithm is efficient enough, and multiplication can be done through this precompile via `a * b = ((a + b)**2 - (a - b)**2) / 4`.
|
||||
|
||||
The bit-based exponent calculation is done specifically to fairly charge for the often-used exponents of 2 (for multiplication) and 3 and 65537 (for RSA verification).
|
||||
|
||||
# Copyright
|
||||
|
||||
Copyright and related rights waived via CC0.
|
|
@ -123,4 +123,4 @@ Note that the input to the Keccak256 hash is the lowercase hexadecimal string (i
|
|||
2. Python example by @Recmo https://github.com/ethereum/eips/issues/55#issuecomment-261521584
|
||||
3. Python implementation in [`ethereum-utils`](https://github.com/pipermerriam/ethereum-utils#to_checksum_addressvalue---text)
|
||||
4. Ethereumjs-util implementation https://github.com/ethereumjs/ethereumjs-util/blob/75f529458bc7dc84f85fd0446d0fac92d991c262/index.js#L452-L466
|
||||
5. Swift implementation in [`EthereumKit`](https://github.com/yuzushioh/EthereumKit/blob/master/EthereumKit/EIP55.swift)
|
||||
5. Swift implementation in [`EthereumKit`](https://github.com/yuzushioh/EthereumKit/blob/master/EthereumKit/Helper/EIP55.swift)
|
||||
|
|
|
@ -103,7 +103,7 @@ Extended operations other than XSHUFFLE and XCAST are only valid on vectors of t
|
|||
|
||||
### Subroutines
|
||||
|
||||
If [EIP 187](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-187.md) is accepted a typpe-safe syntax for declaring subroutines taking vector arguments will be needed.
|
||||
If [EIP 187](https://github.com/ethereum/EIPs/pull/187) is accepted a type-safe syntax for declaring subroutines taking vector arguments will be needed.
|
||||
|
||||
* `BEGINSUBX n_args, arg_types... n_results, result_types...`
|
||||
marks the **single** entry to a subroutine. `n_args` items are taken off of the stack at entry to, and `n_results` items are placed on the stack at return from the subroutine. `n_args` and `n_results` are given as one immediate byte each. The `arg_types` and `result_types` are given in the same encoding as second byte of the SIMD opcodes, and must match the values on the stack. The bytecode for a subroutine ends at the next `BEGINSUB`, `BEGINSUBX` or `BEGINDATA` instruction or at the end of the bytecode.
|
||||
|
@ -129,7 +129,7 @@ divide | 15 _N_**2 + 119 _N_ + 111 | 409 | 827 | 2023
|
|||
|
||||
The remaining operations are of about the same complexity as addition and subtraction, or less. Given that JUMPDEST is a no-op, and is assigned a gas price of 1, this can be taken as the overhead of the interpreter. All of the arithmetic operations are assigned the same gas price of 5, for a remaining runtime of 4. The interpreter loop itself takes about 6 to 8 C instructions, so ADD and SUB are reasonably priced, but MUL is some 5 to 21 times slower than ADD or SUB, and DIV is some 15 to 23 times slower, so they are clearly mispriced.
|
||||
|
||||
By comparison, on most [Intel](https://software.intel.com/sites/landingpage/IntrinsicsGuide) and [ARM](https://developer.arm.com/docs/100166_0001/latest/programmers-model/instruction-set-summary/table-of-processor-instructions) SIMD units instructions take approximately the following cycle counts, independent of register width.
|
||||
By comparison, on most [Intel](https://software.intel.com/sites/landingpage/IntrinsicsGuide) and [ARM](https://developer.arm.com/docs/100166/latest/programmers-model/instruction-set-summary/table-of-processor-instructions) SIMD units instructions take approximately the following cycle counts, independent of register width.
|
||||
|
||||
operation | Intel cycles | ARM cycles | gas
|
||||
-|-|-|-
|
||||
|
|
|
@ -67,7 +67,7 @@ The Yellow Paper implements EIP-649 in [#333](https://github.com/ethereum/yellow
|
|||
Other notable implementations:
|
||||
|
||||
- Eth-Isabelle [#459](https://github.com/pirapira/eth-isabelle/issues/459)
|
||||
- Py-EVM [#123](https://github.com/pipermerriam/py-evm/pull/123)
|
||||
- Py-EVM [#123](https://github.com/ethereum/py-evm/pull/123)
|
||||
|
||||
## Copyright
|
||||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
eip: 778
|
||||
title: Ethereum Node Records (ENR)
|
||||
author: Felix Lange <fjl@ethereum.org>
|
||||
type: Standard Track
|
||||
type: Standards Track
|
||||
category: Networking
|
||||
status: Draft
|
||||
created: 2017-11-23
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
---
|
||||
eip: 86
|
||||
title: Abstraction of transaction origin and signature
|
||||
author: Vitalik Buterin
|
||||
type: Standards Track
|
||||
category: Core
|
||||
status: Draft
|
||||
created: 2017-02-10
|
||||
---
|
||||
|
||||
# Summary
|
||||
|
||||
Implements a set of changes that serve the combined purpose of "abstracting out" signature verification and nonce checking, allowing users to create "account contracts" that perform any desired signature/nonce checks instead of using the mechanism that is currently hard-coded into transaction processing.
|
||||
|
||||
# Parameters
|
||||
|
||||
* METROPOLIS_FORK_BLKNUM: TBD
|
||||
* CHAIN_ID: same as used for EIP 155 (ie. 1 for mainnet, 3 for testnet)
|
||||
* NULL_SENDER: 2**160 - 1
|
||||
|
||||
# Specification
|
||||
|
||||
If `block.number >= METROPOLIS_FORK_BLKNUM`, then:
|
||||
1. If the signature of a transaction is `(CHAIN_ID, 0, 0)` (ie. `r = s = 0`, `v = CHAIN_ID`), then treat it as valid and set the sender address to `NULL_SENDER`
|
||||
2. Transactions of this form MUST have gasprice = 0, nonce = 0, value = 0, and do NOT increment the nonce of account NULL_SENDER.
|
||||
3. Create a new opcode at `0xfb`, `CREATE2`, with 4 stack arguments (value, salt, mem_start, mem_size) which sets the creation address to `sha3(sender + salt + sha3(init code)) % 2**160`, where `salt` is always represented as a 32-byte value.
|
||||
4. Add to _all_ contract creation operations, including transactions and opcodes, the rule that if a contract at that address already exists and has non-empty code OR non-empty nonce, the operation fails and returns 0 as if the init code had run out of gas. If an account has empty code and nonce but nonempty balance, the creation operation may still succeed.
|
||||
|
||||
# Rationale
|
||||
|
||||
The goal of these changes is to set the stage for abstraction of account security. Instead of having an in-protocol mechanism where ECDSA and the default nonce scheme are enshrined as the only "standard" way to secure an account, we take initial steps toward a model where in the long term all accounts are contracts, contracts can pay for gas, and users are free to define their own security model.
|
||||
|
||||
Under EIP 86, we can expect users to store their ether in contracts, whose code might look like the following (example in Serpent):
|
||||
|
||||
```python
|
||||
# Get signature from tx data
|
||||
sig_v = ~calldataload(0)
|
||||
sig_r = ~calldataload(32)
|
||||
sig_s = ~calldataload(64)
|
||||
# Get tx arguments
|
||||
tx_nonce = ~calldataload(96)
|
||||
tx_to = ~calldataload(128)
|
||||
tx_value = ~calldataload(160)
|
||||
tx_gasprice = ~calldataload(192)
|
||||
tx_data = string(~calldatasize() - 224)
|
||||
~calldataload(tx_data, 224, ~calldatasize())
|
||||
# Get signing hash
|
||||
signing_data = string(~calldatasize() - 64)
|
||||
~mstore(signing_data, tx.startgas)
|
||||
~calldataload(signing_data + 32, 96, ~calldatasize() - 96)
|
||||
signing_hash = sha3(signing_data:str)
|
||||
# Perform usual checks
|
||||
prev_nonce = ~sload(-1)
|
||||
assert tx_nonce == prev_nonce + 1
|
||||
assert self.balance >= tx_value + tx_gasprice * tx.startgas
|
||||
assert ~ecrecover(signing_hash, sig_v, sig_r, sig_s) == <pubkey hash here>
|
||||
# Update nonce
|
||||
~sstore(-1, prev_nonce + 1)
|
||||
# Pay for gas
|
||||
~send(MINER_CONTRACT, tx_gasprice * tx.startgas)
|
||||
# Make the main call
|
||||
~call(msg.gas - 50000, tx_to, tx_value, tx_data, len(tx_data), 0, 0)
|
||||
# Get remaining gas payments back
|
||||
~call(20000, MINER_CONTRACT, 0, [msg.gas], 32, 0, 0)
|
||||
```
|
||||
|
||||
This can be thought of as a "forwarding contract". It accepts data from the "entry point" address 2**160 - 1 (an account that anyone can send transactions from), expecting that data to be in the format `[sig, nonce, to, value, gasprice, data]`. The forwarding contract verifies the signature, and if the signature is correct it sets up a payment to the miner and then sends a call to the desired address with the provided value and data.
|
||||
|
||||
The benefits that this provides lie in the most interesting cases:
|
||||
|
||||
- **Multisig wallets**: currently, sending from a multisig wallet requires each operation to be ratified by the participants, and each ratification is a transaction. This could be simplified by having one ratification transaction include signatures from the other participants, but even still it introduces complexity because the participants' accounts all need to be stocked up with ETH. With this EIP, it will be possible to just have the contract store the ETH, send a transaction containing all signatures to the contract directly, and the contract can pay the fees.
|
||||
- **Ring signature mixers**: the way that ring signature mixers work is that N individuals send 1 coin into a contract, and then use a linkable ring signature to withdraw 1 coin later on. The linkable ring signature ensures that the withdrawal transaction cannot be linked to the deposit, but if someone attempts to withdraw twice then those two signatures can be linked and the second one prevented. However, currently there is a privacy risk: to withdraw, you need to have coins to pay for gas, and if these coins are not properly mixed then you risk compromising your privacy. With this EIP, you can pay for gas straight our of your withdrawn coins.
|
||||
- **Custom cryptography**: users can upgrade to ed25519 signatures, Lamport hash ladder signatures or whatever other scheme they want on their own terms; they do not need to stick with ECDSA.
|
||||
- **Non-cryptographic modifications**: users can require transactions to have expiry times (this being standard would allow old empty/dust accounts to be flushed from the state securely), use k-parallelizable nonces (a scheme that allows transactions to be confirmed slightly out-of-order, reducing inter-transaction dependence), or make other modifications.
|
||||
|
||||
(2) and (3) introduce a feature similar to bitcoin's P2SH, allowing users to send funds to addresses that provably map to only one particular piece of code. Something like this is crucial in the long term because, in a world where all accounts are contracts, we need to preserve the ability to send to an account before that account exists on-chain, as that's a basic functionality that exists in all blockchain protocols today.
|
||||
|
||||
# Miner and transaction replaying strategy
|
||||
|
||||
Note that miners would need to have a strategy for accepting these transactions. This strategy would need to be very discriminating, because otherwise they run the risk of accepting transactions that do not pay them any fees, and possibly even transactions that have no effect (eg. because the transaction was already included and so the nonce is no longer current).
|
||||
|
||||
One simple strategy is to have a set of regexps that the to address of an account would be checked against, each regexp corresponding to a "standard account type" which is known to be "safe" (in the sense that if an account has that code, and a particular check involving the account balances, account storage and transaction data passes, then if the transaction is included in a block the miner will get paid), and mine and relay transactions that pass these checks.
|
||||
|
||||
One example would be to check as follows:
|
||||
|
||||
1. Check that the to address has code which is the compiled version of the Serpent code above, with `<pubkey hash here>` replaced with any public key hash.
|
||||
2. Check that the signature in the transaction data verifies with that key hash.
|
||||
3. Check that the gasprice in the transaction data is sufficiently high
|
||||
4. Check that the nonce in the state matches the nonce in the transaction data
|
||||
5. Check that there is enough ether in the account to pay for the fee
|
||||
|
||||
If all five checks pass, relay and/or mine the transaction.
|
||||
|
||||
A looser but still effective strategy would be to accept any code that fits the same general format as the above, consuming only a limited amount of gas to perform nonce and signature checks and having a guarantee that transaction fees will be paid to the miner. Another strategy is to, alongside other approaches, try to process any transaction that asks for less than 250,000 gas, and include it only if the miner's balance is appropriately higher after executing the transaction than before it.
|
||||
|
||||
# Copyright
|
||||
|
||||
Copyright and related rights waived via CC0.
|
|
@ -0,0 +1,108 @@
|
|||
---
|
||||
eip: 900
|
||||
title: Simple Staking Interface
|
||||
author: Dean Eigenmann <dean@tokenate.io>, Jorge Izquierdo <jorge@aragon.one>
|
||||
type: Standards Track
|
||||
category: ERC
|
||||
status: Draft
|
||||
created: 2018-02-22
|
||||
discussions-to: https://github.com/ethereum/EIPs/issues/900
|
||||
---
|
||||
|
||||
## Abstract
|
||||
|
||||
The following standard describes a common staking interface allowing for easy to use staking systems. The interface is kept simple allowing for various use cases to be implemented. This standard describes the common functionality for staking as well as providing information on stakes.
|
||||
|
||||
## Motivation
|
||||
|
||||
As we move to more token models, having a common staking interface which is familiar to users can be useful. The common interface can be used by a variety of applications, this common interface could be beneficial especially to things like Token curated registries which have recently gained popularity.
|
||||
|
||||
## Specification
|
||||
|
||||
```solidity
|
||||
interface Staking {
|
||||
|
||||
event Staked(address indexed user, uint256 amount, uint256 total, bytes data);
|
||||
event Unstaked(address indexed user, uint256 amount, uint256 total, bytes data);
|
||||
|
||||
function stake(uint256 amount, bytes data) public;
|
||||
function stakeFor(address user, uint256 amount, bytes data) public;
|
||||
function unstake(uint256 amount, bytes data) public;
|
||||
function totalStakedFor(address addr) public view returns (uint256);
|
||||
function totalStaked() public view returns (uint256);
|
||||
function token() public view returns (address);
|
||||
function supportsHistory() public pure returns (bool);
|
||||
|
||||
// optional
|
||||
function lastStakedFor(address addr) public view returns (uint256);
|
||||
function totalStakedForAt(address addr, uint256 blockNumber) public view returns (uint256);
|
||||
function totalStakedAt(uint256 blockNumber) public view returns (uint256);
|
||||
}
|
||||
```
|
||||
|
||||
### stake
|
||||
|
||||
Stakes a certain amount of tokens, this MUST transfer the given amount from the user.
|
||||
|
||||
*The data field can be used to add signalling information in more complex staking applications*
|
||||
|
||||
MUST trigger ```Staked``` event.
|
||||
|
||||
### stakeFor
|
||||
|
||||
Stakes a certain amount of tokens, this MUST transfer the given amount from the caller.
|
||||
|
||||
*The data field can be used to add signalling information in more complex staking applications*
|
||||
|
||||
MUST trigger ```Staked``` event.
|
||||
|
||||
### unstake
|
||||
|
||||
Unstakes a certain amount of tokens, this SHOULD return the given amount of tokens to the user, if unstaking is currently not possible the function MUST revert.
|
||||
|
||||
*The data field can be used to remove signalling information in more complex staking applications*
|
||||
|
||||
MUST trigger ```Unstaked``` event.
|
||||
|
||||
### totalStakedFor
|
||||
|
||||
Returns the current total of tokens staked for an address.
|
||||
|
||||
### totalStaked
|
||||
|
||||
Returns the current total of tokens staked.
|
||||
|
||||
### token
|
||||
|
||||
Address of the token being used by the staking interface.
|
||||
|
||||
### supportsHistory
|
||||
|
||||
MUST return true if the optional history functions are implemented, otherwise false.
|
||||
|
||||
### lastStakedFor
|
||||
|
||||
***OPTIONAL:** As not all staking systems require a complete history, this function is optional.*
|
||||
|
||||
Returns last block address staked at.
|
||||
|
||||
### totalStakedForAt
|
||||
|
||||
***OPTIONAL:** As not all staking systems require a complete history, this function is optional.*
|
||||
|
||||
Returns total amount of tokens staked at block for address.
|
||||
|
||||
### totalStakedAt
|
||||
|
||||
***OPTIONAL:** As not all staking systems require a complete history, this function is optional.*
|
||||
|
||||
Returns the total tokens staked at block.
|
||||
|
||||
## Implementation
|
||||
|
||||
- [Stakebank](https://github.com/HarbourProject/stakebank)
|
||||
- [Aragon](https://github.com/aragon/aragon-apps/pull/101)
|
||||
- [PoS Staking](https://github.com/maticnetwork/contracts/blob/master/contracts/StakeManager.sol)
|
||||
|
||||
## Copyright
|
||||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|
2
Gemfile
2
Gemfile
|
@ -30,3 +30,5 @@ gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
|||
gem "wdm", "~> 0.1.0" if Gem.win_platform?
|
||||
|
||||
gem "html-proofer", '>=3.3.1'
|
||||
|
||||
gem "eip_validator", ">=0.4.0"
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
activemodel (4.2.9)
|
||||
activesupport (= 4.2.9)
|
||||
builder (~> 3.1)
|
||||
activesupport (4.2.9)
|
||||
i18n (~> 0.7)
|
||||
minitest (~> 5.1)
|
||||
|
@ -8,6 +11,7 @@ GEM
|
|||
tzinfo (~> 1.1)
|
||||
addressable (2.5.2)
|
||||
public_suffix (>= 2.0.2, < 4.0)
|
||||
builder (3.2.3)
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
execjs
|
||||
|
@ -17,6 +21,9 @@ GEM
|
|||
commonmarker (0.17.9)
|
||||
ruby-enum (~> 0.5)
|
||||
concurrent-ruby (1.0.5)
|
||||
eip_validator (0.4.0)
|
||||
activemodel
|
||||
front_matter_parser (~> 0.1.1)
|
||||
ethon (0.11.0)
|
||||
ffi (>= 1.3.0)
|
||||
execjs (2.7.0)
|
||||
|
@ -24,6 +31,7 @@ GEM
|
|||
multipart-post (>= 1.2, < 3)
|
||||
ffi (1.9.23)
|
||||
forwardable-extended (2.6.0)
|
||||
front_matter_parser (0.1.1)
|
||||
gemoji (3.0.0)
|
||||
github-pages (179)
|
||||
activesupport (= 4.2.9)
|
||||
|
@ -249,6 +257,7 @@ PLATFORMS
|
|||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
eip_validator (>= 0.4.0)
|
||||
github-pages
|
||||
html-proofer (>= 3.3.1)
|
||||
jekyll (~> 3.6.2)
|
||||
|
|
70
README.md
70
README.md
|
@ -1,6 +1,8 @@
|
|||
# EIPs [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ethereum/EIPs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
Ethereum Improvement Proposals (EIPs) describe standards for the Ethereum platform, including core protocol specifications, client APIs, and contract standards.
|
||||
|
||||
A browsable version of all current and draft EIPs can be found on [the official EIP site](http://eips.ethereum.org/).
|
||||
|
||||
# Contributing
|
||||
First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP to it. There is a [template EIP here](eip-X.md). Then submit a Pull Request to Ethereum's [EIPs repository](https://github.com/ethereum/EIPs).
|
||||
|
||||
|
@ -9,71 +11,3 @@ First review [EIP-1](EIPS/eip-1.md). Then clone the repository and add your EIP
|
|||
* **Accepted** - an EIP that is planned for immediate adoption, i.e. expected to be included in the next hard fork (for Core/Consensus layer EIPs).
|
||||
* **Final** - an EIP that has been adopted in a previous hard fork (for Core/Consensus layer EIPs).
|
||||
* **Deferred** - an EIP that is not being considered for immediate adoption. May be reconsidered in the future for a subsequent hard fork.
|
||||
|
||||
# Non-final EIPs
|
||||
| Number | Title | Author | Layer | Status |
|
||||
| ------------------------- | ------------------------------------------------------- | ----------------------------- | --------- | ---------- |
|
||||
| [3](EIPS/eip-3.md) | Addition of CALLDEPTH opcode | Martin Holst Swende | Core | Draft |
|
||||
| [4](EIPS/eip-4.md) | EIP Classification | Joseph Chow | Meta | Draft |
|
||||
| [5](EIPS/eip-5.md) | Gas Usage for `RETURN` and `CALL*` | Christian Reitwiessner | Core | Draft |
|
||||
| [101](EIPS/eip-101.md) | Serenity Currency and Crypto Abstraction | Vitalik Buterin | | Active |
|
||||
| [158](EIPS/eip-158.md) | State clearing | Vitalik Buterin | Core | Superseded |
|
||||
| [165](EIPS/eip-165.md) | ERC-165 Standard Interface Detection | Christian Reitwiessner | Interface | Draft |
|
||||
| [234](EIPS/eip-234.md) | Add `blockHash` to JSON-RPC filter options | Micah Zoltu | Interface | Draft |
|
||||
| [615](EIPS/eip-615.md) | Subroutines and Static Jumps for the EVM | Greg Colvin | Core | Draft |
|
||||
| [616](EIPS/eip-616.md) | SIMD Operations for the EVM | Greg Colvin | Core | Draft |
|
||||
| [681](EIPS/eip-681.md) | ERC-681 URL Format for Transaction Requests | Daniel A. Nagy | Interface | Draft |
|
||||
| [758](EIPS/eip-758.md) | Subscriptions and filters for transaction return data | Jack Peterson | Interface | Draft |
|
||||
| [801](EIPS/eip-801.md) | ERC-801 Canary Standard | ligi | Interface | Draft |
|
||||
|
||||
# Deferred EIPs
|
||||
| Number | Title | Author | Layer | Status |
|
||||
| -------------------------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------ | ---------- | -------- |
|
||||
| [86](https://github.com/ethereum/EIPs/pull/208) | Abstraction of transaction origin and signature | Vitalik Buterin | Core | Deferred (to be replaced) |
|
||||
| [96](https://github.com/ethereum/EIPs/pull/210) | Blockhash refactoring | Vitalik Buterin | Core | Deferred |
|
||||
| [145](EIPS/eip-145.md) | Bitwise shifting instructions in EVM | Alex Beregszaszi, Paweł Bylica | Core | Deferred |
|
||||
|
||||
# Finalized EIPs (standards that have been adopted)
|
||||
| Number | Title | Author | Layer | Status |
|
||||
| -------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------| ---------- | -------- |
|
||||
| [2](EIPS/eip-2.md) | Homestead Hard-fork Changes | Vitalik Buterin | Core | Final |
|
||||
| [6](EIPS/eip-6.md) | Renaming Suicide Opcode | Hudson Jameson | Interface | Final |
|
||||
| [7](EIPS/eip-7.md) | DELEGATECALL | Vitalik Buterin | Core | Final |
|
||||
| [8](EIPS/eip-8.md) | devp2p Forward Compatibility Requirements for Homestead | Felix Lange | Networking | Final |
|
||||
| [20](EIPS/eip-20-token-standard.md) | ERC-20 Token Standard | Fabian Vogelsteller, Vitalik Buterin | ERC | Final |
|
||||
| [55](EIPS/eip-55.md) | ERC-55 Mixed-case checksum address encoding | Vitalik Buterin | ERC | Final |
|
||||
| [100](https://github.com/ethereum/EIPs/issues/100) | Change difficulty adjustment to target mean block time including uncles | Vitalik Buterin | Core | Final |
|
||||
| [137](EIPS/eip-137.md) | Ethereum Domain Name Service - Specification | Nick Johnson | ERC | Final |
|
||||
| [140](https://github.com/ethereum/EIPs/pull/206) | REVERT instruction | Alex Beregszaszi, Nikolai Mushegian | Core | Final |
|
||||
| [141](EIPS/eip-141.md) | Designated invalid EVM instruction | Alex Beregszaszi | Core | Final |
|
||||
| [150](EIPS/eip-150.md) | Gas cost changes for IO-heavy operations | Vitalik Buterin | Core | Final |
|
||||
| [155](EIPS/eip-155.md) | Simple replay attack protection | Vitalik Buterin | Core | Final |
|
||||
| [160](EIPS/eip-160.md) | EXP cost increase | Vitalik Buterin | Core | Final |
|
||||
| [161](EIPS/eip-161.md) | State trie clearing (invariant-preserving alternative) | Gavin Wood | Core | Final |
|
||||
| [162](EIPS/eip-162.md) | ERC-162 Initial ENS Hash Registrar | Maurelian, Nick Johnson | ERC | Final |
|
||||
| [170](EIPS/eip-170.md) | Contract code size limit | Vitalik Buterin | Core | Final |
|
||||
| [181](EIPS/eip-181.md) | ERC-181 ENS support for reverse resolution of Ethereum addresses | Nick Johnson | ERC | Final |
|
||||
| [190](EIPS/eip-190.md) | ERC-190 Ethereum Smart Contract Packaging Standard | Merriam, Coulter, Erfurt, Catalano, Matias | ERC | Final |
|
||||
| [196](https://github.com/ethereum/EIPs/pull/213) | Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 | Christian Reitwiessner | Core | Final |
|
||||
| [197](https://github.com/ethereum/EIPs/pull/212) | Precompiled contracts for optimal Ate pairing check on the elliptic curve alt_bn128 | Vitalik Buterin, Christian Reitwiessner | Core | Final |
|
||||
| [198](https://github.com/ethereum/EIPs/pull/198) | Precompiled contract for bigint modular exponentiation | Vitalik Buterin | Core | Final |
|
||||
| [211](https://github.com/ethereum/EIPs/pull/211) | New opcodes: RETURNDATASIZE and RETURNDATACOPY | Christian Reitwiessner | Core | Final |
|
||||
| [214](https://github.com/ethereum/EIPs/pull/214) | New opcode STATICCALL | Vitalik Buterin, Christian Reitwiessner | Core | Final |
|
||||
| [649](https://github.com/ethereum/EIPs/pull/669) | Metropolis Difficulty Bomb Delay and Block Reward Reduction | Afri Schoedon, Vitalik Buterin | Core | Final |
|
||||
| [658](https://github.com/ethereum/EIPs/pull/658) | Embedding transaction status code in receipts | Nick Johnson | Core | Final |
|
||||
| [706](EIPS/eip-706.md) | DEVp2p snappy compression | Péter Szilágyi | Networking | Final |
|
||||
|
||||
# Active EIPs (standards that have been adopted but never meant to be completed)
|
||||
|
||||
| Number | Title | Author | Layer | Status |
|
||||
| -------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------| ---------- | -------- |
|
||||
| [1](EIPS/eip-1.md) | EIP Purpose and Guidelines | Martin Becze, Hudson Jameson | Meta | Active |
|
||||
|
||||
# Past Hard Forks
|
||||
| Codename | Aliases | Block number | Date (UTC) |
|
||||
|-------------------------------------- |---------------------------- |----------------|------------|
|
||||
| [Homestead](EIPS/eip-606.md) | | 1,150,000 | 2016-03-14 |
|
||||
| [DAO Fork](EIPS/eip-779.md) | | 1,920,000 | 2016-07-20 |
|
||||
| [Tangerine Whistle](EIPS/eip-608.md) | Anti-DoS, EIP 150 | 2,463,000 | 2016-10-18 |
|
||||
| [Spurious Dragon](EIPS/eip-607.md) | State-clearing, EIP 158/161 | 2,675,000 | 2016-11-22 |
|
||||
| [Byzantium](EIPS/eip-609.md) | Metropolis: Part 1 | 4,730,000 | 2017-10-16 |
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
- Draft
|
||||
- Accepted
|
||||
- Final
|
||||
- Active
|
||||
- Deferred
|
|
@ -1,16 +1,26 @@
|
|||
{% assign bystatus = include.eips|sort:"eip"|group_by:"status" %}
|
||||
{% for group in bystatus %}
|
||||
{% if group.name != "" %}
|
||||
<h2>{{group.name}}</h2>
|
||||
<table>
|
||||
<style type="text/css">
|
||||
.eiptable .title {
|
||||
width: 67%;
|
||||
}
|
||||
|
||||
.eiptable .author {
|
||||
width: 33%;
|
||||
}
|
||||
</style>
|
||||
{% for status in site.data.statuses %}
|
||||
{% assign eips = include.eips|where:"status",status|sort:"eip" %}
|
||||
{% assign count = eips|size %}
|
||||
{% if count > 0 %}
|
||||
<h2>{{status}}</h2>
|
||||
<table class="eiptable">
|
||||
<thead>
|
||||
<tr><th>Number</th><th>Title</th><th>Author</th></tr>
|
||||
<tr><th class="eipnum">Number</th><th class="title">Title</th><th class="author">Author</th></tr>
|
||||
</thead>
|
||||
{% for page in group.items %}
|
||||
{% for page in eips %}
|
||||
<tr>
|
||||
<td><a href="{{page.url|relative_url}}">{{page.eip|xml_escape}}</a></td>
|
||||
<td>{{page.title|xml_escape}}</td>
|
||||
<td>{% include authorlist.html authors=page.author %}</td>
|
||||
<td class="eipnum"><a href="{{page.url|relative_url}}">{{page.eip|xml_escape}}</a></td>
|
||||
<td class="title">{{page.title|xml_escape}}</td>
|
||||
<td class="author">{% include authorlist.html authors=page.author %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
<ul class="social-media-list">
|
||||
{%- if site.dribbble_username -%}<li><a href="https://dribbble.com/{{ site.dribbble_username| cgi_escape | escape }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#dribbble' | relative_url }}"></use></svg> <span class="username">{{ site.dribbble_username| escape }}</span></a></li>{%- endif -%}
|
||||
{%- if site.facebook_username -%}<li><a href="https://www.facebook.com/{{ site.facebook_username| cgi_escape | escape }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#facebook' | relative_url }}"></use></svg> <span class="username">{{ site.facebook_username| escape }}</span></a></li>{%- endif -%}
|
||||
{%- if site.flickr_username -%}<li><a href="https://www.flickr.com/photos/{{ site.flickr_username| cgi_escape | escape }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#flickr' | relative_url }}"></use></svg> <span class="username">{{ site.flickr_username| escape }}</span></a></li>{%- endif -%}
|
||||
<li><a href="https://github.com/ethereum/EIPs"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#github' | relative_url }}"></use></svg> <span class="username">ethereum/EIPs</span></a></li>
|
||||
{%- if site.instagram_username -%}<li><a href="https://instagram.com/{{ site.instagram_username| cgi_escape | escape }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#instagram' | relative_url }}"></use></svg> <span class="username">{{ site.instagram_username| escape }}</span></a></li>{%- endif -%}
|
||||
{%- if site.linkedin_username -%}<li><a href="https://www.linkedin.com/in/{{ site.linkedin_username| cgi_escape | escape }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#linkedin' | relative_url }}"></use></svg> <span class="username">{{ site.linkedin_username| escape }}</span></a></li>{%- endif -%}
|
||||
{%- if site.pinterest_username -%}<li><a href="https://www.pinterest.com/{{ site.pinterest_username| cgi_escape | escape }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#pinterest' | relative_url }}"></use></svg> <span class="username">{{ site.pinterest_username| escape }}</span></a></li>{%- endif -%}
|
||||
{%- for mst in site.mastodon -%}{%- if mst.username and mst.instance -%}<li><a href="https://{{ mst.instance| cgi_escape | escape}}/@{{mst.username}}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#mastodon' | relative_url }}"></use></svg> <span class="username">{{ mst.username|escape }}</span></a></li>{%- endif -%}{%- endfor -%}
|
||||
{%- if site.twitter_username -%}<li><a href="https://www.twitter.com/{{ site.twitter_username| cgi_escape | escape }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#twitter' | relative_url }}"></use></svg> <span class="username">{{ site.twitter_username| escape }}</span></a></li>{%- endif -%}
|
||||
{%- if site.youtube_username -%}<li><a href="https://youtube.com/{{ site.youtube_username| cgi_escape | escape }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#youtube' | relative_url }}"></use></svg> <span class="username">{{ site.youtube_username| escape }}</span></a></li>{%- endif -%}
|
||||
{%- if site.googleplus_username -%}<li><a href="https://plus.google.com/{{ site.googleplus_username| escape }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#googleplus' | relative_url }}"></use></svg> <span class="username">{{ site.googleplus_username| escape }}</span></a></li>{%- endif -%}
|
||||
{%- if site.rss -%}<li><a href="{{ 'feed.xml' | relative_url }}"><svg class="svg-icon"><use xlink:href="{{ '/assets/minima-social-icons.svg#rss' | relative_url }}"></use></svg> <span>{{ site.rss | escape }}</span></a></li>{%- endif -%}
|
||||
</ul>
|
|
@ -10,7 +10,7 @@ layout: default
|
|||
<table>
|
||||
<tr><th>Author</th><td>{% include authorlist.html authors=page.author %}</td></tr>
|
||||
{% if page["discussions-to"] != undefined %}
|
||||
<tr><th>Discussions-To</th><td><a href="mailto:{{ page["discussions-to"] | uri_escape }}">{{ page["discussions-to"] | xml_escape }}</a></td></tr>
|
||||
<tr><th>Discussions-To</th><td><a href="{{ page["discussions-to"] | uri_escape }}">{{ page["discussions-to"] | xml_escape }}</a></td></tr>
|
||||
{% endif %}
|
||||
<tr><th>Status</th><td>{{ page.status | xml_escape }}</td></tr>
|
||||
<tr><th>Type</th><td>{{ page.type | xml_escape }}</td></tr>
|
||||
|
|
Loading…
Reference in New Issue