Code Monkey home page Code Monkey logo

eips's Introduction

Ethereum Improvement Proposals (EIPs)

ATTENTION: The EIPs repository has recently undergone a separation of ERCs and EIPs. ERCs are now accessible at https://github.com/ethereum/ercs. All new ERCs and updates to existing ones must be directed at this new repository. The editors apologize for this inconvenience.

The goal of the EIP project is to standardize and provide high-quality documentation for Ethereum itself and conventions built upon it. This repository tracks past and ongoing improvements to Ethereum in the form of Ethereum Improvement Proposals (EIPs). EIP-1 governs how EIPs are published.

The status page tracks and lists EIPs, which can be divided into the following categories:

  • Core EIPs are improvements to the Ethereum consensus protocol.
  • Networking EIPs specify the peer-to-peer networking layer of Ethereum.
  • Interface EIPs standardize interfaces to Ethereum, which determine how users and applications interact with the blockchain.
  • ERCs specify application layer standards, which determine how applications running on Ethereum can interact with each other.
  • Meta EIPs are miscellaneous improvements that nonetheless require some sort of consensus.
  • Informational EIPs are non-standard improvements that do not require any form of consensus.

Before you write an EIP, ideas MUST be thoroughly discussed on Ethereum Magicians or Ethereum Research. Once consensus is reached, thoroughly read and review EIP-1, which describes the EIP process.

Please note that this repository is for documenting standards and not for help implementing them. These types of inquiries should be directed to the Ethereum Stack Exchange. For specific questions and concerns regarding EIPs, it's best to comment on the relevant discussion thread of the EIP denoted by the discussions-to tag in the EIP's preamble.

If you would like to become an EIP Editor, please read EIP-5069.

Preferred Citation Format

The canonical URL for an EIP that has achieved draft status at any point is at https://eips.ethereum.org/. For example, the canonical URL for EIP-1 is https://eips.ethereum.org/EIPS/eip-1.

Consider any document not published at https://eips.ethereum.org/ as a working paper. Additionally, consider published EIPs with a status of "draft", "review", or "last call" to be incomplete drafts, and note that their specification is likely to be subject to change.

Validation and Automerging

All pull requests in this repository must pass automated checks before they can be automatically merged:

  • eip-review-bot determines when PRs can be automatically merged 1
  • EIP-1 rules are enforced using eipw2
  • HTML formatting and broken links are enforced using HTMLProofer2
  • Spelling is enforced with CodeSpell2
    • False positives sometimes occur. When this happens, please submit a PR editing .codespell-whitelist and ONLY .codespell-whitelist
  • Markdown best practices are checked using markdownlint2

It is possible to run the EIP validator locally:

cargo install eipv
eipv <INPUT FILE / DIRECTORY>

Build the status page locally

Install prerequisites

  1. Open Terminal.

  2. Check whether you have Ruby 3.1.4 installed. Later versions are not supported.

    ruby --version
  3. If you don't have Ruby installed, install Ruby 3.1.4.

  4. Install Bundler:

    gem install bundler
  5. Install dependencies:

    bundle install

Build your local Jekyll site

  1. Bundle assets and start the server:

    bundle exec jekyll serve
  2. Preview your local Jekyll site in your web browser at http://localhost:4000.

More information on Jekyll and GitHub Pages here.

Footnotes

  1. https://github.com/ethereum/EIPs/blob/master/.github/workflows/auto-review-bot.yml

  2. https://github.com/ethereum/EIPs/blob/master/.github/workflows/ci.yml 2 3 4

eips's People

Contributors

0xjac avatar 5chdn avatar alita-moore avatar arachnid avatar axic avatar cdetrio avatar chfast avatar chriseth avatar etan-status avatar eth-bot avatar fulldecent avatar gcolvin avatar gumb0 avatar holiman avatar jamesray1 avatar lightclient avatar micahzoltu avatar mudgen avatar nicksavers avatar pandapip1 avatar pirapira avatar poojaranjan avatar ralexstokes avatar samwilsn avatar sorpaas avatar souptacular avatar thunderdeliverer avatar timbeiko avatar wanderer avatar xinbenlv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

eips's Issues

EIP 104 (Serenity): Unlimited storage key or value size

Instead of storage keys and values being 32 bytes, they have unlimited size. We could have opcodes:

  • SSTORE(key_mstart, key_msz, value_mstart, value_msz)
  • SLOAD(key_mstart, key_msz, value_output_mstart, value_output_maxsize)

SLOAD can have gas cost equal to 40 + len(key) + len(min(value_output_maxsize, size_of_actual_output))

The gas cost for SSTORE can be:

def compute_gascost(key_length, value_length, prev_value_length):
    return 2500 + 10 * (key_length + value_length) \
        + (5000 + 40 * (key_length + value_length) if value_length else 0) \
        - (5000 + 40 * (key_length + prev_value_length) if prev_value_length else 0)

Where key_length is the length of the key, value_length is the length of the value, and prev_value_length is the length of the previous value at that key. If the function returns a value less than 2500, the difference is instead accounted for as a refund (eg. if compute_gascost returns 1300, that's a 2500 cost plus a 1200 refund, if it returns -700 that's a 2500 cost plus a 3200 refund, etc).

Motivations

  • Works well with a possible EVM 2.0 architecture which is based on 64 bit integers and where larger values are treated indiscriminately as byte slices, allowing easier use of RSA-based crypto and large-sized elliptic curves on the same footing as 256-bit ECC. If we go this route, there is no reason why the 32-byte length needs to be privileged
  • Works well with an architecture where code is part of storage (eg. code = storage at key index '' [empty string])
  • Allows for quick "shutdown and reboot" functionality where a VM can quickly stop computation in mid-step and save its entire memory to a standardized index in one step, and then quickly reload from there the next time a transaction is called. This is useful for (i) dapps that need to sometimes perform large batch operations that may take up more than the gaslimit, eg. a crowdfunding or auction contract refunding very many participants, (ii) security deposit based auditable computation markets, (iii) generally more efficiency by batching variable lookups, requiring fewer moderately expensive trie operations.

web3.js contract object re-design

ERC: 68
Title: web3.js contract object re-design
Status: Draft
Type: Informational
Created: 08.01.2016
Resolution: https://github.com/ethereum/web3.js

Abstract

This proposal is a move to make it a more future proof javascript representation of a ethereum smart contract.

Motivation

The contract object in web3.js in its current form has confused in many ways and has some draw backs, like not being able to pass a struct (object) as a functions arguments.

Usage

// contract options can be
options = {
    data: '0x12345678', // used when deploying contracts, so users don't need to pass in the data later
    from: '0x12345678..', // default from when sending tx
    gasPrice: '0xb', // default gasPrice when 
    gasLimit: '0xa' // default gasLimit when 
}


// initiating an un"addresses" contract object
var myContract = new web3.eth.contract(abi [, options])
myContract.address = '0x12345678...'; // add address later

// initiating with address
var myContract = new web3.eth.contract(abi, address [, options])

// -> deploying a contract
eventemitter = myContract.deploy({
    arguments: [param1, param2],
    data: '0x2345678' // when provided, this is used over the one from the options object
});
eventEmitter.on('error', function(error){ 
 });
eventEmitter.on('transactionHash', function(hash){ 
 });
eventEmitter.on('mined', function(address) { 
     new web3.eth.contract(abi, address);
     // or
    myContract.address = address;
 });
// also promise style works, will be fired when mined
eventEmitter.then(function(address){
}).catch(function(error){
})

// -> get the call data for a contract deployment
myContract.encodeABI({
    method: 'constructor',
    arguments: [param1, param2],
    data: '0x2345678'
});
> 0x23456780000000000000000000005345345

// -> events
myContract.on('someEvent' [, {filter: {myValue1: 23, myValue2: [3,5], ...}, fromBlock:..}], function(error, returnValues, log) {})

myContract.pastEvents(('someEvent' [, {filter: {myValue1: 23, myValue2: [3,5], ...}, fromBlock:.., toBlock: ...}], function(error, returnValues, log) {
   // called for every past event.
});

// if a `filter` option is provided, it means either value can be contained in the matching event (log)

// -> methods
// -> methods
myContract.myMethod(param1).estimate({from: '0x1234...'}, function(error, result){})

myContract.myMethod(param1).call({from: '0x1234...'}, function(error, result){})

myContract.myMethod(param1).send({from: '0x1234...'}, function(error, hash){})

var eventEmitter  = myContract.myMethod(param1).send({from: '0x1234...'})
eventEmitter.on('error', function(error){ 
 });
eventEmitter.on('transactionHash', function(hash){ 
 });
eventEmitter.on('mined', function(receipt) { 
 });
// also promise style works, will be fired when mined
eventEmitter.then(function(hash){
}).catch(function(error){
})

// -> get the abi of a method
myContract.encodeABI({
    method: 'myMethod',
    arguments: ['hello', 12345] 
}) // get only the data of the call '0x23456787654323456765432340000000000000000000000034'

Summary

The contract object would then look as follow:

new web3.eth.contract(abi, address);
> {
   address: '0x123456...',
   deploy: function(options){...},
   encodeABI: function(options){...},
   // events
   on: function(event, options, callback){...},
   pastEvents:  function(event, options, callback){...},
   // methods
   estimateGas: function(options){...},
   call: function(options){...},
   transact: function(options){...}
}

Community Request

Please give comments and reasons, why we should go in one way or another. Please lets keep this ERC short, We don't want to spend multiple weeks discussing this ;)

Extend contract ABI with structs

Extend contract ABI with anonymous structs / tuples.

Proposed syntax: {address, uint, bool}

The size of a struct is a sum of sizes of its elements (data is packed). Aligned to words.

Rationale

There are cases when packed related elements are easier/cheaper to process. E.g. function pay({address, uint96}[] payments).

ERC: Token Registries

ERC: 22
Title: Token standard
Status: Draft
Type: Informational
Created: 19-11.2015
Resolution: https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs

Abstract

Registries allow listing and searching of tokens and can serve as connector between tokens.

Specification

Token Registries

Token registries contain information about tokens. There is at least one global registry (though other may create more like the global Registry) to which you can add your token. Adding your token to it would increase the experience of the user that the GUI Client can use or not.

symbol

function setSymbol(string _s)
function symbol(address _token) constant returns (string)

Sets or returns a short sequence of letters that are used to represent the unit of the coin. When setting, it assumes the msg.sender is the token. Solidity string is on UTF-8 format so this should support any character supported by UTF-8. Symbols are chosen by the contract and it's up to the client to decide how to handle different currencies with similar or identical symbols.

Examples or symbols: USDX, BOB$, Ƀ, % of shares.

name

function setName(string _s)
function name(address _token) constant returns (string)

Sets or returns the name of a token. Solidity string is on UTF-8 format so this should support any character supported by UTF-8. Names are chosen by the contract and it's up to the client to decide how to handle different currencies with similar or identical names.

Examples of names: e-Dollar, BobToken, Bitcoin-Eth.

baseUnit

function setBaseUnit(uint _s)
function baseUnit(address _token) constant returns (uint256)

Sets or returns the base unit of a token. Although most tokens are displayed to the final user as containing decimal points, token values are unsigned integers counting in the smallest possible unit. The client should always display the total units divided by baseUnit. Base units can be any integer but we suggest only using powers of 10. At the moment there is no support for multiple sub-units.

Example: Bob has a balance of 100000 BobTokens, whose base unit is 100. His balance will be displayed on the client as BOB$100.00

Also see #20

Standard Writeable Mnemonic Seed Proposal

Having an easily portable, easily writeable and even memorisable seed* is an often requested issue and I think there would be benefit to have a cross implementation compatible standard, specially because there's a lot of space for pain if you implement it the wrong way. The end goal should not an "easy to memorize" but rather a "easy to write down/possible to memorize", since the value isn't so much on keeping the wallet 100% on your brain, but rather the extreme portability.

* Sometimes called a Brain wallet, but usually when referring to a human picking the random phrase, which is not the goal here

1. Ask for a Salt: Email address

It doesn't matter how hard is your password to guess, if you don't have a unique part of it, then an attacker could continuously generate a giant table of passwords, that would allow him to steal wallets that are yet to be created for any users. A salt doesn't need to be secret it just needs to be unique, if an attacker knows your salt they can try to guess your password but then they would be using all that hash power against one specific user, so the potential gains are limited.

An email address would be a perfect salt: it's instantly memorable by the user and is unique enough to add security. A client could also use the email to send a message with instructions, which allows a few interesting uses:

  • the user could make an email on the form of [email protected] to add more uniqueness, but they could still search their inbox for it
  • it could be used as an invitation. You add someone emails address and the client will send them instructions on how to redeem the ether (of course the full seed would not be sent on the email, that would require the invitee to contact the inviter)
  • Users are used to the pattern email + password as a login on social networks, so while the way this works is different, they might feel more at ease

2. Random seed generator

The user should never pick his own random seed. Humans are terrible sources of randomness and that should be provided for them. The user could be presented with the following choices:

  1. The level of security they want. This could be presented as "safe to secure up to X amount" and should reflect on the size of the seed. All clients should provide a minimum maximum security that should be in trillions of trillions of possible seeds. Not all use cases need to have complete unbreakable encryption, for transfer of small amounts of pocket money, a password that would take thousands of dollars to break should be enough.
  2. The option to generate a new seed if they want. In a typical use case the user should not have to see more than 10 seeds before settling on one, so that this wouldn't decrease the entropy by much.
  3. The option of selecting between string generation scheme. The user should pick the one that feels more comfortable with his culture or input device. Some examples would be:
  • Word List. BIP39 has an excellent word dictionary of words in multiple languages. Those were picked up to be common words yet all of them can be unambiguously distinguished by just the first 4 letters.
  • Pseudo-words. Using syllables to generate pseudo-words can be as strong and easier to write down. For example these three alien words: "fakpug temvuw jorzul" have the entropy equivalence of 6 random words (from a 1024 word list). Another example: "uffu wojtij ewiome wu cajreg hajkut mar" is the equivalent of 12 seed words.
  • Symbols. If you have a pen input or have knowledge of chinese, then an ideogram is a great seed. There probably a use case for an emoji based seed generation.
  • Security questions. An interesting way to transmit a brain wallet securely to someone would be to generate a series of questions that the user needs to answer on the other side. The questions could be sent via email and the hash would include both the question and answer. This would be much less secure but could be useful in a case where the user simply wants to send a small amount of ethers just so that the user can execute a contract
  • A mix of the above?

3. Multiple hashing rounds and multiple account outputs

Instead of a single round of hashing, the seed should be generated by hashing the password multiple times. The number should be standard, based on something that would take an average laptop/mobile phone in 2016 an average of 1 second or so. This means that even with a specialised computer and taking moose's law in consideration, testing millions of passwords would still take a considerable time and cost for the attacker.

Another layer of security can be added by generating not one, but an indeterminate amount of accounts for the user, by repeating the same hash amount. The user could be presented with 10-12 accounts to choose from whenever they generated a brain wallet, and could even choose them by picking a memorable and aesthetic pleasing icon. The attacker would then have to choose between testing a thousand passwords for 1 account or testing 10 accounts for 100 passwords. Since the user can be using the 12th account, there's a chance the attacker would have his salt, try his password combination and still not find his private key.

Interface Mockup

The following is just a mockup on how a brain wallet could look like in the Wallet. Once a user selects an ethereum address field, a pop up would appear asking them to select a field from their contact list, recently used addresses or a new brain wallet. Once selecting the brain wallet, the user would fill the email, passphrase and then they could select from multiple addresses. Each address would take about a second to appear, and the user could select any page they want.

Creating a new brain wallet:

screen shot 2016-03-09 at 1 23 53 pm

#### Loading an existing brain wallet

screen shot 2016-03-09 at 12 42 00 pm

timestamp as ABI type

Timestamps are quite common in smart contracts, Solidity even has special keywords for handling time. It would improve user interfaces (especially the auto-generated like the "smart wallet") if web3.js would know that a specific variable is a timestamp, so values could be rendered differently and special inputs could be provided.

Question on SHA3

This is probably a bad place to ask this, but I don't seem to find anything related on the interwebs.

Back in Feb 2014 it was announced by @vbuterin that all crypto opcodes will be moved to pre-mined contracts. See here and here.

sha256, ripemd160 and ecrecover since have been moved to such contracts, but sha3 remained as an opcode.

The yellow paper defines separate gas costs for all of them, although in different places. For sha3 it is in Appendix G (Fee Schedule), while the others are explained in Appendix E (Precompiled Contracts).

Is there any memo somewhere explaining the design decisions leading to the current state?

brain wallet discussion

I think it would be important and useful to discuss brain wallets and eventually settle on a method, which can be cross-application.

Current implementations

I am aware of three brain wallet implementations:

Run sha3 on the seed 16384 times. Then run sha3 until the first byte of the address is 0 (to be compatible with ICAP Direct).

A simple sha3 over the passphrase.

Requires a passphrase and a userid, both at least 10 characters long. Use the concatenated userid and passphrase as the input to PBKDF2 with 2000 rounds, 32 bytes key size and sha256 hashing.

(Note: the brain wallet part in Quorum is not supposed to have more Ether than what is needed to execute the contracts and therefore it wasn't made to be very complex)

Passphrase generation

@alexvandesande has posted a nice little tool to generate memorable passphrases. There are many other dictionary tools.

A common interface

It would be important to define a common key derivation method with the inputs required. These inputs also should have minimum length/strength requirements.

Hopefully this can be a start to a discussion to devise such a standard.

cc @alexvandesande @ryancdotorg @romanman @Gustav-Simonsson

Update: it seems like we were writing at the same time with @alexvandesande. #75 proposes a specific method.

EIP 7: DELEGATECALL

Overview

Add a new opcode, DELEGATECALL at 0xf4, which is similar in idea to CALLCODE, except that it propagates the sender and value from the parent scope to the child scope, ie. the call created has the same sender and value as the original call.

Specification

DELEGATECALL: 0xf4, takes 6 operands:

  • gas: the amount of gas the code may use in order to execute;
  • to: the destination address whose code is to be executed;
  • in_offset: the offset into memory of the input;
  • in_size: the size of the input in bytes;
  • out_offset: the offset into memory of the output;
  • out_size: the size of the scratch pad for the output.

Notes on Gas

  • The basic stipend is not given; gas is the total amount the callee receives.
  • Like CALLCODE, account creation never happens, so the upfront gas cost is always schedule.callGas + gas.
  • Unused gas is refunded as normal.

Notes on Sender

  • CALLER behaves exactly in the callee's environment as it does in the caller's environment.

Other Notes

  • The depth limit of 1024 is still preserved as normal.

Rationale

Propagating the sender and value from the parent scope to the child scope makes it much easier for a contract to store another address as a mutable source of code and ''pass through'' calls to it, as the child code would execute in essentially the same environment (except for reduced gas and increased callstack depth) as the parent.

Use case 1: split code to get around 3m gas barrier

~calldatacopy(0, 0, ~calldatasize())
if ~calldataload(0) < 2**253:
    ~delegate_call(msg.gas - 10000, $ADDR1, 0, ~calldatasize(), ~calldatasize(), 10000)
    ~return(~calldatasize(), 10000)
elif ~calldataload(0) < 2**253 * 2:
    ~delegate_call(msg.gas - 10000, $ADDR2, 0, ~calldatasize(), ~calldatasize(), 10000)
    ~return(~calldatasize(), 10000)
...

Use case 2: mutable address for storing the code of a contract:

if ~calldataload(0) / 2**224 == 0x12345678 and self.owner == msg.sender:
    self.delegate = ~calldataload(4)
else:
    ~delegate_call(msg.gas - 10000, self.delegate, 0, ~calldatasize(), ~calldatasize(), 10000)
    ~return(~calldatasize(), 10000)

The child functions called by these methods can now freely reference msg.sender and msg.value.

Possible arguments against

  • You can replicate this functionality by just sticking the sender into the first twenty bytes of the call data. However, this would mean that code would need to be specially compiled for delegated contracts, and would not be usable in delegated and raw contexts at the same time.

A binary format for EVM code

Abstract

The EIP gives EVM code a semantic container that enables quick population of memory and smaller amounts of initialization code. Partly inspired by ELF

Motivation

This is low hanging VM optimization. Given defined sections in a binary VM implementers will be able to more efficiently allocate resources.

Specification

The format has four main segments header, code, init, data . None of the segments are required. They are to be encoded as array. The order does not matter.

Prefixes

Each segment should start with a single byte prefix identifying it.
0x00 header
0x01 code
0x02 init
0x03 data

header

Currently the header only holds information on where to load the data to. Head consists of an array of data segment headers. Data segments represent initialized data that is loaded directly from the binary into memory when the program starts.

header := [data segment headers]
Where each data segment header := [address, data offset, data, size]

  • address - is the address in memory of where to start loading the data
  • data offset - where the data starts in the data segment relative to the first byte in the data segment
  • data size - the number of bytes to load starting at the offset.

If a data segment head points to an indice that does not exist then the binary is invalid.

code

The code to be stored for the contract. The code is saved in the current way; it is hashed and stored at its hash. If the program has no data segment only the init should run and the account should not be saved.

init

The initialization code runs before the account creation is finalized. If the initialization code traps then the account should not be created.

data

The data segment is a single continuous segment. The header and data should be saved in account after the stateRoot field.

fees

The fee for placing code in the state would include the header, data and the code e.i. codedeposit_fee * (num_of_bytes(data + header + code))

The fee for loading the data section to memory is just the cost of memory expansion.

Rationale

  • The main rationale is to aid in optimizing the VM. Batched preallocation of memory will be faster than runtime allocation. Also it make less incremental gas calculations then incremental allocation. Lastly the number of opcodes used to allocate memory in runtime are reduced.
  • Encouraging the separation of data from logic should result in more reusable logic and make code deduplication easier.
  • Data - The rationale for the data section is that it should be used to save globals variables and other initialized data.
  • Initialization - Instead of forcing contracts to have creation code, it is now optional. This will save space by eliminating unnecessary setup code.

Backwards Compatibility

Already initialized programs will work the same way. Txs that have the old format will become invalid.

sub-categorizing Informational EIPs

per #17 (comment) do we want a classification for "contract proposals/standards"?

Another category of Informational EIPs that come to mind, is retrospectives/post-mortems of events like forks, such as https://github.com/bitcoin/bips/blob/master/bip-0050.mediawiki, https://blog.ethereum.org/2015/10/22/security-alert-implementation-of-blockhash-instruction-in-c-and-go-clients-can-potentially-cause-consensus-issue-fixed-please-update Would we want these to be Informational EIPs?

NEW TO ETHELEUM

I am relatively new to etheleum, need assistance with beginners material, and how to join the network of mining etheleum as I assume it works more like bitcoin

Remove ICAP "basic" format

The ICAP spec proposes two formats for encoding an address:

  • the direct format, which cannot encode the full 160 bits of the address, but is IBAN compatible;
  • and the basic, which can, but is not IBAN compatible

The non-IBAN compatible format can cause issues down the line. First, many IBAN validators do check for the length. Those addresses would be dismissed as invalid.

Some validators don't check for the length, but are exposed to problems in the checksum algorithm, which was designed with that length in mind.

These two IBANs XE7338O073KYGTWWZN0F2WZ0R8PX5ZPPZS and XE73038O073KYGTWWZN0F2WZ0R8PX5ZPPZS, although different with the same checksum, will be valid according to the checksum. (Note, the leading zero in base-36 here will result in the same decoded value.)

Since we have the direct format, that means we believe 155bits of the hash is safe to use, I do not see the benefit of offering the basic format too and propose to remove it.

There might be something I'm missing here, please let me know

Note: an Ethereum address is just the least significant 160 bits of the 256 bit Keccak hash of the public key. The direct format means using the least significant ~155 bits of the Keccak hash.

Question: This part of the ICAP specification is not entirely clear:
a) does it require the Keccak hashing to result in a leading zero or
b) is it happy truncating the hash?

I assume it meant a), but this proposal assumes b).

EVM 2/wasm 105

EVM 2.0

Abstract

This EIP proposes upgrading the VM by converting to use a subset of Webassembly (Wasm). Wasm is a new Assembly standard being built for the web. The main advantage of using wasm is performance (both speed and size). The main disadvantage would be the need to port our existing infrastructure to use a new ISA. Most of this EIP is taken from Wasm's design docs which should be referenced for futher details.

Motivation

To truly distinguish Ethereum as the World Computer we need to have a performant VM. The current architecture of the VM is one of the greatest blockers to raw performance. Being stack-based and the 256-bit word size make translation from EVM opcodes to hardware instructions more difficult than needed.

With an architecture that provides a closer mapping to hardware the VM will have a considerably enhanced performance which will effectively open the door to a much wider array of uses that require a much higher performance/throughput. Also, by choosing a common and more standardized architecture anyone will be able to compile C/C++, Solidity (, etc.) once, and the compiled code will run in multiple environments. Using the new Assembly standard will make running a program either directly on Ethereum, on a cloud hosting environment, or on one's local machine - a friction-less process.

Specification

Wasm is a kin to LLVM IR and Low Level Instruction Set Architectures (ISAs). It is an defined as an Abstract Syntax Tree (AST) which has a textual representation using s-expressions. As an AST it has some higher level semantics than pure hardware ISAs. Including functions and basic flow control. Wasm is not finished a specification and still in flux. This EIP suggest using a subset of wasm to allow us to tailor the semantics to Ethereum. This spec is designed so that the minimum amount of changes a wasm VM would need to be implemented. This should make existing implementations of wasm easy to integrate and provide a way to run Ethereum flavored wasm on a unmodified wasm VM.

A Wasm module expressed in s-expressions looks like

(module
  (func $add (param $x i64) (param $y i64) (result i64) (i64.add (get_local $x) (get_local $y)))
  (func $sub (param $x i64) (param $y i64) (result i64) (i64.sub (get_local $x) (get_local $y)))

  (export "add" $add)
  (export "sub" $sub)
  )

Eth Flavored wasm

(module
  (func $add (param $x) (param $y) (result) (add (get_local $x) (get_local $y)))
  (func $sub (param $x) (param $y) (result) (sub (get_local $x) (get_local $y)))

  (export "add" $add)
  (export "sub" $sub)
)

For Ethereum we can consider each contract as a module therefore we can have an intrinsic modules and we do not need to specify the module’s closure (we leave it now for clarity). Furthermore if we restrict the types to 64 bit then we can eliminate the type information from the locals definition.

Difference from WASM

  • A local variable limit
  • Metering
  • Shared memory for call returns
  • Limit types and functions to i64
  • No Datatype conversion
  • No select op
  • No comma op
  • No conditional op
  • No need for a explicit module definition

Metering

Metering can initial be accomplished by injecting the counting code into the AST then passing the modified AST to a wasm VM. Modifying the AST is done by traversing the AST and adding a gas check immediately after each branch condition and at the start of functions and loops. For a more performant version gas counting could possibly be done at the VM directly. But from initial trials injecting gas at the AST level does not greatly affect performance. Since the gas counting code must be protected it would have to be implemented in a separate module.

Ethereum Specific Opcodes

  • call_delegate
  • call_code
  • create
  • gas
  • logs
  • suicide
  • environmental information (blockhash, coinbase, etc)
  • general module imports

The above opcodes should be used with WASM's call. call_delegate would become call $call_delegate <params> and so on.

The open-ended nature of module imports allow them to be used to expose arbitrary host environment functionality to WebAssembly code, similar to a native syscall. For example, a shell environment could define a builtin stdio module with an export puts. referance

Whether the module system could be used for contracts in general is an open questions. For now we will not use it in favor of using the CALL, CALLCODE and CALLDELEGATE semantics. This could be revisited once wasm has support for runtime dlopen like dynamic linking.

Modified Ethereum operations

Elimination of PUSH, DUP, SWAP, POP, PUSH, JUMP, JUMPI

SUICIDE, CALL, CALLCODE, CALLDELEGATE now gets the to address from memory and are expressions.

note on CALLs

The module loading system can’t yet support call since exported function are only allowed to return one value and do not have shared memory access. When implementing SUICIDE, CALL, CALLCODE, CALLDELEGATE the host environment will have to load the return values into the specified location in linear memory.

Abstract Syntax Tree Semantics

For the current full definition see here I’m only going to post here the core semantics that we are intersted in. For more details see the accompanying wiki. A formal spec such for each opcode will be worked out if this EIP gains Momentum. Currently this EIP suggests limiting the functions to only 64 bit Integer operations.

Internal Function Calls

Each function has a signature, which consists of: Return types, which are a sequence of value types Argument types, which are a sequence of value types

WebAssembly doesn't support variable-length argument lists (aka varargs). Compilers targeting WebAssembly can instead support them through explicit accesses to linear memory. The length of the return types sequence may only be 0 or 1

Direct calls to a function specify the callee by index into a main function table.

  • call_func: call function directly
    A direct call to a function with a mismatched signature is a module verification error.

Integer Operations

  • add: sign-agnostic addition
  • sub: sign-agnostic subtraction
  • mul: sign-agnostic multiplication (lower 32-bits)
  • div_s: signed division (result is truncated toward zero)
  • div_u: unsigned division (result is floored)
  • rem_s: signed remainder (result has the sign of the dividend)
  • rem_u: unsigned remainder
  • and: sign-agnostic bitwise and
  • or: sign-agnostic bitwise inclusive or
  • xor: sign-agnostic bitwise exclusive or
  • shl: sign-agnostic shift left
  • shr_u: zero-replicating (logical) shift right
  • shr_s: sign-replicating (arithmetic) shift right
  • eq: sign-agnostic compare equal
  • ne: sign-agnostic compare unequal
  • lt_s: signed less than
  • le_s: signed less than or equal
  • lt_u: unsigned less than
  • le_u: unsigned less than or equal
  • gt_s: signed greater than
  • ge_s: signed greater than or equal
  • gt_u: unsigned greater than
  • ge_u: unsigned greater than or equal
  • clz: sign-agnostic count leading zero bits (All zero bits are considered leading if the value is zero)
  • ctz: sign-agnostic count trailing zero bits (All zero bits are considered trailing if the value is zero)
  • popcnt: sign-agnostic count number of one bits

Flow Control

  • block: a fixed-length sequence of expressions with a label at the end.
  • loop: a block with an additional label at the beginning which may be used to form loops
  • br: branch to a given label in an enclosing construct
  • br_if: conditionally branch to a given label in an enclosing construct
  • get_reg: gets a register. We constrain registers to be one byte. Therefor we have 255 registers
  • store_reg: stores a register.

The br and br_if constructs express low-level branching. Branches that exit a block or loop may take a subexpression that yields a value for the exited construct. Branches may only reference labels defined by an outer enclosing construct. This means that, for example, references to a block's label can only occur within the block's body. In practice, outer blocks can be used to place labels for any given branching pattern, except for one restriction: one can't branch into the middle of a loop from outside it. This restriction ensures all control flow graphs are well-structured

  • unreachable: An expression which can take on any type, and which, if executed, always traps. It is intended to be used for example after calls to functions which are known by the producer not to return (otherwise the producer would have to create another expression with an unused value to satisfy the type check). This trap is intended to be impossible for user code to catch or handle, even in the future when it may be possible to handle some other kinds of traps or exceptions.

Linear Memory

The main storage of a WebAssembly instance, called the linear memory, is a contiguous, byte-addressable range of memory spanning from offset 0 and extending for memory_size bytes which can be dynamically grown by grow_memory. The linear memory can be considered to be an untyped array of bytes, and it is unspecified how embedders map this array into their process' own virtual memory. The linear memory is sandboxed; it does not alias the execution engine's internal data structures, the execution stack, local variables, or other process memory. The initial state of linear memory is specified by the module.

Linear Memory Accesses

Linear memory access is accomplished with explicit load and store operators. Integer loads can specify a storage size which is smaller than the result type as well as a signedness which determines whether the bytes are sign- or zero- extended into the result type.

  • load8_s: load 1 byte and sign-extend i8 to i32
  • load8_u: load 1 byte and zero-extend i8 to i32
  • load16_s: load 2 bytes and sign-extend i16 to i32
  • load16_u: load 2 bytes and zero-extend i16 to i32
  • load: load 4 bytes as i32

Stores have an additional input operand which is the value to store to memory. Like loads, integer stores may specify a smaller storage size than the operand size in which case integer wrapping is implied.

  • store8: wrap i64 to i8 and store 1 byte
  • store16: wrap i64 to i16 and store 2 bytes
  • store32: wrap i64 to i32 and store 4 bytes
  • store: (no conversion) store 8 bytes

Local variables

Each function has a fixed, pre-declared number of local variables which occupy a single index space local to the function. Parameters are addressed as local variables. Local variables do not have addresses and are not aliased by linear memory. Local variables have value types and are initialized to the appropriate zero value for their type at the beginning of the function, except parameters which are initialized to the values of the arguments passed to the function. Local variables can be thought of as registers

  • get_local: read the current value of a local variable
  • set_local: set the current value of a local variable

Module start function

If the module has a start node defined, the function it refers should be called
by the loader after the instance is initialized and before the exported functions
are called.

  • The start function must not take any arguments or return anything
  • The function can also be exported
  • There can only be at most one start node per module

For example, a start node in a module will be:

(start $start_function)

or

(start 0)

In the first example, the environment is expected to call the function $start_function
before calling any other module function. In the second case, the environment is
expected to call the module function indexed 0.

A module can:

  • Only have at most a start node
  • If a module contains a start node, the function must be defined in the module
  • The start function will be called after module loading and before any call to the module
    function is done

Binary Specification

Further attention to the binary encode can be tracked here. Currently wasm only has an early binary encoding spec.
Its ends up being fairly easy to follow. But not all of the features are relevant to Ethereum so some iteration can be done there. An overview of binary encoding can be seen here.

Rationale

  • Faster. Here are the benchmarks results. The benchmarks are based of off wasm-to-llvm-prototype. It compares a Wasm JIT based on LLVM to a EVM JIT which is also uses LLVM.
  • Maybe Smaller. Using the code from the benchmarks I compared the binary size. The results are that WASM was 29% smaller. But there is not enough real world data to be confident of this result. Also It compares handwritten WASM to EVM generated by solidity.
  • Toolchain Compatibility. LLVM front-end.
  • A large development base. It is being developed by Mozilla, Google, Microsoft, and Apple. Wasm is already in the Chromium's code base and is targeted to be deployed in all the major web browsers. Which would result in it being one of the most widely deployed VM architecture.
  • Furthermore some of Wasm's top design goals are largely applicable to Ethereum

Define a portable, size- and load-time-efficient binary format to serve as a compilation target which can be compiled to execute at native speed by taking advantage of common hardware capabilities available on a wide range of platforms, including mobile and IoT.

Detailed Rationale

Rationale For Registered Based ISA.

  • Register-based virtual machines are more like actual hardware.
  • Easier to JIT
  • Although most early computers used stack or accumulator-style architectures, virtually every new architecture designed after 1980 uses a load-store register architecture. The major reasons for the emergence of general-purpose register (GPR) computers are twofold. First, registers—like other forms of storage internal to the processor—are faster than memory. Second, registers are more efficient for a compiler to use than other forms of internal storage. For example, on a register computer the expression (A * B) – (B * C) – (A * D) may be evaluated by doing the multiplications in any order, which may be more efficient because of the location of the operands or because of pipelining concerns. Nevertheless, on a stack computer the hardware must evaluate the expression in only one order, since operands are hidden on the stack, and it may have to load an operand multiple times. More importantly, registers can be used to hold variables. When variables are allocated to registers, the memory traffic reduces, the program speeds up (since registers are faster than memory), and the code density improves (since a register can be named with fewer bits than can a memory location). Reference
  • (Java is stack based.) "Java byte-codes have additional disadvantages. Directly mapping byte-codes onto the underlying architecture is much more difficult than generating machine instructions from an abstract syntax-tree. Code generators that are based on a high-level representation do not have to deal with unfavorable peculiarities of Java byte-codes but can tailor their output towards advanced and specific processor features, such as special purpose instructions, size of register sets, and cache architectures. This is especially true for today's most common RISC processors which are less suited for byte-code's heavily used stack operations. Reference ftp://ftp.cis.upenn.edu/pub/cis700/public_html/papers/Kistler96.pdf
  • The design of the Inferno virtual machine
  • Virtual Machine Showdown: Stack Versus Registers

AST

  • compression benefits "use predictive compression algorithm that allows to encode recurring sub expressions in a program space efficiently while facilitating also fast decoding with simultaneous code-generation. Our compression scheme is based on adaptive methods such as LZW but has been tailored towards encoding abstract syntax trees rather than character streams. It takes advantage of the limited scope of variables in programming languages,which allows to deterministically prune entries from the compression dictionary, and uses prediction heuristics to achieve a denser encoding." Reference ftp://ftp.cis.upenn.edu/pub/cis700/public_html/papers/Franz97b.pdf
  • JITing benefits.
  • Notes on better JIT compilers using AST

64-bit vs 256-bit

A 64 bit word size would map to real world hardware. Most the time we don’t need 256 bit arithmetic. 256 was chosen to work with 256-bit hashes but we can easily store hash results in memory. Some opcodes such as CALL would have to load the to address from memory.

Implementation

While the complete EIP is not implemented many pieces of it are.

There are several Wasm implementations; here are a few.

References

EIP 102 (Serenity): Rename "gas" to "mana"

To commemorate the increased environmental friendliness of proof of stake, starting from Serenity "gas" should be renamed to "mana".

Rationale

Aside from the above, "mana" is a better descriptor because:

  • Unlike "gas", "mana" is typically understood to be ephemeral and nontransferable, clarifying the relationship between ether and gas/mana that has so far been a source of great confusion.
  • Gas in the real world is non-renewable, gas in Ethereum is renewable. Mana is typically understood to be renewable, and so would be more accurate.

Implementation

 for x in `find .`; sed -i s/gas/mana/g $x

Rename/alias sha3 to minimize confusion with SHA-3 standard

We should rename or have an alias for Ethereum sha3 to something else, to minimize confusion with the SHA-3 standard. Even though Yellow Paper and some docs mention Keccak-256, having sha3 in Solidity code is highly misleading. Some suggestions are ksha3, keccak. Any others?

Aliasing say ksha3 to sha3 (preserves backward compatibility) and encouraging the use of the new term, and then deprecating sha3 in a future version of Solidity, seems like a practical option to move forward.

ERC: Standard URI scheme with metadata, value and byte code

This proposal is inspired by BIP 21 and could apply to IBAN address format but can be extended to other proposed addresses formats. Imagine these scenarios:

  • An exchange or a instant converter like shape shift wants to create a single ethereum address for payments that will be converted into credit in their internal system or output bitcoin to an address
  • A store wants to show a QR code to a client that will pop up a payment for exactly 12.34 ethers, which contains metadata on the product being bought
  • A betting site wants to provide a link that the user can click on his site and it will open a default ethereum wallet and and execute a specific contract with given parameters
  • A dapp in Mist wants so simply ask the user to sign a transaction with a specific abi in a single call

In all these scenarios, the provider wants to set up internally a transaction, with a recipient, an associated number of ethers (or none) and optional byte code, all without requiring any fuss from the end user that is expected simply to choose a sender and authorise the transaction.

Currently implementations for this are wonky: shape shift creates tons of temporary addresses and uses an internal system to check which one correspond to which metadata, there isn't any standard way for stores that want payment in ether to put specific metadata about price on the call and any app implementing contracts will have to use different solutions depending on the client they are targeting.

I propose adding, beyond address, also optional byte code and value to any proposed address standard. Of course this would make the link longer, but it should not be something visible to the user, instead it should be shown as a visual code (QR or otherwise), a link or some other way to pass the information.

If properly implemented in all wallets, this should make execution of contracts directly from wallets much simpler as the wallet client only needs to put the byte code by reading the qr code.

If we follow the bitcoin standard, the result would be:

 ethereum:<address>[?value=<value>][?gas=<suggestedGas>][?data=<bytecode>]

Other data could be added, but ideally the client should take them from elsewhere in the blockchain, so instead of having a label or a message to be displayed to the users, these should be read from an identity system or metadata on the transaction itself.

Example:

Clicking this link would open a transaction that would try to send 5 unicorns to address deadbeef. The user would then simply to approve, based on each wallet UI.

 ethereum:0x89205A3A3b2A69De6Dbf7f01ED13B2108B2c43e7?gas=100000&data=0xa9059cbb00000000000000000000000000000000000000000000000000000000deadbeef0000000000000000000000000000000000000000000000000000000000000005

Without byte code

Alternatively, the byte code could be generated by the client and the request would be in plain text:

 ethereum:<address>[?value=<value>][?gas=<suggestedGas>][?function=nameOfFunction(param)]

Example:

This is the same function as above, to send 5 unicorns from he sender to deadbeef, but now with a more readable function, which the client converts to byte code.

 ethereum:0x89205A3A3b2A69De6Dbf7f01ED13B2108B2c43e7?gas=100000&function=transfer(address 0xdeadbeef, uint 5)

EIP 103 (Serenity): Blockchain rent

Motivation

The Ethereum platform gives users access to a number of computational resources: particularly computational steps, memory, logs / bloom filter usage and permanent storage in the Ethereum state. For most of these resources, the gas system is roughly incentive-compatible, although price-fixing the exchange rates between these resources is, in the current framework, unfortunately required. Storage, however, is unique in that it is not ephemeral; once storage is filled, it must be stored by all full nodes forever until/if it is deliberately cleared. The cost of storage is bytes * time, but users are only paying for bytes.

A partial solution exists for Ethereum 1.0 in the form of the SSTORE clearing refund, where a user gets up to a net 10000 gas back for converting a filled storage slot into an empty slot. However, this approach is imperfect for two reasons:

  1. During a block where transaction inclusion demand does not reach the gas limit (or even where the opportunity-cost gasprice is cheaper than average), miners have the incentive to fill up storage slots so as to use them as a "bank" that expensive transactions can use to grant themselves additional gas at a time when gasprice is expensive; essentially, conducting inter-temporal gas arbitrage with the additional negative externality of requiring all full nodes to store extra data in the meantime.
  2. There is no incentive to use storage slots for a short period of time instead of a long period of time.

Proposal

A proposal for solving this is to introduce "blockchain rent": rather than charging for bytes, actually charge for bytes * time. Here is a proposed protocol for doing so:

  • In the account RLP, keep track of the variables last_accessed and total_storage_bytes. last_accessed is meant to represent the block number at which storage was most recently changed, and total_storage_bytes is meant to represent the total number of bytes in account storage.
  • When you perform an SSTORE(k, v) operation on the account, let fee = (TOTFEE[block.number] - TOTFEE[last_accessed]) * account.total_storage_bytes, where TOTFEE[n] is the sum of the data storage fees from block 0 to block n (eg. TOTFEE[n] = n * c for some constant c would work as a basic policy but one can come up with more dynamic policies that change per block). Set account.balance -= fee, account.last_accessed = block.number and account.total_storage_bytes += len(v) + (len(k) if v != '' else 0) - len(old value of account.storage[k]) - (len(k) if old value of account.storage[k] != '' else 0). If account.balance < 0, destroy the account.
  • Create a special type of ping transaction which performs a dummy SSTORE(0, account.storage[0]) operation on any desired account. Miners can run this if they see an account that needs to be deleted in order to process fees and delete it if it is in fact bankrupt. If and only if a ping leads to an account bankruptcy, it requires no gas.

For example, suppose that TOTFEE[n] = n * 10 (ie. 10 wei per block per second), a block was last accessed in block 321070, the current block is 312085, the account has a pre-existing balance of 1000, and it only has two keys in storage: {"cow": "dog", "horse": "doge"}. We should have account.last_accessed = 321070 and account.total_storage_bytes = 3 + 3 + 5 + 4 = 15. Now, suppose we have a transaction that sends 10000 wei and, in the process of executing code, sets SSTORE("moose", "deer"). We compute:

  • Balance increased from 1000 to 11000
  • fee = (TOTFEE[312085] - TOTFEE[312070]) * 15 = (3120850 - 3120700) * 15 = 2250
  • Balance decreased from 11000 to 8750 due to the fee
  • account.total_storage_bytes += len("deer") + len("moose") - 0 - 0, ie. increased by 9 for a new total of 15 + 9 = 24. The values subtracted are both zero because there was nothing pre-existing in that key.
  • account.last_accessed = 312085

Setting TOTFEE

The hardest challenge in this scheme is setting the TOTFEE function. One could set this to a static value (ie. TOTFEE[n] = c * n), but this is essentially a form of price-fixing and so is arguably hard to set in a way that is economically efficient. A somewhat more effective strategy is to set a space limit (arguably, this is no less reasonable than setting a gas limit), and targeting TOTFEE based on that value. For example, consider a policy where we have some function for setting a space limit L (eg. a flat L = 2**35 or a linearly growing L = 2**10 * (block.timestamp - genesis.timestamp)). Then, every block, we set TOTFEE[n] = TOTFEE[n-1] + 2**(20 * L / (L - total_state_size)) (ie. the fee is 2**20 wei ~= 0.001 shannon initially, then when the total state size increases to 5% of the maximum it doubles, when it increases to 10% of the maximum it doubles again, and so forth, with the doubling intervals decreasing in size and ultimately converging to a singularity at L). In theory, the amount of storage usage should increase until it hits an equilibrium equal to the marginal demand for storage at a supply somewhere less than L (in the case of the above example, roughly L / 2 is plausible); the main tradeoff to be made is in the steepness of the supply function. Steeper supply functions are more robust to mistakes made in the initial supply-function-setting process, but they also lead to more volatile rent charges.

Why should I want to support a proposal that adds in a "weird new tax" when storage usage per second is free now?

  • The SSTORE gas costs may go down, benefiting dapp developers that only use storage for short time durations
  • The disk space requirements for a full node will go down

Extend the case-sensitive checksum to ICAPs

Abstract

Extend the Yet another cool checksum address encoding #55 to ICAP addresses

Rationale

The ICAP format has both a Direct and Basic format, which only differs by one character in length; this is risky, given the weak checksum of only 6.6 bits (two digits: 00-99). There are real risks that someone might add a character by mistake and accidentally create a valid but unintended ICAP. Similar issue was raised here

IBANs are by specifications case insensitive, making it backwards compatible to alter the case for the purpose of checksums.

Implementation

Applying the Yet another checksum to the ICAP Direct and Basic. The case-change should only be applied to the "address" section of the ICAP, not the 4 first characters. In effect, the final ICAP will look like this:

Basic (34 chars):
XE7338O073kYGtWWzN0f2Wz0R8Px5ZPpZs

Direct (35 chars):
XE73038O073kYGtWwZN0f2Wz0R8pX5ZpPzS

Note: The change in case above is only for illustration, I haven't really calculated the real checksum. That should be trivial if people find this EIP useful.

The problems that this page raises, that an user enters one extra character without changing the checksum, is in this proposal almost reduced to zero.

The number of checksum bits increases from 6.5 bits to 6.5 + 30(26/36) ~ 28 bit => 1/268 million*

Serenity Validators, As Official Decentralized Casper Staking Pool Smart Contracts

I'm a total novice at cryptocurrency tech, but was thinking it might be feasible to have each Serenity validator instead of being X number of randomly chosen accounts that meet certain criteria, be X number official Casper decentralized staking pool smart contracts instead? Wouldn't this simultaneously solve these two potential issues:

  1. Everybody can participate in staking at any time, with any amount of ETH.

  2. With multiple official decentralized staking pools to choose from that are all identical protocols, pool centralization issues cannot easily occur.

Sorry if I'm missing something here from a technical perspective, I'm just a web2 guy for now (slowly getting there with web3).

Some kind of incentive to perform a selfdestruct operation

If we view the blockchain as a public utility, would it not make sense that we should put in some kind of incentive for developers to "Clean up" once their contract has executed its function. This would reduce the load on the state, and help keep the protocol decentralized. Where this incentive would come from, I'm not certain, but I think it's definitely something that ought to be thought about. Any and all ideas I would love to have the discussion about.

EIP 101 (Serenity): Currency and Crypto Abstraction

Title

  EIP: 101
  Title: Serenity Currency and Crypto Abstraction
  Author: Vitalik Buterin <[email protected]>
  Status: Active
  Type: Serenity feature
  Created: 2015-11-15

Specification

  1. Accounts now have only two fields in their RLP encoding: code and storage.
  2. Ether is no longer stored in account objects directly; instead, at address 0, we premine a contract which contains all ether holdings. The eth.getBalance command in web3 is remapped appropriately.
  3. msg.value no longer exists as an opcode, and neither does tx.gasprice
  4. A transaction now only has four fields: to, startgas, data and code.
  5. Aside from an RLP validity check, and checking that the to field is twenty bytes long, the startgas is an integer, and code is either empty or hashes to the to address, there are no other validity constraints; anything goes. However, the block gas limit remains, so miners are disincentivized from including junk.
  6. Gas is charged for bytes in code at the same rate as data.
  7. When a transaction is sent, if the receiving account does not yet exist, the account is created, and its code is set to the code provided in the transaction; otherwise the code is ignored.
  8. A tx.gas opcode is added alongside the existing msg.gas at index 0x5c; this new opcode allows the transaction to access the original amount of gas allotted for the transaction

Note that ECRECOVER, sequence number/nonce incrementing and ether are now nowhere in the bottom-level spec (NOTE: ether is going to continue to have a privileged role in Casper PoS). To replicate existing functionality under the new model, we do the following.

Simple user accounts can have the following default standardized code:

# We assume that data takes the following schema:
# bytes 0-31: v (ECDSA sig)
# bytes 32-63: r (ECDSA sig)
# bytes 64-95: s (ECDSA sig)
# bytes 96-127: sequence number (formerly called "nonce")
# bytes 128-159: gasprice
# bytes 172-191: to
# bytes 192+: data

# Get the hash for transaction signing
~mstore(0, msg.gas)
~calldatacopy(32, 96, ~calldatasize() - 96)
h = sha3(96, ~calldatasize() - 96)
# Call ECRECOVER contract to get the sender
~call(5000, 3, [h, ~calldataload(0), ~calldataload(32), ~calldataload(64)], 128, ref(addr), 32)
# Check sender correctness
assert addr == 0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1
# Check sequence number correctness
assert ~calldataload(96) == self.storage[-1]
# Increment sequence number
self.storage[-1] += 1
# Make the sub-call and discard output
~call(msg.gas - 50000, ~calldataload(160), 192, ~calldatasize() - 192, 0, 0)
# Pay for gas
~call(40000, 0, [SEND, block.coinbase, ~calldataload(128) * (tx.gas - msg.gas + 50000)], 96, 0, 0)

This essentially implements signature and nonce checking, and if both checks pass then it uses all remaining gas minus 50000 to send the actual desired call, and then finally pays for gas.

Miners can follow the following algorithm upon receiving transactions:

  1. Run the code for a maximum of 50000 gas, stopping if they see an operation or call that threatens to go over this limit
  2. Upon seeing that operation, make sure that it leaves at last 50000 gas to spare (either by checking that the static gas consumption is small enough or by checking that it is a call with msg.gas - 50000 as its gas limit parameter)
  3. Pattern-match to make sure that gas payment code at the end is exactly the same as in the code above.

This process ensures that miners waste at most 50000 gas before knowing whether or not it will be worth their while to include the transaction, and is also highly general so users can experiment with new cryptography (eg. ed25519, Lamport), ring signatures, quasi-native multisig, etc. Theoretically, one can even create an account for which the valid signature type is a valid Merkle branch of a receipt, creating a quasi-native alarm clock.

If someone wants to send a transaction with nonzero value, instead of the current msg.sender approach, we compile into a three step process:

  1. In the outer scope just before calling, call the ether contract to create a cheque for the desired amount
  2. In the inner scope, if a contract uses the msg.value opcode anywhere in the function that is being called, then we have the contract cash out the cheque at the start of the function call and store the amount cashed out in a standardized address in memory
  3. In the outer scope just after calling, send a message to the ether contract to disable the cheque if it has not yet been cashed

Rationale

This allows for a large increase in generality, particularly in a few areas:

  1. Cryptographic algorithms used to secure accounts (we could reasonably say that Ethereum is quantum-safe, as one is perfectly free to secure one's account with Lamport signatures). The nonce-incrementing approach is now also open to revision on the part of account holders, allowing for experimentation in k-parallelizable nonce techniques, UTXO schemes, etc.
  2. Moving ether up a level of abstraction, with the particular benefit of allowing ether and sub-tokens to be treated similarly by contracts
  3. Reducing the level of indirection required for custom-policy accounts such as multisigs

It also substantially simplifies and purifies the underlying Ethereum protocol, reducing the minimal consensus implementation complexity.

Implementation

Coming soon.

ERC: Default Ethereum Name Registrar

  ERC: 26 (based on issue number) or 3 (based on ERC)
  Title: Default Mist Name Registrar
  Author: Alex Van de Sande ([email protected])
  Status: Draft
  Type: Informational
  Created: 20-11.2015

Abstract

An important aspect of making ethereum Ðapps easily accessible is a name registry that will connect a human readable name to a hash for usage in IPFS/SWARM or any DHT system.

The name registrar is not meant to be the one and only name registrar on ethereum but rather a default registrar to be used by Mist to resolve names. It will be an user configurable setting.

Motivation

The goal of this contract is:

  • To find the optimal price for names: create a strategy where the nash equilibrium for each player is to simply put down the maximum amount they are willing to pay for a name, and not create incentives for names to be overpaid
  • To allow optimal usage of names: allow good names to circulate among those who want have better usages for it, while keeping smaller brands reasonably protected
  • To make name markets as transparent as possible. Currently domain squatting is a very sneaky business that utilizes information asymmetry to sell names. This proposal, while still allows names to be sold or transferred outside this market, will create a last resort market where name prices are transparent and optimal
  • Registering names should have an optimal cost, cheap enough to be inclusive, but not too much to allow excessive name squatting. This intends to describe the design and parts of the proposed system.
  • Privacy by obscurity: give unpopular and niche domain holders a reasonable privacy expectation while making the most popular names evaluations transparent. Creating a spider that crawls all name markets is exponentially expensive.

Specification

The system will consist of 4 main parts:

Hash Registrar

The registrar itself is the contract that stores the basic data. If more data is needed it can be stored in other contracts, using this one as the reference. It doesn't use the name directly to reference the registry but its data. Keeping the names as hashes instead of plaintext has two advantages: first it allows privacy by obscurity, meaning that if the name isn't known enough to be in a rainbow table then you can't really know who the information is about. Second, it allows a more general purpose and future proofing use of the contract, as it can be used to claim ownership on anything that can be translated into hash, like devices, files, texts and other uses we haven't thought about now.

function getAuction() constant returns (address auction)
function getElection() constant returns (address election)
function getCollector() constant returns (address collector)
function setCollector(address _newCollector) returns (bool success)

The registry is set at startup with the address of three other contracts, the Collector contract, Election Contract and Auction contract, that have special rights. Only the Election contract can change the collector. The others are unchangeable.

function getRegistry(bytes32 _hash) constant returns (address _owner, uint _renewalDate,  uint feesPaid, string _redirectAddress)

It uses a hash as an index and attributes these informations to it: an address that owns it; the expiration date of the registration; the amount of ether that the owner effectively paid to the registrar address as the process of renewal; a string which is the http, buzz or ipfs address of the app.

Other contracts might extend this functionality by simply creating a registry of extra information about a hash and then only allowing edits to it by checking this master contract for the owner address. For example, the wallet app might want to make a registry where a name is associated to an address (different from the owner), or if you want to have a secondary content hash for http links then a secondary contract could be deployed, only allowing edit access to the addresses on marked as owner on this contract.

function editRegistry(bytes32 _hash)

All the information on that hash can be edited by the owner of the address up to 48h before the renewal Date, and at that time the information is locked. After the expiration date, only the Auction Contract can change the owner of the hash.

function newRegistry(bytes32 _hash, string _redirectAddress, address _owner)

Only the Auction Contract can add new registries.

function ()

All funds given to the Registrar contract are redirected to the Collector Contract. These will not count towards the feesPaid.

function invalidateEntry(string _name)

The disadvantage of hashes as identifiers is that it literally allows anything, therefore making it impossible to create restrictions such as "names shorter than 6 letters can only be registered after 2017". This could be avoided by creating validity rules that need to be reported and if true will delete the entry, but this would require all those rules to be set at the first setup. Another way to do it is to grant the Collector Contract power to invalidate entries, but this would open the possibility of an evil collector contract censoring entries. Another solution is simply to allow any entries, but simply enforce those rules on the client: mist could be programmed to look at other contracts for special names

I'm open to more elegant solutions.

Auction Contract

The auction contract is set at startup of the Hash registrar, but since they are separated it is possible to clone a copy of the registrar contract and just change these variables.

The purpose of the auction contract is to receive bids for hashes and select a winner.

function startBid(bytes32 _newHash)

If _newHash is not registered to anyone this will create a new register, owned by 0x000 with a renewal date exactly 7 days after this function was executed. This allows a short time in which a Vickrey Auction can decide who is the first owner of the name.

The cost of start a bid can be defined by the collectorContract, but otherwise is kept at free.

function putSealedBid(bytes32 _sealedBid)

A sealed bid is just a message with the hash of the bid and some ether. The amount of ether sent on this step is also recorded, as long as the time in which the bid was put. The amount of ether can and should be higher than the amount bid, to protect the privacy of the bid. For the same reason, the bidder doesn't need to be the future owner.

The collectorContract, might define a deposit value that needs to be added on top of the put, but if it doesn't implement it then it's free.

function revealBid(bytes32 _sealedBid, bytes32 _biddedHash, address _owner, uint _bidPrice, uint _duration, string _salt)

_sealedBid is the hash saved on _sealedBid
_biddedHash is the hash that the bidder wants to own
_owner is the future owner of the hash, if the bid is successful. The bidder and the owner need not to be the same person
_bidPrice is the maximum price the bidder is willing to pay for it
_duration is the length of time (in days) the owner wants to renew it for. Must be longer than 180 and smaller than 3660. If this is the first time this hash is being bidder on then the _duration cannot be longer than 366, if it has been registered before then the _duration cannot be longer than twice the length of time that has passed since it was first registered, as to avoid very long registrations during the first years.

_salt is just a random string to prevent deanonimization of sealed bids by brute force

This action can be done by anyone. If the _sealedBid doesn't match the hash of all other parameters put together then the bid is not revealed, otherwise it's saved on the revealed bids. Collection contract.

Once a bid is revealed, the proposed setup is a closed bid Vickrey auction, where the highest bidder becomes the owner but only pays the second highest bid:

  • If the new prospective owner is not the current owner then his bidPrice will be the parameter on _bidPrice. If the owner is bidding to renew the name then his bid will be calculated as _bidPrice * K/ _duration. In practice this means that the owner is appraising his own name at that price and is putting down a Fee that is a percentage of the total appraised value of his name, proportional to the renewal period. That percentage is the same for all names and is decided by the Collector Contract
  • If the expiration date is on the past, then the bid is deleted and the funds sent to it are sent to the Collector Contract
  • Else if the duration is outside the bounds of minimum and maximum durations OR if the ether amount sent during the sealed bid isn't enough to cover his price and fees OR if the sealed bid has been sent less than 48h before the renewal period then the bid is considered invalid, it is deleted and the ether amount sent back to the bidder.
  • If the bidPrice it's the highest yet then it should be saved as such and the price to be paid should be set at the asking price of the previous highest bid (or 0 if there are none). The second highest bid should be deleted and its ether sent back to its bidder. If the bid new owner is not the current owner, K is 1, otherwise (if it's the owner renewing the ownership) then K is a factor set by the Collector Contract.
  • Else if the bid is lower than the highest bid but bigger than the price to be paid of the highest bid, then the price to be paid is set at the this bid asking price. This bid is deleted and its ether sent back to its bidder.

Should a bid be considered invalid if it's revealed earlier than 48h of the renewal date?

Bids revealed too early might affect the game strategy and will influence the price to be paid. In the other hand a deleted bid might mean that someone will lose his property without the correct asking price. Since losing a domain name is harsher than someone overpaying for it, then I suggest that there should not be an obligatory reveal period, only a suggested 24h window.

The collector contract can set a function that will determine a fee to be paid by the bidders, but otherwise it will default to free.

function revealBid(bytes32 _sealedBid, bytes32 _biddedHash, address _owner, uint _bidPrice, uint _duration, string _salt)

A bid can only be removed by the original owner and only earlier than 48 hours before the renewal date.

function finalizeAuction(bytes32 _biddedHash)

This action can be only executed after the renewalDate has passed. Anyone can call it, so it could be scheduled with the alarm clock.

If owner has not changed, then an amount of ether equivalent to _bidPrice/ _duration * K will be sent to the Collectors Contract and the remaining amount will be sent back to the original bidder. The amount paid will be registered at feesPaid. The renewal date will be set at the last renewal data + _duration.

If the owner has changed then amount of priceToBePaid will be sent to the previous owner, and a fee calculated by priceToBePaid * K / _duration will be sent to the collectors contract and registered as feesPaid. Otherwise a user could keep a name indefinitely by simply selling it to itself. The renewal date will be set at the last renewal data + _duration.

function cleanOldBids()

Deletes any unsealed bids that are older than the maximum duration time that any name can accept and forwards the ether to the Collector.

Collector contract

The Collector Address is an address that receives all the funds collected in auctions and has a special right to change the K factor. The purpose of the name registry auction is not to make a profit but to allow the optimal distribution of names, to prevent name squatting while still allowing cheap and easy access to registering a name. The cost of the renewal is given by the market price of the total price, divided by K. If K is too low it might allow name squatting, but if it's too high it can make keeping names too expensive.

The collector contract can also define fees related to bidding, in order to fight spam. The collector contract can determine which rules are broken in order to consider a registry invalid (short names could only be registered after a few years, etc)

How exactly the Collector contract changes the K factor or spends its funds is not defined here, as the contract itself is a changeable parameter elected by the Election Contract.

My proposal is that the first Collector contract be just a "Boomerang contract", a contract that simply keeps all ether sent to it and then send them back after 1 year. This will allow the funds to be safely kept for a period while the community build tools and DAOs for the collector contract for the first election. Since they can always elect the 0x address, then if the community wants to do so they can still vote to burn all the ether collected during the first year.

Election Contract

The election contract has the special right to change the collector address. The exact workings of the election, as well as their frequency is not yet defined here and is open to discussions.

One important issue is that it's impossible to tell which are the entities behind each name, if they coordinate with each other or if they are owned by other entities, therefore the concept of anti-sybil (and to a point anti-coercion) mechanisms does not really apply here. Also, the job of the Collector Contract is basically to define the use of it's own funds and how to raise or lower the "tax rate" on new names, therefore it's only natural that the weights of the votes should be based barely on the amount of funds each name has sent to the contract during their last renewing period.

A user that bought four names four 1 ether each and a user that bought a single name for 4 ethers have contributed the same amount to the collector contract and therefore should have the same right to decide how the funds are spent. If the system favours the former (like quadratic voting does) will stimulate users to buy tons of small names they are not going to use, a system that favours the latter will stimulate users to double bid on their own names to pay higher taxes and therefore get more voting power. Both will would be contrary to the whole purpose of the name registrar.

The suggested voting mechanism is a mix of approved voting with Liquid democracy, as follows:

function setDelegate(string32 _ownedHash, address _delegate)

Instead of voting directly, a voter instead can decide to appoint a delegate. The contract verifies that the msg.sender is the owner of the _ownedHash and then moves his voter weight ('feesPaid') to the new _delegate

function unsetDelegate(string32 _ownedHash)

The voter removes his vote to his delegate and states that wants to vote himself.

function setVote(address[] approvedCandidates)

The voter selects an array of contracts he approves for the job of Collector Contract. These remain static and can be changed anytime. If you

function tallyVotes()

Instead of a fixed election cycle, votes can be counted at anytime if someone feels voter's preference have changed enough. The cost of counting the votes is paid by the function caller. First the function will calculate the voter's weight by the sum of his 'feesPaid' and the weight of all voters that delegate their vote into him. Votes can be delegated forward a finite number of time (3, 5 or 7, depending on gas costs).

Then all addresses the voter approved will be receive an equal number of votes as his weight. The Address with a higher number of approvals will be selected as the new Collector Contract, effectively immediately.

Acknowledgements

People who contributed to this proposal, in no particular order: @nagydani & @zelig (with their research for the swarm name registrar), @vbuterin (for insights in elections), @gavofyork (who designed the first name registrar ), @yann300 and @arkpar (who implemented the current name registrar), @pipermerriam & @nmushegian (for their great insights at DevCon1) and @ryepdx (that is implementing the maker registry) and @danielnovy (auctions Ðapp at consensys)

Ethereum VM C interface

Motivation

Based on work done in EVM JIT project https://github.com/ethereum/evmjit I would like to propose C-like interface specification for Ethereum VM ABI that could be used to create high performance VM implementations.

Specification

Types

  • uint256be - unsigned 256-bit big endian integer (32 bytes)
  • uint256 - unsigned 256-bit host endian integer (32 bytes)
  • uint64 - unsigned 64-bit host endian integer (8 bytes)
  • int64 - signed 64-bit host endian integer (8 bytes)
  • address - Ethereum address (20 bytes)
  • byte - a byte
  • ptr - a pointer to byte array

Inputs

Name Type Was Comment
gas uint256 int64 Execution with more than 263 gas is very theoretic.
gas price uint256 int64
input_data ptr Data must be available to VM until execution is finished.
input_data_size uint64
address address
caller address
origin address
transfer_value uint256
apparent_value uint256 Added in Homestead.
coinbase address
difficulty uint256
gas limit uint256
block number uint64
timestamp int64
code_hash uint256be The hash of the code to be executed.
code ptr The code is requested with get_code query.
code_size uint64

Outputs

  • status/result (ok, oog)
  • output data
  • storage modification list
  • suicide list
  • other state changes?

Queries (aka Callbacks)

VM uses this query functions to get additional information from a Ethereum node.

Declaration Description
uint256be keccak(ptr data, uint64 size) Ask VM to compute Keccak hash of the given data. This should be replaced with internal implementation of Keccak.
uint256 balance(address) Query the balance of the given address. See BALANCE instruction.
uint256be blockhash(uint256 number) Get hash of a block with given number. See BLOCKHASH instruction.
(ptr, uint64) extcode(address) Get the code of the given account. This should be used to get the code of the current execution request. In case the code has been compiled and cached the query is not needed.
void log(ptr data, uint64 size, uint256be topic1, uint256be topic2, uint256be topic3, uint256be topic4) Send logs. This should not be needed. Logs should be aggregates by the VM and provided to Ethereum node with other output.
uint256be sload(uint256be key) Load a word from the storage.
void sstore(uint256be key, uint256be value) Store a word in the storage. To count gas for that the VM needs to check the previous value with sload.
bool call(...) Call other contract.
void create(...) Create new contract.

ABI: enums, structs and timestamps

This is a combination of several already existing issues about extensions to the ABI. It subsumes #21, #46 and #47.

Time Units

Add the following new elementary types to the ABI:
timestamp, timespan
Encoding: identical to int256 for both
Semantics:

  • timestamp: point in time as seconds since the unix epoch (Discussion: As we have int256 we could also make it milli or microseconds)
  • timespan: a span of time in seconds (or smaller unit as above)

Enums

At any point in an interface definition where an elementary type is allowed, the following is also allowed:
(A|), (A|B), (A|B|C), ... for A, B, C being from [_$a-zA-Z][_$a-zA-Z0-9]*

Such a type is called an "enum" and the identifiers A, B, C, ... are encoded as 0, 1, 3, ..., respectively. This means that languages and user interfaces should prefer names over numeric values, but the names are not visible in the binary encoding and the type is treated identical to uint256.

Structs

Structs allow several values to be grouped together. This is especially useful if arrays of structs are created. If you look closely, you notice that the set of return values or arguments is already a struct now and the notation will be consistent with this proposal.

Change to function signatures as needed for function identifiers

As function signatures omit parameter names and only specify their types, and struct types should be a generalisation of a list of parameters / return parameters, the following change is proposed:

At any point where a type is allowed, a list of types in the from (type1,type2,..) is permitted, to the extent where there may be only one type. Examples:

function f((uint256[],uint8,(string,bytes20),(string))[20])

The function takes an array of 20 objects, each of which is of the following type:

  • The first value is a dynamic array of uint256s,
  • the second is a uint8,
  • the third is an object that consists of a string and a bytes20
  • the fourth is an object that only holds a string

Note that this notation is (hopefully) bijective.

Encoding

Structs are actually already part of the encoding specification, hidden in this comment. The gist is that the way arrays are encoded does not rely on the fact that the encoding of every element of the array is the same, so we can encode structs in just the same way as we encode arrays. This means that the encoding of a struct with only fixed-size types is the concatenation of the encodings of its elements. If there are dynamic types, their dynamic part is added at the end and the offset to the dynamic part is calculated from the start of the struct. This means that the offset to the string data is computed in a different way for (uint256,string) and (uint256,(string)).

JSON-formatted abi:

inputs and outputs is an array of objects with properties name (optional), type, subtype (optional, new) and indexed (for events). type can be any of the already supported types ("uint256", "uint256[10][]", ...), but additional values are permitted:

  • "[]" or "[k]" for some integer k (or a sequence of those, i.e. [][10][]): If this is used, the object is of array type and the type of the elements of the arrays is specified under the property subtype.
  • an non-empty array of objects as described here - this models a tuple.

If the subtype property is used, its value cannot be "[]" or "[k]", but it can be an array of length 1 whose element models the type one deeper in the array hierarchy.

Example:

The signature function f(abc: uint, def: (a: uint, b: (c: string, d: uint16)[10]))) is translated into json-abi as follows:

{
  name: "f",
  inputs: [
    {name: "abc", type: "uint256"},
    {name: "def", type: [
      {name: "a", type: "uint256"},
      {name: "b", type: "[10]", subtype: [{name: "c", type: "string"}, {name: "d", type: "uint16"}]}
    ]}
  ]
}

Identity based Standard Global Dictionary - Localisation / Categories / Descriptions

To have a global dictionary which can be used as an standard for wording of keywords, titles, descriptions, categories and localisation.

For example:

I have a contract which allows for categorisation for example an Augur Event (pick another business domain for your liking ie: Insurance, Zoo Animals, Tracker).

The market can be of many categories, ie Political, Election, Country, Regional, etc..

If we have a global standard dictionary:
Political could be 1, Election can be 20, US, 31, UK 32... etc.

Then a market could be assigned an array of multiple identifiers which can be easily identify, translated, make accessible and data mine.

EIP 105 (Serenity): Binary sharding plus contract calling semantics

This EIP is a solidification of a proposal to implement a simple binary sharding scheme in Ethereum, in the spirit of what was shown at Devcon 1 here: https://docs.google.com/presentation/d/1CjD0W4l4-CwHKUvfF5Vlps76fKLEC6pIwu1a_kC_YRQ

Design goals include:

  • Minimal initial implementation complexity, while at the same time serving as an effective "on-ramp" easing the transition toward a fully scalable Ethereum 2.0
  • Backward-compatibility with the existing Ethereum 1.0 contracts/state/applications (though the economics of ethereum 2.0 may eventually render some of the contract interactions that are currently happening prohibitively expensive even if they remain theoretically possible)
  • Flexibility, including the ability to expand and decrease the de-facto number of "shards" as needed
  • The ability to offer something equivalent to sharding at a "sub-contract" level, or some similar mechanism in order to allow individual contract developers to easily create applications that are themselves sharded and scalable.
  • The ability to offer a flexible tradeoff to developers between transaction cost and being able to make synchronous calls across a large state

We can describe the scheme as follows:

  1. There is now a new type of object, called a transaction group. A transaction group specifies a list of transactions, a gas limit, and an activity range of size 2**k between 2**k * m and 2**k * (m+1), for some values k, m where 144 <= k <= 160,m >= 0 and 2**k * (m+1) <= 2**160. The intuition is that any valid activity range constitutes a "shard", with each block of 2**144 being a "bottom level shard". Every shard that is not bottom level can also be decomposed into two "child shards", one for the left half of its range and one for the right half.
  2. Transactions now also specify activity ranges. Transaction groups cannot include transactions whose activity range is outside their own.
  3. Instead of containing a tree of transactions, a block now contains a list of transaction groups, which MUST have disjoint activity ranges.
  4. When executing a transaction, any CALL or other operation that attempts to access an address which is outside of the transaction's containing group's activity range immediately triggers an out-of-range exception. New RANGEMIN and RANGEMAX opcodes are added to make it easier for developers to deal with this.
  5. When creating a new account, a transaction will now automatically set the first 160-k bits of the address so that the account that it creates will fit into the containing transaction group's range. CREATE operations work similarly, except that they always set the first 16 bits of the target address to fit into the same bottom-level shard.
  6. New specialized SSTORE and SLOAD opcodes are introduced along the existing ones, such that these opcodes take an additional "shard ID" as an argument, where the shard ID should be in the range 0 < k <= 65535. A contract at address A can use these opcodes to read and write the storage of addressk * 2**144 + A % 2**144, provided that this address is within the current activity range. Use of these opcodes will also fill in the target address's code to equal the sender's, if it is not yet set.
  7. Contracts now store a code hash at key '' in the tree, not the actual code (this reduces data duplication arising from (5)).
  8. The receipts for a transaction are now saved in the leftmost shard allowed by the transaction group (ie. at MINRANGE + (d % 2**144) where d is the current address of the receipt storing contract).
  9. If GL is the global gas limit, the transaction group gas limits must satisfy the formula sum([max(L[i]**1.5, L[i] *GL / 4) for L in transaction_group_gas_limits]) < GL**1.5. This allows blocks to include more gas, up to a maximum 4x increase, if they include transactions that can be executed in parallel (this limit can later on be removed or relaxed once proper sharding is implemented).

Philosophically speaking, this introduces the following considerations:

  • There are now three types of exceptional conditions, rather than two as before: (i) out-of-gas, (ii) preventable errors arising from badly written code, and (iii, newly) out-of-range. Out of range should be viewed as being philosophically similar to out of gas, and similar kinds of guards in the code should be used to prevent attacks in both cases.
  • The preferred paradigm for making scalable applications will now be to create a receipt in one shard representing half of a completed operation, and then consume the receipt in another shard, verifying it using a merkle branch plus the STATEROOT opcode. A precompile contract for doing this will likely be added. Applications designed to be asynchronous will thus always benefit from the highest gas discounts as each transaction will only need to touch one contract.
  • High-level languages will likely include a shardedMap primitive, perhaps allowing a user-specified sharding schema (eg. shard = address // 2**144, shard = sha3(name) % 65536, etc), allowing contracts to store state across multiple shards.
  • Contract code can now be safely processed in parallel, introducing an immediate ~2-8x scalability benefit for the public ethereum blockchain assuming that miners have multicore processors, and a much larger scalability benefit for ethereum private chains; in a private chain context, the problems in http://www.multichain.com/blog/2015/11/smart-contracts-slow-blockchains/ would be completely solved.
  • It may be possible to make Ethereum massively scalable (defined either as "can safely process 10000+ tx/sec" or "transaction processing capacity quadratic in the processing power of a single node") with no further changes, if almost all validators under this scheme become comfortable mining/staking without running full validating nodes, instead employing collaborative validation strategies where they randomly poll other nodes on the validity of blocks on some shards and individually validate other shards. Hence, in the event that the Ethereum developers get blown up by [insert crazies here] or the foundation goes bankrupt, Ethereum will be much more well-suited to scale over time with only minimal further work on the core protocol if need be.

From an economics perspective, the following observations can be made:

  • Contract creators now have the ability to make a choice between being in shards where the contracts that they care to interact with are highly concentrated (and thereby benefit from network effects) and being in shards where contracts are rarefied (and thereby benefit from cost savings). This is very similar to the tradeoff faced by humans deciding whether to live in a big city or in a smaller city or the countryside, and so many insights from urban economics may be transferable.
  • Existing contracts do NOT have the ability to move between shards if they are unhappy with a change in the congestion/cost tradeoff of a given shard that arises from changes in the ecosystem; addresses are static. However, they do have an alternative escape valve: de-facto splitting and merging the shards that they are in. If a given shard becomes too congested, its gas price will go up, and so users will increasingly prefer to make operations that are limited to one of its two sub-shards; if enough people do this, then transaction groups at the higher shard level will be rare and transaction groups at the sub-shard level will be more frequent, thereby increasing the "distance" between the shards. Instead of (or rather, alongside) the citizens moving, the city itself shrinks or grows.

In order to process all transaction execution in parallel between transaction groups in a completely disjoint fashion, there are two possible routes from a data structure standpoint. The first is to modify the tree structure so as to have a depth-16 binary tree at the top level. The second is to implement Patricia tree splitting and merging (see python implemented code here: ethereum/pyethereum@81d37fc ), and do it all with the existing hexary Patricia tree: when processing every block, the process becomes split -> process in parallel -> merge. The former route may be slightly more efficient in the long term, the latter seems more efficient in the short term and may require writing slightly less code (though the code that does need to be written for split/merge is somewhat involved).

Note that if the 144-bit address plus 16-bit sharding scheme is undesirable because it unreasonably splits up existing contracts, we can also take the route of 160-bit addresses plus 16-bit shards for a total of 176 bit addresses.

ERC: Token standard

The final standard can be found here: https://eips.ethereum.org/EIPS/eip-20


ERC: 20
Title: Token standard
Status: Draft
Type: Informational
Created: 19-11.2015
Resolution: https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs

Abstract

The following describes standard functions a token contract can implement.

Motivation

Those will allow dapps and wallets to handle tokens across multiple interfaces/dapps.

The most important here are, transfer, balanceOf and the Transfer event.

Specification

Token

Methods

NOTE: An important point is that callers should handle false from returns (bool success). Callers should not assume that false is never returned!

totalSupply

function totalSupply() constant returns (uint256 totalSupply)

Get the total token supply

balanceOf

function balanceOf(address _owner) constant returns (uint256 balance)

Get the account balance of another account with address _owner

transfer

function transfer(address _to, uint256 _value) returns (bool success)

Send _value amount of tokens to address _to

transferFrom

function transferFrom(address _from, address _to, uint256 _value) returns (bool success)

Send _value amount of tokens from address _from to address _to

The transferFrom method is used for a withdraw workflow, allowing contracts to send tokens on your behalf, for example to "deposit" to a contract address and/or to charge fees in sub-currencies; the command should fail unless the _from account has deliberately authorized the sender of the message via some mechanism; we propose these standardized APIs for approval:

approve

function approve(address _spender, uint256 _value) returns (bool success)

Allow _spender to withdraw from your account, multiple times, up to the _value amount. If this function is called again it overwrites the current allowance with _value.

allowance

function allowance(address _owner, address _spender) constant returns (uint256 remaining)

Returns the amount which _spender is still allowed to withdraw from _owner

Events

Transfer

event Transfer(address indexed _from, address indexed _to, uint256 _value)

Triggered when tokens are transferred.

Approval

event Approval(address indexed _owner, address indexed _spender, uint256 _value)

Triggered whenever approve(address _spender, uint256 _value) is called.

History

Historical links related to this standard:

Question on EIP3: CALLDEPTH

link: https://eips.ethereum.org/EIPS/eip-3

IMO it's a good practice to check return value of callee if consequential operations is dependent and critical, if so what's the advantage of checking CALLDEPTH instead of return value?

Another point is, even if you use CALLDEPTH to guard stack overflow, you may still need return value guard in case there's other errors, thus leads to more verbose code?

Standardize start of version string reported by clients

As exposed by http://ethernodes.org/, we have a lack of basic uniformity in our "agent version" strings.

I would like to propose that we add a RECOMMENDATION that all agents report the following three entries at the START of the version name, followed by whatever else makes sense.

Name/Version/OS/*

For example:

Geth/v1.3.3/darwin/go1.5.2
++eth/v0.9.41-ed7a8a35/Windows/Release/msvc/JIT
Ethereum(J)/v1.0.0/Linux/Dev/Java

See also ethereum/webthree-umbrella#128.

EIP 106: Rename "contract" to "snork" in documentation and everywhere else.

The term "contract" is arguably a poor fit for the core building block of Ethereum (i.e., the account type / object on the blockchain). Because it's the name of that building block, we've wound up using it to refer to our simple applications, games, and other things that a far, far apart from contracts at law and possibly even the smart contracts, at least as Nick Szabo defined them. "Have you checked out my tic tac toe contract?"

I propose we re-name it a "snork." Like the things in the cartoon from the 80’s. It's fun. It's got nostalgic appeal. And, best of all, it's completely use case-agnostic and has no confusing legal connotations.

Contract autobounce funds

(An idea I've had for a while, also spoken of by chriseth at DEVCON1.)

Right now, contracts default to accept all incoming funds, only returning or forwarding funds if specifically coded to. This creates a situation where the creator either has to code most methods to return funds or just accept that "mistake" funds will be sent periodically and add a "drain funds" method to recover them.

Shouldn't a developer be able to specify "autobounce" at the contract level to change invert the current default behavior? In this situation, the coder would have to include an "accept offered funds" line in the code at each appropriate location, but in practice, that'll end up being far few times than returning funds in all error scenarios.

ERC: Pub/Sub + web sockets in web3.js

ERC: 25
Title: Pub/Sub + web sockets in web3.js
Status: Draft
Type: Informational
Created: 08.01.2016
Resolution: https://github.com/ethereum/web3.js

Abstract

This ERC is to get some opinions on the coming changes in the RPC layer and the web3.js API.
We want to introduce a publication/subscription support for the RPC layer, so that dapps can subscribe for events and get notified when they happened, without that they have to constantly poll for information.

Motivation

The main motivation for this is to provide a modern push based API for dapps, to reduce the CPU and code overhead for constant polling of data.

Once a dapp crosses a certain size, the amount of information it requires to be notified by the node rises.
Some information, will only happen very rarely and some more often. With the current polling cycle we make come easily up to a batch request with 20-40 request, which we poll every 200ms.
This creates a CPU overhead in the dapp as well as in the node, in 95% of the cases the requests come back with not change.

So push to the rescue.
We introduced a new push API, based on the JSON RPC 2.0 notification support and already implemented that in the geth node's RPC layer.
It works fine with the current IPC socket connection and is implemented in the web3.js#subscriptions branch.

To make it working for the HTTP transport layer we need to introduce web socket support.

This ERC is mainly to discuss the pros and cons of moving to web sockets. Whether normal HTTP requests should be deprecated or not etc.

Usage

Web sockets will be introduced like another provider and will work the same as the currently existing IPC provider. Once you choose to use the web socket provider, all communication (method calls, notfications) go through an open web socket created by the provider module.

Pros and Cons

As much as web sockets improve the development of dapps, it has some certain drawbacks and based on those, we need to decide in which direction to go here.

Pros

  • push notifications, allowing for pub/sub
  • faster notification
  • less CPU usage on the node (no polling request to process) and on the Dapps (no sending and analysing of poll cycles)

Cons

  • in the current implementation, subscriptions are based on sockets, so lost connections would require the dapp to re-subscribe (or we could try to do this automatically in web3.js)
  • web sockets are problematic on mobile devices, due to the cell tower switches and unstable internet connections
    • certain cell towers/mobile providers, can cancel and regain connections without the dapp being notified, therefore loose the subscription without noticing it
    • some mobile providers don't allow web sockets at all. (could be an outdated info)
  • Dapps couldn't make synchronous calls anymore, as web sockets don't allow that (which are a no go for UI's anyway).

Deprecation

Ideally i would like to remove all polling code from web3.js and the nodes RPC side, so that for notifications sockets is the only way. This will clean up the complexity of both web3.js and the node and remove the need to maintain a legacy connection.

We could keep the HTTP request based providers for all simple calls. This would allow to still request, but not use filters etc anymore, as they would require push.

Community Request

Please give comments and reasons, why we should go in one way or another. Please lets keep this ERC short :)

Spending gas from contract's balance - proposed optional opcode for a contract

Currently the gas limit is defined and paid by the caller. This proposal is about adding an option to the VM to set an alternate gas limit and gas source (the contract) by means of executing a special opcode within the contract, e.g. PAYGAS <limit>

A simple use case: the contract decides that the caller is on the list of trusted sources (for example it is a token holder) and takes over paying the gas. Alternatively the gas limit provided by the caller is used until exhausted, before using the contract's balance. This would be especially useful at fallback entry points enabling simple transactions to interact with a contract.

As you can see this idea is a a very early stage and comments are more than welcome.

Change ABI to provide a string reason for a throw in Solidity

Currently a throw does not supply any particular reason why the contract threw, and this could get confusing not just for developers but for people who are utilizing contracts as they grow and become more complex. More information is a nice thing especially when dealing with something as new as Solidity. Would love to hear opinion on this.

ENUM as ABI type

A FAQ on the solidity docs:

If I return an enum, I only get integer values in web3.js. How to get the named values?
Enums are not supported by the ABI, they are just supported by Solidity. You have to do the mapping yourself for now, we might provide some help later.

Enums would actually very useful types to be exposed on the ABI, specially for auto generated interfaces on the wallet and on abi2html, for example. On the read side, properties could be exposed as words instead of meaningless integers. On the execute side, enums could be rendered as drop down or radio boxes.

This would make interface creation easier.

Ethereum Request for Comments (ERCs) and Ethereum Standards (ESDs)

Should we have something like ERC (Ethereum Request for Comments, like the IETF's RFC https://www.ietf.org/rfc.html) ?
Or do we want to somehow expand the notion of EIPs to include them?

The items in https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs are top candidates for ERCs.

https://en.wikipedia.org/wiki/Request_for_Comments
https://en.wikipedia.org/wiki/Internet_Standard

Then down the line (could take a while), some ERCs could be ESDs (Ethereum Standards).

This is relevant now, since token "standards" are being discussed quite heavily:
https://gist.github.com/frozeman/090ae32041bcfe120824

Simpler signing and verifying procedure

To make the life of developers on ethereum, many encountering the tools of cryptography for the first time, the ECDSA for signing and verifying a message should be as simple as possible (but no simpler).
I believe that the current procedure is more complicated than necessary, which gives rise to confusion:
http://ethereum.stackexchange.com/questions/1777/workflow-on-signing-a-string-with-private-key-followed-by-signature-verification
http://ethereum.stackexchange.com/questions/710/how-can-i-verify-a-cryptographic-signature-that-was-produced-by-an-ethereum-addr/718#

I propose that the intermediate steps of hashing the message should be removed, and that developers shouldn't have to deal with ECDSA values r, s and v at all, just a 65 byte signature.
The procedure would then be as simple as:
With web3 or in the javascript console:

signature = web3.eth_sign(address, message)

Which could then be directly used in a solidity contract as:

function verify(message, signature, address) returns (bool valid) {
   address signer = ecrecover(message, signature);
   if (signer == address) {
      return true;
   }
   else {
      return false;
   }
}

If there are use cases where one wants to sign a message that has already been hashed, then this option could be passed as an option to the functions, like: signature = eth_sign(address, hash, {hashed: true}) or ecrecover(hash, signature, {hashed: true})

A prerequisite of this is of course that all clients return the signature in the same format, so first this issue needs to be addressed.

APIs for Transferable Fungibles

The specification is at the wiki https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs#transferable-fungibles so that it can be edited by anyone.
The wiki is initially from https://gist.github.com/frozeman/090ae32041bcfe120824 from which prior discussion should be viewed.
This issue is created per obscuren's suggestion on Gitter.
Anyone can provide content/suggestions for Abstract, Motivation etc.

  EIP: 
  Title: APIs for Transferable Fungibles
  Author: 
  Status: Draft
  Type: Informational
  Created: 2015-11-19

==Abstract==
Although Ethereum allows developers to create absolutely any kind of application without restriction to specific feature types, and prides itself on its "lack of features", there is nevertheless a need to standardize certain very common use cases in order to allow users and applications to more easily interact with each other. This includes sending currency units.

==Motivation==

==Specification==
https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs#transferable-fungibles

==Rationale==

==Implementation==

Safer Ethereum Address Format

Motivation

The primary motivation is to have a safer address format used for user-to-user and user-to-contract transactions/interactions.

Secondary motivations:

  • try not to reinvent the wheel
  • try sticking with Ethereum supported hashing methods and not introducing new ones
  • make it easily implementable in contracts if needed (but it shouldn't be)

Clarification regarding in-contract implementation: assuming there is a contract call which receives an address type as a parameter, the client software should be able to convert the proposed address format to the raw Ethereum address and send that in the request.

Implementation across the ecosystem

It should be initially implemented in client side solutions and the network endpoints (RPC) would receive the current addresses. If #55 is implemented on the RPC level it would be easy to convert this format to that.

Probably it is safe to assume that data sent to the RPC/network level should be validated by the clients and no change is proposed to those levels.

Other formats

The ICAP format can safely store a reduced set of Ethereum addresses (called direct ICAP). The basic ICAP is a format allowing storage of all Ethereum addresses at the risk of checksum collision. This has been raised multiple times, see #57 and #70. The ICAP format also supports indirect ICAP addresses which work through a name registry. Maybe it is better to leave that to its own format - the ICAP.

The checksumming proposed in #55 is clever at being backward compatible. I like it personally and implemented where possible, but I do not think it is a complete solution.

Specification

1) The internally stored data should be (similar to how Bitcoin addresses are built):

[flags: 8 bit][address: 160 bit][checksum: 32 bit]

where flags is a configuration field for future extensions and checksum corresponds to the lowest 32 bits of the sha3/keccak hash of the address. (This is different to Bitcoin.)

2) This binary data should then be encoded using a defined alphabet, more on that later.

3) A prefix (such as E, ET, ETH) would be very useful to make the address easily recognizable. This prefix could either be manually appended as a string or be part of the binary (as a special value producing those letters after the transformation).

I am leaning towards just using the prefix as a string and not being part of the binary data.

Contracts

I am not entirely sure, but it might make sense having either a flag or a different prefix to distinguish between external accounts and contract addresses.

One of the reasons is that without querying the network it would be clear that different gas costs would apply for making a value transfer. And it would be clear in which case contract interactions are possible.

Alphabets

Before deciding on an alphabet an important question to answer is whether we anticipate these addresses to be typed in or purely copy-pasted. If the ability to type in is important, probably an alphabet should be used which eliminates obvious errors (i = l = 1, 0 = o, u = v).

I have experimented with different alphabets and have no conclusion yet. ethbase are made up by me. I like ethbase-2 and ethbase-3.

ethbase-1         abcdefghjklmnopqrstvwxyz
ethbase-2         0123456789abcdefhklmnorstuwxz
ethbase-3         123456789abcdefhklmnorstuwxz
ethbase-4         ABCDEFGHJKLMNOPQRSTVWXYZ
ethbase-5         987654321
base-36           0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
base-55           123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuwxyz
base-58           123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
rfc4648 base32    ABCDEFGHIJKLMNOPQRSTUVWXYZ234567
z-base-32         ybndrfg8ejkmcpqxot1uwisza345h769
crockford base-32 0123456789ABCDEFGHJKMNPQRSTVWXYZ
base32hex         0123456789ABCDEFGHIJKLMNOPQRSTUV
nintendo base-32  0123456789BCDFGHJKLMNPQRSTVWXYZ

Examples

These don't have the prefix suggested above (and have flag = 1). I can generate a larger set and publish as a gist if needed.

address           ef51080ba7c0921f19fb4617c229678c88553389
ethbase-1         bhhnzhazaxzqtyqpgcddhbatkdfegfznxcyyososbex
ethbase-2         b7195o3ketcot844shuhbmt9le64f3t8oot79k3s
ethbase-3         2k635kfubsm93f7bkr46nkmem7l68slcs8l57ckse
ethbase-4         BHHNZHAZAXZQTYQPGCDDHBATKDFEGFZNXCYYOSOSBEX
ethbase-5         3326143634584248146854755777454147652553325927564561848478919
base-36           365QOV5A3FL2W2P3ERQZMIVMISU372HKN92TV9
base-55           5U46LNtk1tnMEudAacfbUAE9c6GBc2D4qw
base-58           n9zZ7sByjfR294rDVqYCy2uUv3tYa5pnQ
rfc4648 base32    HXVCCALU7AJEHYZ7NDBPQRJM6GIQVJTRFQKV2FV
z-base-32         8zinnymw9yjr8a39pdbxotjc6geoijutfoki4fi
crockford base-32 7QN220BMZ0947RSZD31FGH9CY68GN9KH5GANT5N
base32hex         7NL220BKV0947OPVD31FGH9CU68GL9JH5GALQ5L
nintendo base-32  TVQ3YCLSRJHWGYF3GVGRX5RVMJFQFD5H97002T6
address           f843c676c0f3d5e1ac47472056ff55da9e2e42c9
ethbase-1         bhxcvrmhfnbcgvkayjhpqmvmnxxkbhozmkphoqvyybk
ethbase-2         bcx3ubwz1m2b5c6k409hm3fclno2u1r5c5b76bm2
ethbase-3         2kzcww8rmueftlwc6u4urn3u7ddma9mbhnzd8krr6
ethbase-4         BHXCVRMHFNBCGVKAYJHPQMVMNXXKBHOZMKPHOQVYYBK
ethbase-5         3217136285259645423933751837977796654267814649388588342414353
base-36           387ZIM0R4FK6UKHTA3AL8Q24LQCVOCWY4CTWGX
base-55           5YVYc2Hhm73jgRuMbu3KNpDUbaQdsrRcby
base-58           nyJknndQU58JASatAcvYNJfribXu1TBAY
rfc4648 base32    H4EHRTWYDZ5LYNMI5DSAVX7KXNJ4LSCZF5TPBNB
z-base-32         8hr8tusad37mapce7d1yiz9kzpjhm1n3f7uxbpb
crockford base-32 7W47HKPR3SXBRDC8X3J0NQZAQD9WBJ2S5XKF1D1
base32hex         7S47HJMO3PTBODC8T3I0LNVAND9SBI2P5TJF1D1
nintendo base-32  VB63KWM6FYQLN299G31CHS1W61M6BZYBQCWNJRC

Alternative solution

A possible alternative solution is sticking with the hex alphabet (base-16) and checksumming the content using the method described in #55.

Important differences:

  • include any flag or data suggested above
  • strip the hex prefix so the mixed-caps won't be modified by software believing it is a hex string, which is case agnostic

eth_sendTransactionToNonNeighbors

Abstract

This proposal helps prevent correlating transactions to individual ip addresses. It does this by giving clients the ability to broadcast transactions only to their non-neighbor peers.

Motivation

A user may wish to broadcast a transaction that cannot be linked to their ip address. However, an attacker can sybil attack a node by generating a node id close to the target. Once an attacker has a similar node id, it becomes a "neighbor node". As a neighbor node, it is easier to perform traffic analysis to determine which transactions originated from the target node.

Design

Adds two rpc methods eth_sendTransactionToNonNeighbors and eth_sendRawTransactionToNonNeighbors. These methods mirror eth_sendTransaction and eth_sendRawTransaction, however they only broadcast to non-neighboring nodes only.

EIP 5: Gas costs for return values

Proposal

Change memory gas costs for return values of a call to be applied depending on the size of the written memory area, not the reserved memory area.

Current Situation

In a call, the caller has to provide an area where the returned data from a call is written to. Only reserving it already changes gas costs for memory.

Advantage

This makes it possible to read a return value whose size is not known to the caller prior to the call: The caller just reserves a huge amount of memory.

Possible Extension

The CALL opcode (and its friends) may even return the actual size of memory written to, so that the data can be used (e.g. forwarded) even if nothing is known about its structure.

Implementation

The implementation might be a bit tricky: The CALL opcode has to be charged some gas upfront, then the call is performed without allocating memory for the return value. At the point, the return value is available, gas costs are computed and if some gas is still available, memory is allocated and written to.

Support RSA signature verification

I propose to support RSA signature verification through a precompiled contract with appropriate fees.

With the current EVM, verification for very low key lengths is trivially implemented using the native 256 bit arithmetic, although it is useless due to inadequate security. Supporting bigger key lengths is prohibitive cost wise. (Requires implementing a bignum library for mul and mod on top of EVM. Alternatively it can be offloaded to an oracle, where trust can be a problem and is also suboptimal.)

Motivation: many PKI schemes, including those employed by government ID cards, rely on RSA. Supporting an easy way to verify a signature would mean to support authentication/authorization using those schemes in a smart contract.

High level method: rsaverify(msg, N, e, S, paddingScheme), where

  • msg is the message hash,
  • N is the public key modulus,
  • e is the public key exponent
  • and S is the signature.

Returns a boolean.

Regarding padding schemes I would definitely include an option none, where no padding would be applied and the caller would be expected to handle that.

Challenges: Where this gets complex is defining which key lengths and padding schemes to support and how to define the API. Size of N could be used to determine key length. Possibly the fee would depend on the key length.

Yet another cool checksum address encoding

EDITOR UPDATE (2017-08-24): This EIP is now located at https://eips.ethereum.org/EIPS/eip-55. Please go there for the correct specification. The text below may be incorrect or outdated, and is not maintained.

Code:

def checksum_encode(addr): # Takes a 20-byte binary address as input
    o = ''
    v = utils.big_endian_to_int(utils.sha3(addr))
    for i, c in enumerate(addr.encode('hex')):
        if c in '0123456789':
            o += c
        else:
            o += c.upper() if (v & (2**(255 - i))) else c.lower()
    return '0x'+o

In English, convert the address to hex, but if the ith digit is a letter (ie. it's one of abcdef) print it in uppercase if the ith bit of the hash of the address (in binary form) is 1 otherwise print it in lowercase.

Benefits:

  • Backwards compatible with many hex parsers that accept mixed case, allowing it to be easily introduced over time
  • Keeps the length at 40 characters
  • The average address will have 60 check bits, and less than 1 in 1 million addresses will have less than 32 check bits; this is stronger performance than nearly all other check schemes. Note that the very tiny chance that a given address will have very few check bits is dwarfed by the chance in any scheme that a bad address will randomly pass a check

UPDATE: I was actually wrong in my math above. I forgot that the check bits are per-hex-character, not per-bit (facepalm). On average there will be 15 check bits per address, and the net probability that a randomly generated address if mistyped will accidentally pass a check is 0.0247%. This is a ~50x improvement over ICAP, but not as good as a 4-byte check code.

Examples:

  • 0xCd2a3d9f938e13Cd947eC05ABC7fe734df8DD826 (the "cow" address)
  • 0x9Ca0e998dF92c5351cEcbBb6Dba82Ac2266f7e0C
  • 0xcB16D0E54450Cdd2368476E762B09D147972b637

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.