Ethereum (ETH) - POW/POS - Ethash

  • Ethereum Name System (ENS)The Next Phase Of The Internet: Joining The Dots

    Since its initial release in July 2015, the rate of development seen by Ethereum has been nothing short of incredible. The Ethereum value exchange network outperforms Bitcoin in terms of speed, cost, reliability, and energy efficiency and its smart contract platform for programming is gaining traction as the de facto platform for building distributed applications. Very soon, all of the dots for the next phase of the internet will be in place for Dapp developers and users to join together. The internet of tomorrow will be an internet of value and those who participate in it will be able to seamlessly make exchanges using programmable digital currencies, such as Ethereum.

    The history of the internet began with a basic, yet highly functional, closed academic and military network, which soon found widespread use in homes and businesses all over the world. From there we saw the rise of high-speed connections, advanced search engines, and mobile cloud computing. But while the rate of progress has been staggering, there have also been challenges ranging from centralization and fraud to establishing convenience of use. While Ethereum may not be the cure-all solution, it has the benefit of being able to stand on the shoulders of giants and develop solutions in a first principles way.

    From a primitive point of view, Ethereum's technology can be thought of as a way to manage value in a manner that is cheap, efficient, and secure. However, the most valuable aspect of Ethereum is the potential for developers to build on top of its platform, led by their imaginations and the needs and wants of their users. Here we will explore some interesting projects that could go on to improve the internet of tomorrow.

    Ethereum Name System Just like the Internet Domain Name System (DNS), the Ethereum Name System (ENS) allows users to interact with Ethereum addresses by way of user-friendly names rather than raw, 160-bit hashes that are almost impossible to remember or manually dictate/transcribe without error. Imagine trying to remember and type in the IP address of your favorite website every time you wanted to visit. This is currently how one interacts with a contract or sends tokens, which leads to a lot of copying and pasting. This is OK if you have time to check or you're a computer, but it's not very human-friendly and not conducive to the mass rollout of Ethereum in the real world.

    ENS is currently live on testnet, where you can register names and see how the process works.ENS will go live on the mainnet on “Pi Day” (March 14th) and another .com-style gold rush may be expected. ENS is designed to be as flexible as possible and allows for non-ASCII characters, but the minimum domain name length will be seven characters. That means no apple.eth or google.eth, though this could change in the future, as it is hoped that the major internet browsers will soon support the .eth domain name.

    The registration of .eth names is straightforward and fair –
    involving an auction process that discourages domain name squatting.
    Full details can be found on the official Ethereum ENS GitHub page.
    The main Ethereum clients (e.g. geth) have supported name registration
    commands for several months now and there's an easy-to-use plugin for
    Mist available that allows people to comfortably register a .eth domain
    name using a GUI.

    Identity Ethereum is a fundamentally distributed protocol in terms of its architecture, where all accounts and addresses are treated equally. But what if authorized and/or identified addresses are required for a particular business use-case? That's where identity providers can come in to accredit an account or contract address so that participants can trust that the entity they're doing business with is who they say they are. The Ethereum Foundation doesn't get involved in identity directly, however, there are a number of very interesting projects underway that allow users to identify themselves. The possibilities of an identified/authorized/compliant Ethereum are endless but include compatibility with today's banking rules, secure voting, and anti-fraud and anti-terrorism regulations. One of the most exciting identity projects currently underway is contract codes, and iPhone/Android codes available for the development of next-generation identity-enabled Dapps. Other identity platforms of note include Thompson Reuters' blockchain-based identity service underpinned by Thompson Reuters. Another identity service is Storage

    We're well used to storing data in the cloud - access speed, latency, and geographical content delivery has improved tremendously in recent years. Ethereum-incentivized distributed filesystems aren't seeking to replace the cloud offerings of Microsoft, Amazon, Google, etc., but to offer options, new tools, and new technologies to application developers so that they can potentially serve their content more efficiently than by using a global cloud provider.

    Two of the most well-known distributed file storage projects nearing release are InterPlanetary Filesystem (IPFS) and Swarm. Both are very similar technologies in that they store files on an economically incentivized network of peer-to-peer distributed computers. But while Swarm uses raw Ethereum tokens as its incentive system, IPFS will use its own token called "Filecoin." Payment is used to prevent files from being tampered with and to ensure that files are served on demand with low latency and high bandwidth. At this point, it's too early to tell if one storage system will obviate the other, but this technology has the potential to revolutionize many application areas with cheap, uninterruptable, and secure storage.

    Swarm is currently undergoing testing, and the public can upload files to it free of charge. However, files uploaded to Swarm are regularly purged and it's not quite clear how storage node operators can protect themselves from storing and serving unwanted, objectionable, or even illegal content. The legalities of such file storage systems could prove to be an area of contention, but technical steps can be taken to give node operators a degree of plausible deniability. Regardless, the project's development continues full steam ahead as these details are worked out.

    As of this publication, it's possible to open files from Swarm directly in your web browser by using the Swarm gateway ( Once ENS is live and web browsers start supporting the bzz: protocol, interacting with Swarm will be as seamless as serving files from any of the major cloud providers.

    Smart Contract Platform and PoS Ethereum's smart contract platform is at the heart of the internet of the future. The Ethereum Virtual Machine (EVM) is the world's most advanced and battle-tested platform for the deployment of smart contract-based applications and the number of Ethereum nodes online is increasing all the time (there are almost 7000, globally, as of this writing); with most nodes currently located in Europe, Asia, and North America. The upgrade release schedule presents new features every couple of weeks. The next major milestone for Ethereum's development is the transition to proof-of-stake (PoS), which will vastly improve Ethereum’s energy efficiency, but more importantly, will improve Ethereum’s scalability and ensure that it is even more resistant to centralization attempts. When we observe the current state of Bitcoin, we see what can happen if mining power is controlled by a handful of mining farm operators, many of whom do business with each other inside the same jurisdiction. These kinds of risks could lead to much bigger problems but Ethereum is taking active steps to shift the focus from mining to validation, hoping to meet these challenges head on.

    Availability of Advanced Development Tools The core development effort is focused on protocol - ensuring that the demands of performance are met before anything else can happen. But most developers and business analysts don't operate at this level - they want an EVM that works, want to be able to build applications yesterday, and have access to the tools they need to make it happen as fast as possible. The availability of such tools will accelerate the deployment of Ethereum in the real world - that means real businesses and real people using Ethereum in everyday situations. One project of note, Truffle, is from ConsenSys and is currently the most popular Ethereum development framework. The availability of Truffle is a tremendous gift to the Ethereum community, in that it guides application developers in a systematic way and forces them to be more aware of security.

    Looking Forward A lot of recent media focus has been on high dollar value ICO token sales and upcoming Dapps, but perhaps much of the work that's been going on behind the scenes has been missed. It's impatient to demand a series of "unicorn" Dapps at this early stage of smart contract technology - the first "killer app" may not be in the form of an ICO'd Dapp but could instead present itself as something much more primitive, with immediate practical benefits. Once this base infrastructure is set in place over the coming months, the core foundation will be there for developers to build more advanced Dapps that solve real world problems, without having to build from scratch and/or reinvent the wheel. Q1 2017 has been a very exciting time - Ethereum has fully recovered from last year's DAO set-back and resolved a few security quibbles that occurred during DevCon. This is reflected in the healthy exchange rate and an impressive pace of new user adoption. As we look further into 2017 and beyond, it's clear that the bigger picture is emerging and the transformational effect of Ethereum's advanced value exchange network and smart contract platform will be at the heart of the internet of tomorrow.


    Eamonn Hynes

  • Ethereum Virtual Machine for Coq (v0.0.2)

    Author, Yoichi Hirai

    Here is the version 0.0.2 of eth-isabelleproject. Now it can produce a Coq definition of the Ethereum Virtual Machine. The project provides a formal definition of the Ethereum Virtual Machine for interactive theorem provers. So far, the project provided the definition for Isabelle/HOL and HOL4. From version 0.0.2, the Coq version is available. Now it should be possible in Coq to prove Ethereum smart contracts correct.


    The logo of Coq (distributed under LGPL).

    The Coq version of the EVM definition is highly experimental because of the way it is generated. The original definition is written in a language called Lem, and the original is translated into different interactive theorem provers. I hear that Lem works well with HOL4 and Isabelle/HOL but that Coq extraction is harder to control. Sami Mäkelä spent a lot of time adjusting the Lem definitions so that the Coq extraction passes syntax & type-checking. The HOL extraction is in a similar state.

    The development is in an early stage, so any suggestion is welcome. The definition should be able to run a program on EVM until it returns, fails or calls something.

    After cloning the project and putting the Lem executable (lem) in the PATH,

    make lem-coq

    should generate the Coq version. With/usr/local/share/lem/coq-libcompiled,

    cd lem

    should compile the Coq EVM definition.

    Currently, the Coq version has no theorems built on top. Some Isabelle proofs are in example directory using the Isabelle version.

  • Ethereum Core Developer Meeting #10 and #11 Notes & Audio

    Audio of Meeting


    1. New EIP GitHub process and cleanup. [Facilitator: Hudson]
    2. Come to final agreement on EIP 196: zk-SNARK precompiles [Facilitator: Christian]
    3. Update on EIP for precompiles for elliptic curve point addition, elliptic curve scalar multiplication and pairing [Facilitator: Christian]
    4. Metropolis and associated EIPs. [Facilitator: Vitalik/Christian]
    5. EIP 5/8: Gas costs for return valuesEIP 86: Proposed initial abstraction changes for Metropolis [Facilitator: Vitalik]
    6. EIP 96: putting block hashes and state roots into the stateEIP 100: uncle mining incentive fix [Facilitator: Vitalik]
    7. EIPs 196197: pairings [Facilitator: Christian/Vitalik]
    8. EIP 198: bigint arithmetic [Facilitator: Vitalik]
    9. ethereum/EIPs#206: Revert OPCODE and ethereum/EIPs#207: Encoding of revert OPCODE [Facilitator: Vitalik]
    10. STATIC_CALL: ethereum/EIPs#116 follow-up. [Facilitator: Christian]



    1: pairing precompile: Gas still to be determined after we have some implementations, probably linear in the number of pairings

    2: EC operations: Also, gas still to be determined, multiplication similiar to EXP

    3: 5/8: compromise proposal (needed to make proposal B backwards compatible): new rules only if the return size is 2^256-1 Nick: seems complicated, what about adding “returndatasize” and “returndatacopy” similar to “calldatasize” and “calldatacopy” that can access return data even if return area size was specified as zero

    4: 86 (account abstraction):



  • Formal methods on another Casper


    Yoichi Hirai

    In a previous post, I talked about proving properties of Vitalik’s Casper. This post is about Vlad’s Casper. They are very different. The two Caspers are not just two different protocols, but two opposite approaches to protocol designs.

    Vitalik’s Casper looks implementable. It is a direct construction that solves a simple problem first and puts on more and more sophistication to match the real requirements.

    Vlad’s Casper is more like an effort to find fundamental difficulties. It leaves not-so-fundamental problems open and focuses on the essence. The hardest core of the problem comes from asynchrony, where messages can be delayed and reshuffled. This is equivalent to nodes being slowed down at arbitrary rates. That, in turn, is equivalent to having an attacker making as many moves as it wants, at any moment. The core of the problem is how to establish secure knowledge about the future, just by looking at the subjective past.

    Vlad’s Casper at the current form does not specify the way of communication between validators. Is it round-based? No, but even a round-based protocol can be analyzed as one instantiation of Vlad’s Casper. Does it have liveness assumptions? No, but arbitrary assumptions on the message delays or validator liveness can be added to Vlad’s Casper. It is a stem cell of many protocols. It is also a gauge that can measure many different-looking algorithms.

    I guess it’s just 5% of Vlad’s Casper, but somehow Vlad and I proved some portion of his Casper in Isabelle/HOL.The code is available on GitHub.

    Toward the end of this first part, the most important notion is estimate-safety: “an estimate is safe based on a view.” The special thing about it is, any participant can locally judge if an estimate is safe just by looking at their view of the past, and the safety would tell them the estimate is never going to change. That’s the solution to the hardest problem of establishing a secure knowledge about the future just by looking at the subjective past. Vlad’s Casper goes further and describes an algorithm that guarantees the estimate-safety, but we have not formalized this algorithm in Isabelle/HOL.

    At one point one needs to stop talking and start typing code. This is the same as in software development. The first lines are typically boring. That’s why it’s important to look ahead and talk freely, sometimes. After knowing what we want, sometimes we can endure the boring parts.

    Validators. What are validators? We don’t know much. We just say there are as many validators as there are integers. Integers in Isabelle/HOL are infinitely many.

    datatype validator = Validator int

    After we say this, Isabelle/HOL allows us to compare two validators and see if they are equal or not. It does not allow us to “add” or “multiply” validators. It does not allow us to ask if a validator is larger than another validator. It does not allow us to compare a validator against an integer. That’s a comfortable situation. We are protected from many mistakes.

    Validators have weights. We just talk about functions that assign weights to validators.

    type_synonym weight = “validator ⇒ int”

    After we say this, whenever Isabelle/HOL sees weight, it does not see weightbut sees validator => int, which is the type of (usual total) functions that take validators and return integers. The function just returns one integer on every validator.

    Of course, we can specify properties on the weight functions.

    definition tie_breaking :: “validator set ⇒ weight ⇒ bool”
    “tie_breaking V w =
     ( ∀ S0 S1.
     S0 ⊆ V ⟶
     S1 ⊆ V ⟶
     S0 ≠ S1 ⟶
     sum w S0 ≠ sum w S1 )”

    After typing these lines, Isabelle/HOL knows tie_breakingmeans something. It does not automatically replace occurrences of tie_breakingwith the lengthier definition, but it’s aware thattie_breakingis defined. Some plugins even look at the content of the definitions to figure out how to (dis)prove stuff.

    The weight function w is tie_breakingon the validator set if and only if, for arbitrary different subsets S0 and S1of V, the sum of over S0 is not equal to the sum of over S1.

    The initial part of the formalization is boring but also dangerous. A mistake here might cost thousands of lines later. Maybe we should perform an experiment. Let’s say there are two validators of weight one; then the tie-breaking property should not hold. We prepare a uniform weight function that assigns 1 to every validator.

    definition uniform_weight :: “validator ⇒ int” 
    “uniform_weight v = 1”

    On this uniform weight function should be tie-breaking on two validators.

    lemma should_be_false: “¬ tie_breaking {Validator 0, Validator 1} uniform_weight“

    When a user types in this statement, Isabelle/HOL tries to find a counter-example for a second or two (if you want a longer check, type nitpick). At the same time Isabelle/HOL echoes back the statement, as the goal to be proven.

    proof (prove)
    goal (1 subgoal):
     1. ¬ tie_breaking {Validator 0, Validator 1} uniform_weight

    Now it’s up to the user how to prove this. I said, “use the definition of tie_breaking and crunch down the goal.”

    apply(simp add: tie_breaking_def)

    Isabelle/HOL replies immediately with the result.

    proof (prove)
    goal (1 subgoal):
     1. ∃S0⊆{Validator 0, Validator 1}. ∃S1⊆{Validator 0, Validator 1}. S0 ≠ S1 ∧ sum uniform_weight S0 = sum uniform_weight S1

    The crunched-down statement reads like; there exist two different subsets of{Validator 0, Validator 1} over which the sum of uniform_weight is the same.

    Again it’s my turn what to do. I have to pick S0 and S1 that witness the tie-breaking property. When I actually do that (I’m not showing the commands anymore), Isabelle/HOL acknowledges the theorem.

    theorem should_be_false:
    ¬ tie_breaking {Validator 0, Validator 1} uniform_weight

    I have another conjecture: any weight function should be tie_breaking on an infinite set of validators. In Isabelle/HOL, sum over an infinite set is defined to be zero. I haven’t checked this conjecture, but moved on to bets and views.

    In Vlad’s Casper, validators sign bets. A bet contains an estimate. Intuitively the estimate is on the outcome of the consensus, but we don’t rely on this intuition. Our problem is to set up some criteria on a validator’s behavior, and ultimately to build a game that rewards and punishes validators. The validators might be purely implemented as a computer program or as a swarm of bees. So it does not make much sense to ask the validators’ intensions. The whole game must be defined using only the observable behavior.

    Who observes the validator’s behavior? I don’t know. We don’t need to know this right now. Whoever observes the validators’ bets, an observation would contain a set of bets signed by validators.

    Eventually, we will want to form a consensus on a history. The desired history might be linear or not. Depending on the contents of the history, some events might be compatible with other events. That sort of combinatorics causes its own headaches. So, the problem is a binary choice right now: choosing one of two values. This is another act of delaying a smaller problem and focusing on the essence.

    Isabelle/HOL has a datatype with two values: a boolean. Using this, we define a datatype called estimate.

    datatype estimate = Estimate bool

    After I type this, Estimate True andEstimate False are two different estimates. There are no other estimates.

    A bet is inductively defined as a triple of a validator (signer), an estimate and a set of bets (justifications). I said “inductively defined as” because otherwise the sentence didn’t form a definition. Can a bet’s justification’s justification contain the first bet in question? Can one start with one bet and find a justification, and a justification of that, and so on infinitely? The answer to both questions is “no”, as we will prove later, but that’s just because I said “inductively”.

    In Isabelle/HOL, every datatype definition is taken as an inductive definition. I don’t have to say “inductive” there.

    datatype bet =
     Bet “estimate * validator * bet list”

    Something tricky happens here. I don’t know how Isabelle/HOL handles this. Somehow Isabelle/HOL proves a theorem in the background (this statement looks particularly ugly, but don’t be scared. Isabelle/HOL is usually very nice-looking on the UI):
     (⋀xa. (⋀xaa xaaa xaaaa. xaa ∈ Basic_BNFs.snds xa ⟹ xaaa ∈ Basic_BNFs.snds xaa ⟹ xaaaa ∈ set xaaa ⟹ ?P xaaaa) ⟹
     ?P (Bet xa)) ⟹
     ?P ?bet

    This allows one to prove things about all bets by mathematical induction.

    The sender of a bet is the validator contained in the bet:

    fun sender :: “bet ⇒ validator”
    “sender (Bet (_, v, _)) = v”

    The estimate of a bet is the estimate contained in the bet:

    fun est :: “bet ⇒ estimate”
    “est (Bet (e, _, _)) = e”

    A bet justifies a bet if the former is one of the justifications of the latter:

    fun justifies :: “bet ⇒ (bet ⇒ bool)”
    “justifies b (Bet (e, v, js)) = (b ∈ set js)”

    A bet depends on a bet when there is a sequence of justification from the latter to former. “justifies” is a binary relation on bets, and “is_dependency” is a transitive closure of that.

    A transitive closure can be defined as:

    inductive tran :: “(bet ⇒ bet ⇒ bool) ⇒ (bet ⇒ bet ⇒ bool)”
      tran_simple: “R x y ⟹ tran R x y”
    | tran_composit: “tran R x y ⟹ R y z ⟹ tran R x z”

    “tran R” is the smallest binary relation on bets such that “tran R x y” holds in two cases, 1) simply “R x y” holds, and when 2) “tran R x y” and “R y z” hold.

    I have to say “the smallest” because the above two conditions are not specific enough to identify a single binary relation “tran R”. For instance, the conditions hold even if “tran R” connects every two bets. (Does this “smallest” thing exist? Good question!

    After doing this, we can just say “is_dependency” is the transitive closure of “justifies”.

    definition is_dependency :: “bet ⇒ bet ⇒ bool”
    “is_dependency = tran justifies”

    In the definition of transitive closure, I said “tran R x y” and “R y z”. I could have added the third case “R x y” and “tran R y z”, but that shouldn’t have changed the transitive closure.

    lemma is_dependency_tail_first :
     “tran R y z ⟹ R x y ⟹ tran R x z”

    The proof is induction on the transitive closure.

    I said the definition of bets is inductive. So I can prove that two bets are not mutually in dependency. There are no cycles of justifications. There are no vicious cycles, so to speak.

    lemma dependency_no_cycle :
     “∀ a. is_dependency a b ⟶ ¬ is_dependency b a”

    The proof is induction on b. The proof is interesting because the induction does not decrease the size of the cycle.

    There is a less exciting fact that “is_dependency” is indeed transitive.

    lemma dependency_is_transitive :
     “is_dependency y z ⟹
      ∀ x. is_dependency x y ⟶ is_dependency x z”

    The proof is induction over transitive closure.

    After so much bureaucracy, here is a meaningful concept. A validator equivocates when it signs two different bets, none of which is dependent on the other. This is the Casper equivalent of double-spending. Equivocation means not keeping one’s own linear history.

    definition equivocation :: “bet ⇒ bet ⇒ bool”
    “equivocation b0 b1 =
     (sender b0 = sender b1 ∧ ¬ is_dependency b0 b1
     ∧ ¬ is_dependency b1 b0 ∧ b0 ≠ b1 )”

    This says, two bets b0 and b1 form an equivocation when they are from the same sender, neither depends on the other and  are different.

    A view is a set of bets that does not contain equivocation.

    definition is_view :: “bet set ⇒ bool”
    “is_view bs = (∀ b0 b1. b0 ∈ bs ⟶ b1 ∈ bs ⟶ ¬ equivocation b0 b1)”

    A set of bets is a view if and only if no two bets in the set form an equivocation.

    We are usually interested in the latest bets from a validator.

    definition latest_bets :: “bet set ⇒ validator ⇒ bet set”
    “ latest_bets bs v =
       { l . l ∈ bs ∧ sender l = v 
          ∧ (¬ (∃ b’. b’ ∈ bs ∧ sender b’ = v ∧ is_dependency l b’))}“

    I’m very sorry that (an alphabet) and ∨ (the symbol for disjunction) look very similar. In the definition above, there is only the alphabet vee, not the disjunction symbol. The latest bets in a set bs of bets from a validator vconsist of those bets in bs whose sender is v, which is not dependency of any bet in bs from v.

    Regardless of validators, we can also talk about the latest bets in a set of bets.

    definition is_latest_in :: “bet ⇒ bet set ⇒ bool”
    “is_latest_in b bs =
      (b ∈ bs ∧ (¬ (∃ b’. b’ ∈ bs ∧ is_dependency b b’)))”

    A bet is latest in a set of bets when the bet is an element of the set and the bet is not dependency of any bet in the set.

    A set is non-empty when it has an element:

    definition is_non_empty :: “‘a set ⇒ bool”
    “is_non_empty bs = ( ∃b. b∈bs )”

    When a set of bets is finite and non-empty, it has latest bets:

    lemma latest_existence’ :
     “finite bs ⟹ is_non_empty bs ⟶ (∃ l. is_latest_in l bs)”

    This depends on the fact that the chain of justifications does not form a cycle. The finiteness is necessary because otherwise there all bets might belong in an infinite chain of justification.

    An interesting thing about the latest bets from a validator is, there can be only one unless the validator has equivocated. When there are two different latest bets from the same validator, they form an equivocation.

    lemma two_latests_are_equivocation :
     “b0 ∈ latest_bets bs v ⟹ b1 ∈ latest_bets bs v ⟹ b0 ≠ b1 ⟹ equivocation b0 b1”

    A set has at most one element when any two elements are equal:

    definition at_most_one :: “‘a set ⇒ bool”
    “at_most_one s = (∀ x y. x ∈ s ⟶ y ∈ s ⟶ x = y)”

    Since a view does not contain equivocation, a view can contain at most one latest bet from a validator:

    lemma view_has_at_most_one_latest_bet :
     “is_view bs ⟹ at_most_one (latest_bets bs v)”

    Sometimes we are interested in validators who have signed bets in a set of bets:

    definition observed_validators :: “bet set ⇒ validator set” 
     “observed_validators bs =
    ({v :: validator. ∃b. b ∈ bs ∧ v = sender b })”

    The observed validators in a set of bets consist of those validators who have signed some bets in the set. Note that this does not consider the justifications that are out of the set.

    So, in a non-empty set of bets, we can find some validators.

    lemma observed_validators_exist_in_non_empty_bet_set :
     “is_non_empty bs ⟹ is_non_empty (observed_validators bs)”

    Maybe more interestingly, if the set of bets is empty, an observed validator always has a latest bet.

    lemma observed_validator_has_latest_bet :
     “finite bs ⟶ v ∈ (observed_validators bs) ⟶ is_non_empty (latest_bets bs v)”

    Combining the above two, we know existence of a validator who has at least on latest bet, always on a finite non-empty set of bets.

    lemma latest_bets_exist_in_non_empty_bet_set :
     “finite bs ⟹
     is_non_empty bs ⟹
     ∃v::validator.(is_non_empty (latest_bets bs v))”

    We are interested in which validators are currently supporting which estimate. A validator has a latest bet on an estimate when it has a latest bet that contains the estimate.

    definition has_a_latest_bet_on ::
     “bet set ⇒ validator ⇒ estimate ⇒ bool”
    “has_a_latest_bet_on bs v e =
     (∃ b. b ∈ latest_bets bs v ∧ est b = e)”

    In a view, a validator cannot have a latest bet on different estimates:

    lemma validator_in_view_contributes_to_at_most_one_estimates_weight :
     “is_view bs ⟹
     ∀v. v∈(observed_validators bs) ⟶ at_most_one {e. (has_a_latest_bet_on bs v e)}”

    The latest bets are combined with the weight function to give a weight on an estimate in a set of bets. The weight is the sum of the weights of validators that have latest bets on the estimate.

    definition weight_of_estimate ::
     “bet set ⇒ weight ⇒ estimate ⇒ int”
    “weight_of_estimate bs w e =
     sum w { v. has_a_latest_bet_on bs v e }”

    Now we can talk about which estimate is leading the race. An estimate is a max-weight-estimate when its weight is at least as larget as other estimates’ weights.

    definition is_max_weight_estimate ::
     “bet set ⇒ weight ⇒ estimate ⇒ bool”
    “is_max_weight_estimate bs w e =
     (∀ e’.
     weight_of_estimate bs w e ≥ weight_of_estimate bs w e’)”

    Can there be more than one max-weight-estimates? No, under certain conditions: on a finite, non-empty view, with a positive, tie-breaking weight function.

    lemma view_has_at_most_one_max_weight_estimate :
     “is_view bs ⟹
     finite bs ⟹
     is_non_empty bs ⟹
     positive_weights (observed_validators bs) w ⟹
     tie_breaking (observed_validators bs) w ⟹
     at_most_one {e. is_max_weight_estimate bs w e}”

    With the notion of max-weight-estimate, now we are ready to describe the honest behavior. A validator should not equivocate. A validator should only produce valid bets.

    When a validator has justifications, since the justifications are bets, there are max-weight-estimates. A valid bet is on a max-weight-estimate of the justifications.

    fun is_valid :: “weight ⇒ bet ⇒ bool”
    “is_valid w (Bet (e, v, js))
      = is_max_weight_estimate (set js) w e”

    A valid view is a view that contains only valid bets:

    definition is_valid_view :: “weight ⇒ bet set ⇒ bool”
    “is_valid_view w bs = (is_view bs ∧ (∀ b ∈ bs. is_valid w b))”

    In a valid view, every bet is honestly created. No validators equivocate. All bets with justifications follow the max_weight rule. Here we are not dealing with Byzantine faults (when validators do whatever, slightly dishonest or completely random). Maybe, provably dishonest bets are dropped from a view.

    So far all arguments have been on one static set of bets. Now we talk about two views, one being a possible future of the other.

    definition is_future_view :: “weight ⇒ bet set ⇒ bet set ⇒ bool”
    “is_future_view w b0 b1 =
     (b0 ⊇ b1 ∧ is_valid_view w b0 ∧ is_valid_view w b1)”

    The definition of the future views requires the views to be valid views.

    Our goal was to ensure knowledge about the future based on an observation of the past. One form of desirable knowledge is estimate-safety. An estimate is safe when it is the max weight estimate on all future views:

    definition is_estimate_safe ::
       “weight ⇒ bet set ⇒ estimate ⇒ bool”
    “is_estimate_safe w bs e =
     (∀ bf. is_future_view w bf bs ⟶ is_max_weight_estimate bf w e)”

    When a participant gets a safe estimate, and another participant obtains a safe estimate, it’s desirable they are equal. If that’s the case, whoever reaches a safe estimate will share the same estimate.

    Two views are consistent when the union of them is a valid view.

    definition consistent_views :: “weight ⇒ bet set ⇒ bet set ⇒ bool”
    “consistent_views w b0 b1 =
     (is_valid_view w b0 ∧ is_valid_view w b1
     ∧ is_valid_view w (b0 ∪ b1))”

    We were able to prove a nice property about estimate safety. When an estimate is safe on a view, and another estimate is safe on another view, the two estimates always coincide.

    lemma consensus_safety :
     “finite b0 ⟹
     finite b1 ⟹
     is_non_empty b1 ⟹
     positive_weights (observed_validators b0) w ⟹
     positive_weights (observed_validators b1) w ⟹
     tie_breaking (observed_validators (b0 ∪ b1)) w ⟹
     is_estimate_safe w b0 e0 ⟹
     is_estimate_safe w b1 e1 ⟹
     consistent_views w b0 b1 ⟹
     e0 = e1”

    Essentially, when you have a safe estimate, you needn’t worry that your knowledge of the world might be imperfect. You don’t need to learn more. All other parties that learn well enough will reach the same estimate as yours. It’s time to shout (or quietly receive conviction), this estimate is going to be the consensus.

    It remains to see how to judge if an estimate is safe in a view. Vlad has this part on paper. He also has an implementation. The proof of the algorithm is not machine-checked yet.

  • Why Ethereum is great for payments


    Edmund Edgar

    Photo by Babak Fakhamzadeh (CC BY-NC-ND 2.0)

    Tech people love cool new things, and when we talk about Ethereum we hardly ever talk about it as a way of doing things Bitcoin could already do. But the experience of using Bitcoin to pay for things is getting increasingly painful, and it’s time has come to look at how Ethereum could help.

    Ethereum people have often tended to tip-toe around its usefulness for payments; Many cut their crypto teeth on Bitcoin, and they are generally uninterested in picking a fight.

    But I’m going to argue that Ethereum is not just capable of doing online payments, but actually seriously great.

    Ethereum payments are simpler

    People often think of Ethereum as a complicated technology. It’s true that to make full use of all its smart contract capabilities, you need to wrap your head around a bewildering array of technologies and sub-projects.

    But you don’t have to use all that stuff, and where it counts, payments on Ethereum are simple. Here’s why.

    UTXO Oh No

    There is no such thing as a Bitcoin. A Bitcoin transaction consists of actions performed against a payment you received earlier: combining previous payments and splitting previous payments.

    If I send you 10 Bitcoins, I may simply be forwarding the result of a previous payment I received from someone else of exactly 10 Bitcoins. But more likely I’m combining a number of previous payments together. And that hardly ever comes out at exactly the amount I want to send, so I’m also sending another payment back to myself.

    This gives users a lot of control over the way they handle payments that depend on each other. But when you look at a typical bitcoin wallet, you see very little about UTXO. Wallet authors know they’re doing: Elegant and powerful as it may be, the UTXO scheme doesn’t match the normal user’s mental model of what a wallet looks like.

    Wallet authors try hard to abstract this complexity away and hide it in the software internals, but the abstraction leaks. On a congested network, it leaks a lot.

    For example, every now and again someone will complain about the crazy fees they’re being charged to send a bitcoin transaction. Bitcoin veterans will then usually look at that transaction, nod sagely and explain that their transaction had a large number of inputs, so what do they expect? They’re right — but this is complexity that the wallet was explicitly trying not to bother the user with.

    In Ethereum, this doesn’t have to happen. A user’s account can be modeled as… an account. You can have a single balance, and it doesn’t matter how many payments it took to get you that balance. Wallets are simpler, less surprising stuff happens, and fees are easier to predict and explain. All payments cost the same, regardless of where the funds came from.

    Security is easier with Ethereum

    Smart contracts with yourself

    There’s no point in receiving money unless you can secure it, and securing private keys is hard.

    You can make a multi-sig address and put the keys in cold-storage, in bank vaults on multiple continents, but that makes it hard for you to spend. You can have an accessible key that you keep with you on your phone, but it’s hard for you to secure.

    Sometimes these cases fall naturally into the way we like to use different devices. You might have a wallet on your phone for small amounts of change and another on a hardware device for your life savings. But in practice people often need the ability to shift fairly large sums of money reasonably fast. Every now and again, the hot wallet of a bitcoin exchange gets hacked, and even after they have detected the theft, people keep sending money to it. Because bitcoin’s scripting system is so limited, they have no way of taking back control.

    There’s a lot we can do to make this process work better.

    • You want to be able to rate-limit routine payments secured by a particular process, so your money doesn’t all vanish at once.
    • When you’re using multiple keys and some of them are in cold storage, you should be able to replace one of them without taking all the others out of cold storage.
    • The way you secure the ability to *stop* money leaving your wallet needs to be different from the way you secure the ability to initiate one. The key that triggers, “Stop people spending this money” needs to be readily accessible, whereas the key that says “go ahead and hand over my life savings” needs to be highly secure.

    Smart contracts are usually mainly discussed as ways for different people to interact with each other, but they work just as well when we’re talking about keys held in different places, or funds that should only move according to user-defined rules. This is a contract that secures funds in this way in Ethereum. It didn’t take an academic paper to describe it, and it doesn’t take a lot of study to be able to read it and understand what it does.

    This stuff isn’t quite impossible in Bitcoin, but nobody does it because it’s insanely complicated.

    Busting out of the nerd ghetto

    A clear lesson from the early days of bitcoin is that regular users suck at managing private keys. This isn’t yet a solved problem on any platform, but for crypto-currency to break out of a nerd ghetto, we’re going to need some new kinds of tools. With state and a reasonably functional scripting environment, we’re starting to see fresh and imaginative solutions like uPort, which allows you to distribute trust among your friends.

    A better scaling game

    Ethereum fees are currently orders of magnitude lower than Bitcoin fees. But people moving from the one to the other will want to know why it won’t end up meeting the same fate if it becomes more popular. The good news is that Ethereum is in a much better position to scale to handle substantial numbers of payments than Bitcoin.

    An established governance procedure for capacity increases, not an endless political food-fight.

    Bitcoin’s block size has been stuck at 1 MB for years. Most bitcoin people say they support an increase in capacity, but Ethereum’s grows naturally through an automatic adjustment.

    More mature scaling tech

    Setting up a fully validating bitcoin node is notoriously slow. To validate new blocks, your node needs to know about all the transactions that it is currently possible to spend. To create this database, it has to look through every single block since Satoshi generated the genesis block from a headline from The Times. Only once it has downloaded these blocks can it “prune” them, throwing away most of the data that it just downloaded and leaving only the data that it needs to validate new transactions.

    There are proposals to make this list, called the UTXO set, more easily available to clients with less historical information. With UTXO Commitments, you organize the database in a tree and store its hash in the header of each block. Everyone agrees that this would be useful. But the actual implementations are still at the stage of bad-tempered nerd fights on mailing lists.

    In Ethereum this was a fundamental part of the design. Every block contains a hash of the tree of the current state database. If you can work out what block belongs to the longest valid chain, you can confirm the state of anything in the database. Among other benefits, this makes it safer to sync up a node without downloading everything that ever happened on the network. The result is that despite the Ethereum block chain already holding much more data than Bitcoin’s, you can get a fully validating node running in about 15 GB.

    Better prospects for off-chain systems

    Off-chain payment systems are smart contract systems

    The great hope for scaling bitcoin has long been that rather than needing to send every transaction to the blockchain, transactions can be exchanged out-of-band and only sent to the blockchain if there is a problem that needs to be resolved.

    This can be done on Bitcoin, with Bitcoin’s very limited scripting language. But it’s extremely hard to do, and even harder to do securely. People trying to build practical systems usually end up realizing that they need changes to Bitcoin’s scripting language, at which point they have to wait while the Bitcoin developers stroke their beards and try to think of all the possible ways the new feature could be used and whether they consider them helpful or harmful.

    These systems are smart contract systems, and Ethereum is designed for smart contracts. Because it already has an unrestricted scripting language and the ability to store and read information in the state database, off-chain systems can be simple, elegant and include functionality that is simply not possible in Bitcoin, at least without many more iterations of “please add this soft fork”.

    Raiden, Ethereum’s equivalent to Bitcoin’s much-awaited Lightening Network, now looks set to ship in useful form while Lightening is still waiting for bitcoin transaction system upgrades.

    The best approach for privacy, but not yet

    The weakness in all this is privacy. The UTXO model provides somewhat better privacy than the account model, so the simplest imaginable use of Ethereum will tend to provide less privacy than Bitcoin would have provided to date. And if you’re moving from Bitcoin to something else, you have options like Monero and Z-Cash, which provide a huge step up.

    Ethereum does not, on its own, provide good solutions for sending funds privately. But because it lets developers write their own contract logic, insights from these systems can be ported to Ethereum systems without changing Ethereum. Rather than needing to define your currency based on its privacy technology, you’ll be able to wrap existing coins and tokens in contracts that provide privacy. If a better technology comes along, you can move to it right away. This doesn’t help you today, but it’s a promising way to handle privacy tech, which is evolving fast and experiencing some teething troubles.

    Better money

    Ethereum is a great technology for sending people money on the internet. Maybe it wasn’t supposed to be, but it is.

  • A safe token sale mechanism


    Vlad Zamfir

    Hi everyone!

    I’m going to tell you about a token sale architecture that arguably has some nice safety properties.

    It implements a price floor and a price ceiling on the token being sold.

    Special thanks to Rick Dudley and Peter Borah for their help on this.

    I’m going to assume for the sake of clarity that everything is happening inside ethereum.

    Mechanism overview

    The mechanism has the followingparameters:

    1. Token sale price, which I sometimes call the ceiling price
    2. Token purchase price, which I sometimes call the floor price

    The token sale mechanism parameters can vary over time and are determined by the sale administrator.

    The administrator may be a fully automated smart contract, an externally operated account, or can be a smart contract with external participants. We could think of sale administrator as arole — I’m just going to assume that the sale administrator exists at some fixed ethereum address.

    The mechanism exposes the following functions:

    1. move_ceiling, and move_floorcallable only by the sale administrator.
    2. purchase_tokens, callable by the anyone.
    3. sell_tokens, callable by the anyone.
    4. The ERC20 token interface, callable by anyone.

    The sale mechanisms will sell any number of tokens at the sale price. By doing this, it will accumulate a balance. It will use its balance to buy any number of tokens at the purchase price.

    Purchasing tokens from the mechanism will increases the caller’s ERC20 balance, and selling tokens to the mechanism will decreases the caller’s ERC20 balance.

    The sale never ends. This means we can bound the price of the token above. It also means that the total supply of tokens is not necessarily bounded, and is almost certainly not fixed.

    A constant ceiling removes all reasonable expectation of return that token purchasers may otherwise have. Any low-enough ceiling can prevent “pumps-and-dumps” from pumping.

    The buy-back never ends. This means we can bound the price of the token below.

    This protects token purchasers from downside risk. This can isolate token purchasers from loss due to a token purchase. Any high-enough floor can prevent “pump-and-dumps” from dumping.

    I think this will be safer than the status quo we see in token sales today.

    This next section gives detail about why the purchase price is a price floor and why the sale price is a price ceiling. Skip if you don’t want to get bored. The section following this one is about how the beneficiaries of the sale benefit from the sale.

    Explaining the price ceiling and price floor

    The mechanism’s token sale price is aneffective price ceiling on the market for tokens.

    If there are bids on the open market for prices above the mechanism’s token sale price, traders can execute the following arbitrage strategy:

    1. buy tokens from the safe token sale mechanism
    2. sell tokens on the market
    3. repeat until these are no more bids above the token sale price

    This is why I refer to the token sale price as the ceiling price.

    Similarly, the mechanism’s tokenpurchase price is an effective price flooron the market for tokens.

    If there are offers on the open market for prices below the mechanism’s token purchase price, traders can execute the following arbitrage strategy:

    1. buy tokens on the market
    2. sell purchased tokens to the SafeTokenSale mechanism
    3. repeat until there are no more asks below the purchase price

    This is why I refer to the token purchase price as the floor price.

    The mechanism allows the sale administrator to place a floor and ceiling on the price of a token, taming otherwise volatile markets.

    Note that there are the following two edge cases:

    1. The sale administrator sets floor = ceiling forever, and the token purchasers are never exposed to any risk or any opportunity for returns.
    2. The sale administrator sets floor = 0, ceiling = infinity, perhaps after some time of having ceiling at a fixed or growing price.

    It is worth noting that the first precisely corresponds to a two-way peg of the type originally proposed for Bitcoin’s pegged sidechains, and that the second precisely corresponds to the most common finite-quantity sale models in today’s token crowd sale ecosystem.

    Note also that the sale administrator can’t raise the floor price if doing so would make it unable to purchase all of the tokens at the floor price.

    I left this part about how the beneficiaries of the sale get paid for later because I wanted to start by giving you a feeling for how and why this mechanism is safer for token purchasers than token sale architectures that are common today. I actually completely left it out of the “design overview” section, I hope you didn’t mind :)

    How the beneficiaries get paid

    Naively, we would propose that any of the funds in the sale mechanisms which are not allocated for buying back (all of the) tokens at the floor price can be withdrawn by the beneficiary at any time.

    However, there is potentially a big problem with this. The beneficiary of the sale could effectively buy tokens at the floor price by following the following two steps:

    1. Purchase tokens from the sale mechanism at sale_price
    2. Receive sale_price - purchase_price from the token sale mechanism as beneficiary, for every token purchased.

    In the end, the beneficiary will have spent sale_price - (sale_price -purchase_price) = purchase_price for every token purchased. This will allow the sale beneficiary to push the price of the tokens on the market to the floor price by following an arbitrage strategy similar to the one described in the previous section.

    We will give the responsibility of allocating funds to beneficiaries to the sale administrator, pushing the responsibility of preventing excessive “double-dipping” outside of the safe token sale protocol.

    Let us therefore give a revised list of methods exposed by the mechanism:

    1. move_ceiling, and move_floorcallable only by the sale administrator.
    2. purchase_tokens, callable by the anyone.
    3. sell_tokens, callable by the anyone.
    4. The ERC20 token interface, callable by anyone.
    5. allocate_funds_to_beneficiary,callable only by the sale administrator
    6. claim_revenue, callable only by anyone, throws an exception if the requested funds have not been allocated to the caller by the sale admin.

    Note thatallocate_funds_to_beneficiary fails if allocating those funds would mean that the sale mechanism is no longer able to buy back all tokens at the floor price if those funds were to be withdrawn. Note that similarly move_floor fails if the administrator tries to push the floor too low.

    A quick note on how investors might get paid

    Some of you may be concerned that the safe token sale mechanism removes at least some expectation of return from investors.

    Apple investors do not purchase products from Apple in expectation that their price will appreciate, but they purchase shares of Apple and receive revenues from Apple’s profit, which Apple has because people buy their products because their products are useful.

    The analogous story here is that investors should be paid out of funds allocated to beneficiaries (after beneficiaires pay expenses) rather than by expecting the token sold by the mechanism to appreciate.

    At least this is my philosophy for how to use the safe token sale mechanism. You might want to let the floor price fall to allow more funds to be allocated to the investors through the beneficiary, or to allow the ceiling price to rise to give token purchasers more upside potential.

    The mechanism can be parametrized — but please be safe!


    The “safe token sale mechanism” allows us to trade off between the interest of token purchasers and beneficiaries, while also being able to prevent (or at least effectively mitigate) pump-and-dumps. It provides flexibility to how the investors in an enterprise who wants to sell tokens can get paid.

    I hope that it can lead to a radical departure from the philosophy of token sales today, by giving up on the “fixed known supply” model in favour of the “this is a product that is sold in perpetuity to consumers who find it useful” model. It is possible — we do have the technology. But I’m just being crazy :)

    Really hope you like it!

  • March Madness (on Ethereum)

    Contract address: 0xae251c170b388fbbfb5a16f925b0ace951820200

    WARNING: This is not-even-beta software. USE AT YOUR OWN RISK and make sure you know what you are doing.


    3/12 9AM PST: Contract deployed! Submit a bracket before 11:00 AM EST on Thursday, March 16!


    Welcome to March, my favorite month! I love this month because here in America we host the best sports tournament on the planet - the NCAA Basketball Tournament (a.k.a. March Madness).

    64 college basketball teams from all across America go head-to-head in a single-elimination fight to the top. Well, technically there are 68 teams, but I'll get into that later.

    The week before the tournament starts, it is customary here in America to fill out brackets with your predictions of who will win each game. It's a lot of picks (59 games) and the probability of guessing every game correctly is 1 in 2.4 trillion. Within a bracket pool (usually comprised of your friends and family), the person who picks the most winners is crowned the champion. There are many strategies ranging from picking your favorite teams to always picking the highest seed (usually a bad idea in big pools) to consulting a probability distribution. Which is the best strategy? Who knows.

    As a huge Arizona basketball fan I thought it would be fun to put my Ethereum skills to the test and deploy a bracket pool to the Ethereum network.

    If you would like to participate (buy in is 0.5ETH), read on!

    Since I have a real job at ConsenSys and I just recently though of this, I don't have time to put out a fully functioning website, so I'm going to force you to use Python.


    The tournament starts promptly at 11:00 AM EST on Thursday, March 16 (unix = 1489680000) and concludes with the championship game at 9:00 PM EST on Monday, April 3 (ending roughly 3 hours later, at unix = 1491541200).

    How to participate

    You will fill out a bracket and submit this to the blockchain along with the buy-in cost of 0.5 ETH. You must submit your bracket before the tournament commences (i.e. before 1489680000). You may only submit one bracket per Ethereum address.

    Points are allocated as follows:

    • 1 point for submitting a braket
    • 1 point for each correctly chosen team in round of 64, 32, sweet 16, and elite 8
    • 2 points for each correctly chosen team in the final four
    • 4 points for the correctly chosen champion

    This means the highest possible score is 69.

    NOTE: Each game is scored independently of others, so as long as you pick the winning team, it doesn't matter if you incorrectly picked their opponent.

    I will be responsible for submitting the oracle bracket (that is, the winners of the each game). I will add to it each day once games are concluded and you may compare your score whenever you'd like (more on this later).

    Shortly after the tournament ends (give me ~15 min to update the oracle), you will have 72 hours to submit your score for review (ending at 1491541200). When you submit your score (discussed later), you will be added as the leader if your score is higher than the current leader score. The highest score wins. If there is a tie, the pool is distributed evenly across winners.

    And before you ask, yes I know that you need to trust me to be an arbiter of the truth. If you're uncomfortable with that, you are welcome to re-deploy this contract and start your own pool.

    What if something goes wrong?

    I have built an escape hatch so if something goes wrong, I will notify everyone with instructions on how to withdraw your 0.5 ETH. (I've actually already used this after I deployed a borked contract earlier) Sorry in advance if that happens.


    There are no fees. 100% of the pool goes to the winner[s].

    Creating a bracket

    Before doing anything, you will need this repo. Open up your command line, navigate to a new directory, and type the following:

    git clone

    Fill out a bracket

    It's probably a good idea to fill out a bracket visually first. You can find one herehere. You will only need this for reference later.

    I guess I should address the issue of there being 68 teams. For some reason, the NCAA tournament has the 4 weakest teams each play an extra game ahead of the tournament to vie for a 16 seed (the worst seed). Also, 4 "bubble" teams play for the 11 seed. Anyway, it's not important. What I'm going to do is let you pick either one of the extra teams to advance (basically treat them as a package). It will make more sense when you fill out the bracket.

    Transcribe your picks into this command line tool

    To boot up the tool:


    If you run into problems, make sure you have python installedpip installed and run pip install <packagename> (you may need to include sudo at the front if that doesn't work).

    Once the program in running, it will ask you for your picks for all 59 games. If at any time you want to reset your bracket, close out of the program (control+C) and restart. If it asks you to use an old bracket, say no.

    After you're done with your bracket, you will see something like the following:

    Cool. You've made your picks. Now we need to put it on the blockchain.
    Setup your bracket:
    Please copy the following string and send a raw transaction with it as the data parameter:

    That hex string at the bottom is what you will need to copy and paste into your Ethereum wallet in the data field.

    Sending your Ethereum transaction with MEW

    If you're using My Ether Wallet:

    1. Go to Send Ether & Tokens
    2. Set the To Address field to 0xae251c170b388fbbfb5a16f925b0ace951820200
    3. In the Amount to send field, put 0.5ETH.
    4. In the gasLimit put 2000000 (it shouldn't use this much and the remainder will be refunded).
    5. Click Advanced: Add Data and paste the hex string from before into the Data field.
    6. Sign and send the transaction!

    Sending your Ethereum transaction locally

    If you have a node running locally, you can do cURL requests:

    curl --data '{"method":"personal_unlockAccount","params":["<your address>","<your password>",null],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545
    curl --data '{"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{"to":"0xae251c170b388fbbfb5a16f925b0ace951820200","gas":"0x1E8480","value":"0x6F05B59D3B20000","from": "<your address>","data":"<string you got>"}],"id":1}'  -H "Content-Type: application/json" -X POST localhost:8545

    You have now created your bracket!

    During the tournament: Checking your score (optional)

    Once the tournament starts, you can check your score by opening up a web3 console and doing the following:

    var addr = "0xae251c170b388fbbfb5a16f925b0ace951820200";
    var abi = [{"constant":true,"inputs":[],"name":"pool","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"abort","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"user","type":"address"},{"name":"region","type":"uint8"}],"name":"getQuarter","outputs":[{"name":"","type":"uint8[15]"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"withdraw","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"south","type":"uint8[15]"},{"name":"west","type":"uint8[15]"},{"name":"east","type":"uint8[15]"},{"name":"midwest","type":"uint8[15]"},{"name":"finalFour","type":"uint8[4]"},{"name":"championship","type":"uint8[2]"}],"name":"setBracket","outputs":[{"name":"","type":"bool"}],"payable":true,"type":"function"},{"constant":false,"inputs":[],"name":"issueWinner","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"leadingScore","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"region","type":"uint8"}],"name":"getOracleQuarter","outputs":[{"name":"","type":"uint8[15]"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"user","type":"address"}],"name":"getFinals","outputs":[{"name":"","type":"uint8[6]"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"leaders","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"user","type":"address"}],"name":"getCurrentScore","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"ABORTED","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"scoreBracket","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"getOracleFinals","outputs":[{"name":"","type":"uint8[6]"}],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"}]
    var contract = web3.eth.contract(abi)
    var instance =
    // Check your score
    instance.getCurrentScore(<your address>)
    // Get the total pool (in wei)

    After the tournament: Submitting your score

    Once the championship ends, you have 72 hours to submit your score if you think it is high enough to win (note: you can't win if you don't submit!). You will need to submit a new transaction to claim it. Use the following as your data parameter:


    (fun fact: this is the first 4 bytes of the keccak_256 hash of the function you are calling, which is scoreBracket())

    Make sure you do this from the same address you used to make the bracket!

    Using MEW

    If you're using My Ether Wallet:

    1. Go to Send Ether & Tokens.
    2. In the Amount to send field, put 0.
    3. In the gasLimit put 2000000 (it shouldn't use this much and the remainder will be refunded).
    4. Click Advanced: Add Data and use 0xdc26824f for the Data parameter.
    5. Send the transaction!

    Using a local node:

    If you have a node running locally:

    curl --data '{"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{"to":"0xae251c170b388fbbfb5a16f925b0ace951820200","gas":"0x1E8480","from": "<your address>","data":"0xdc26824f"}],"id":1}'  -H "Content-Type: application/json" -X POST localhost:8545

    Before a winner is declared (optional)

    While you wait for the 72 hour window to pass, you can check the top scores using a web3 console:

    var addr = "0x2dcbe558103caa847d5580604272321284cc312a";
    var contract = web3.eth.contract([{"constant":false,"inputs":[],"name":"setAbort","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"pool","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"abort","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"user","type":"address"}],"name":"getQuarterScore","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"south","type":"uint8[15]"},{"name":"west","type":"uint8[15]"},{"name":"east","type":"uint8[15]"},{"name":"midwest","type":"uint8[15]"},{"name":"finalFour","type":"uint8[4]"},{"name":"championship","type":"uint8[2]"}],"name":"setBracket","outputs":[{"name":"","type":"bool"}],"payable":true,"type":"function"},{"constant":false,"inputs":[],"name":"issueWinner","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"leadingScore","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"leaders","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"user","type":"address"}],"name":"getCurrentScore","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"ABORTED","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"scoreBracket","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"user","type":"address"}],"name":"getFinalScores","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"}])
    var instance =
    // Get the leader(s) (hopefully this shows your address!)
    // Check the highest score

    Declaring a winner

    After the 72 hour submission period, I will call the issueWinner() function, which will send all funds to the winner(s) of the bracket pool. I will subsequently announce the winner and the winnings on Reddit.

    Good luck!


  • TrueBit Whitepaper Released

    TrueBit has quietly gone through a major upgrade, and Jason Teutsch and I are pleased to finally announce the official TrueBit 1.0 protocol, available on our project webpage. TrueBit’s fond and familiar “dispute resolution layer” still lies at the core of TrueBit’s construction, but we’ve wrapped it up inside of a new “incentive layer.” This new layer should both properly reward Verifiers and, in turn, force Solvers to behave correctly. Practically speaking, smart contracts with TrueBit can execute C++ code without running up against Ethereum’s gas limit. TrueBit itself is simply a smart contract, which means that we don’t need to introduce a hard fork, a soft fork, or disrupt legacy smart contracts to achieve full computing functionality.

    Some more technical details:

    For quite some time, the Ethereum community has known about the dispute resolution layer which Verifiers can invoke upon error detection. As a standalone system, however, the dispute resolution layer lacks incentives for Verifier participation. In TrueBit’s previous incarnation, if a Solver knew that a Verifier was watching closely, the Solver would not try to cheat. On the other hand, Verifiers receive little, if any, compensation for allocating their limited resources to watching Solvers closely. In this simple system, Verifiers only get rewarded when they identify Solvers’ mistakes, whereas their act of watching ensures that Solver mistakes never actually occur. This weird dynamic results in Verifiers inevitably becoming lazy over time and provides Solvers with opportunities to cheat.

    The obvious fix for this laziness issue is to reward the Verifier each time she checks a solution. But if a solution does not contain an error, how can the Verifier prove to a smart contract, whose computational bandwidth is limited, that she did indeed check it? To solve this problem, TrueBit 1.0 introduces a “forced error mechanism” which forces Solvers to occasionally produce incorrect outputs. By detecting and reporting such “forced errors,” Verifiers prove to the system that they are still paying attention.

    Please see our whitepaper for further details, analysis, and application ideas!



  • Ethereum-Solidity Version 0.4.10 Release 

    This release is focused on stability and also introduces some new smart contract safety features:requireassert andtransfer. Note that the newrevert function will only be gas-efficient starting from homestead.


    • Add assert(condition), which throws if condition is false (meant for internal errors).
    • Add require(condition), which throws if condition is false (meant for invalid input).
    • Commandline interface: Do not overwrite files unless forced.
    • Introduce .transfer(value) for sending Ether.
    • Code generator: Support revert()to abort with rolling back, but not consuming all gas.
    • Inline assembly: Support revert(EIP140) as an opcode.
    • Parser: Support scientific notation in numbers (e.g. 2e8 and 200e-2).
    • Type system: Support explicit conversion of external function to address.
    • Type system: Warn if base of exponentiation is literal (result type might be unexpected).
    • Type system: Warn if constant state variables are not compile-time constants.


    • Commandline interface: Always escape filenames (replace /:and . with _).
    • Commandline interface: Do not try creating paths . and ...
    • Commandline interface: Allow long library names.
    • Parser: Disallow octal literals.
    • Type system: Fix a crash caused by continuing on fatal errors in the code.
    • Type system: Disallow compound assignment for tuples.
    • Type system: Detect cyclic dependencies between constants.
    • Type system: Disallow arrays with negative length.
    • Type system: Fix a crash related to invalid binary operators.
    • Type system: Disallow vardeclaration with empty tuple type.
    • Type system: Correctly convert function argument types to pointers for member functions.
    • Type system: Move privateness of constructor into AST itself.
    • Inline assembly: Charge one stack slot for non-value types during analysis.
    • Assembly output: Print source location before the operation it refers to instead of after.
    • Optimizer: Stop trying to optimize tricky constants after a while.

    If you want to perform a source build, please only use solidity_0.4.10.tar.gz and not the zip provided by github directly.


  • Devcon 3 dates announced, November 1st-4th at Mexico

    Event information for attendees will be updated on the Devcon3 site as the event draws closer.  

    • Companies interested in corporate level sponsorships, please email us with the subject line Top Tier Sponsorships.
    • Startups, small companies and organizations, consultants, and developers, interested in Community Sponsorships, please email us with the subject line Community Sponsorships.
    • Ethereum developers and researchers submitting presentations, email us with the subject line: Presentation Proposal.

    Submissions for presentations should include:

    1. Title
    2. Short description or abstract
    3. Name of the presenter(s)
    4. Company, organization or institution name (if applicable)

    Contact the Devcon3 team via email at: [email protected]

    Media Contact: John Frazer, External Relations, [email protected]  

  • Beginner’s guide to own an Ethereum Name Service

    Disclaimer: you cannot truly own an ENS domain as of today. This guide is for you to exercise the bidding process on a test net(called Ropsten test net, not associated with real money). You do need to exercise since the ENS service will be on soon.

    Although ENS is not up and running today, I have a lot of faith on it. Consider when any Ethereum payment system is more widely adopted, how nice it would be if you have companyname.eth on your business card or website instead of 0xabc123…, which your customer will have to spellcheck 3 times before hitting the pay button.

    If you are going to bid for an ENS domain, you should prepare beforehand. For example, fund transfer from your bank to an Ethereum exchange might take 3 business days. You do not want to be doing that when the auction is ongoing. This guide is to help you choose the right tool, since when I was trying this out, I spent days without an instruction telling me everything I should use.

    I wanted to keep this guide short and also include a tl;dr section explaining which is what. Now the guide is already too long, I will consider to keep the rest in another topic.

    1.Own an exchange account

    As a prerequisite, own an Ethereum exchange account such as Coinbase or Kraken. Purchase more than 0.01 ETH multiplied by the number of domains you want to own.

    2. Install Homebrew.

    Most likely you already did it if you are a dev guy and you own a Macbook.

    3. Install Parity (a local Ethereum wallet) as follow in the Terminal app,

    brew tap ethcore/ethcore
    brew install parity --stable

    4. Install Geth

    brew tap ethereum/ethereum
    brew install ethereum

    5. Checkout the ens(ethereum name service) source code to a folder

    git clone

    6. Download a JSON file

    7. Start Parity in the Terminal by typing

    parity --jsonrpc --chain /path/to/ropsten.json

    8. Work with Parity UI

    Open a web browser (I use Opera) and type Create a wallet as prompted. Copy your wallet address. Later in the article I will refer to this page as Parity page.

    9. Get Ether from a faucet

    Go to and paste your wallet address. Go to the Parity page and make sure you receive 1 ETH. It might not arrive imminently, but if not, would do just within a minute.

    10. Attach geth to the Parity instance by,

    geth attach rpc:

    You should see a geth console (a ‘>’ symbol followed by where you can type in Terminal)

    11. Load script

    Remember where you downloaded ens? Hint: step 5. Type this in the geth terminal


    12. Follow the ENS documentation

    Now basically follow the official ENS document at Note all the commands go into the geth console.

    First, try out the FIFS registrar (This is not a must, but just to familiarize yourself for less surprise when you bid for .eth)

    • To ensure the domain name is available,
    new Date(testRegistrar.expiryTimes(web3.sha3('myname')).toNumber() * 1000)
    • Register the domain name
    testRegistrar.register(web3.sha3('myname'), eth.accounts[0], {from: eth.accounts[0]});
    • Verify you register well on FIFS registrar. Note FIFS’s extension is .test

    Second, bid a .eth domain

    • Check availability

    When you get 0, start your own auction. When get 1, bid as soon as possible, at least 2 days before the deadline

    • Start an auction
    ethRegistrar.startAuction(web3.sha3('name'), {from: eth.accounts[0], gas: 100000});
    • When you get 1, check if there are 48 hours before the deadline,
    new Date(ethRegistrar.entries(web3.sha3('name'))[2].toNumber() * 1000)
    var bid = ethRegistrar.shaBid(web3.sha3('name'), eth.accounts[0], web3.toWei(0.01, 'ether'), web3.sha3('secret'));
    ethRegistrar.newBid(bid, {from: eth.accounts[0], value: web3.toWei(0.01, 'ether'), gas: 500000});

    Third, reveal your bid within 2 days before the deadline.

    • In the time duration nobody else can bid (supposedly, but I heard there is a bug somebody can still bid, which is why ENS get delayed). Thus it is safe to reveal. You do not want others to see your bid, do you?
    ethRegistrar.unsealBid(web3.sha3('name'), eth.accounts[0], web3.toWei(0.01, 'ether'), web3.sha3('secret'), {from: eth.accounts[0], gas: 500000});

    Last, finalize the auction.

    • Someone needs to call a line to finalize the auction. I suspect the team could have designed the APIs that this step does not have to be manual. By the deadline, if you did not get your fund back in full, or you suspect you win, call this command,
    ethRegistrar.finalizeAuction(web3.sha3('name'), {from: eth.accounts[0], gas: 500000});
    • Find out if you are the winner,

    If you are, your wallet address is returned.

    13. Wait for the ENS auction

    You are not able to play with real money yet. Sites like this keeps track of ENS news. Keep visiting them to find out when ENS auction is ongoing. If you miss out the first week, you sure will miss out the hottest domain names people want to register.

    14. Start Parity on the main net

    Once the ENS auction is on, go to step 7. This time the command to run would be,

    parity --jsonrpc

    15. Transfer funds

    Luckily you had experience going step 1 through 12. Now it is much more safe to deal with real Ethers. Go to step 8 and copy your wallet address. From your exchange account, transfer Ethers to your wallet address. If your Parity is syncing, your wallet balance will not be updated until the syncing is finished(syncing would take hours, so do not be surprised). You can search your wallet address on If you see it has balance, no need to panic. Ethers usually arrive at your wallet no more than 5 minutes(usually much shorter) after you made the transfer.

    16. Load a different script

    Now follow everything starting step 9. At step 11, you need to instead type,


    Also you do not have to experiment with the FIFS registrar. Just start with real auctions.

    17. Be super careful when you work with real ethers. Avoid typos. Ethers are expensive today. Have fun bidding!



  • Ethereum Core Devs Meeting#12- 17/03/2017 

    All Core Devs: Meeting 12

    Time: 3/17/2017 14:00PM UTC

    Audio/Video of Meeting


    1. EIP signaling and voting system update [Facilitator: Hudson]
    2. In STATICCALL Opcode should state-changing operations should actually throw, or just be reverted after the call returns? [Facilitator: Nick and/or Martin]
    3. EIP 161


      1. EIP Signaling/Voting System [Hudson]

      There is a group from the Ethereum Foundation, Boardroom, Carbonvote, Metamask, and community volunteers who are creating the voting/signaling system for EIPs. It is going well. cdetrio has started making a compatibility table with a similar style of this one


      3. In STATICCALL Opcode should state-changing operations should actually throw, or just be reverted after the call returns? [Martin]

      Discussion on the potential security issues with implementing REVERT opcode, its effects on static analyzers, and other potential unwanted side effects. Martin: As soon as we implement revert, it may be possible to abuse revert functionality to artificially create provably pure calls. Do we want these different mechanisms?

      REVERT, STATIC_CALL, RETURNDATASIZE and RETURNDATACOPY opcode proposals have some interconnections that will be further discussed. They are somewhat cross-referenced in the EIP repositories README page.

      Full conversation happens 12:27-29:17.

      4. EIP 161

      5. Metropolis Update

      We are now going to put the most updated potential EIPs for metropolis in the EIPs Under Consideration section of the [EIP repo] ( and geth (

      Test Cases for EIPs [Martin]

      Martin: I want to mention that anyone implementing Metropolis changes and other EIPs need to submit their test cases to tackle weird edge cases. The things learned when implementing these changes will benefit all clients and prevent consensus issues.

      There is currently not a formal process to submit these test cases. Informal process is to talk to Martin or Dimitry about submitting the test cases. Peter: One of the issues for devs is that it is complicated and messy to create tests that no one bothers. Long term solution suggestion: tool that allows a simple way to create tests. A way to more automatically create test cases. Martin: I complete agree. For now, it is valuable for devs to write up descriptions and submit their test cases to send to Dimitry or others. Hudson: I will talk to Dimitry about a cleaner process in the future and formalizing a way to submit test cases.


      Alex Beregszaszi (EWASM), Andrei Maiboroda (cpp-ethereum), Arkadiy Paronyan (Parity), Casey Detrio (Volunteer), Christian Reitwiessner (cpp-ethereum/Solidity), Greg Colvin (EVM), Hudson Jameson (Ethereum Foundation), Jan Xie (ruby-ethereum & pyethereum), Martin Holst Swende (geth/security), Paweł Bylica (cpp-ethereum), Péter Szilágyi (geth), Vitalik Buterin (Research & pyethereum), Yoichi Hirai (EVM)

  • Ethereum JS Ecosystem Updates

    It’s been a fairly busy for the last couple of months for the Ethereum javascripters. To start with, there was a really great hackathon with IPFS. You can read Dan Finlay’s excellent write up here.

    Also, during this time Aaron Davis (Kumavislibp2p to build a in-browser mesh network and IPLDCasey Detrio worked on a standard json RPC test suite, which you can see the results of here.

    After the Seattle Meetup, we (AxicWanderer) sat down for a week long hackathon in Budapest to hash out some details of ewasmethjs. The rest of this post will be charting the various projections that this technology could provide as well as going into some details about each individual project. All these projects are all open source and encourage community participation, so if you are interested please check them out, say hello and send in a PR if you have time! 


    Ewasm’sWebassembly and secondarily, implement a client for the current system which can be efficiently JITed (or transcompiled) to WebAssembly.

    A major piece of evaluating WebAssembly for blockchain usage will be create a test network and this year the focus of the Ewasm team will be bringing that test network to life. The testnet work will:

    • enable hands-on work with ewasm for a wider audience
    • enable related work, such as experiments with casper to be done by providing a flexible platform for experimentation

    The ewasm track is dedicated to ewasm research and development, while the client integration track will be dedicated to developing the network and bring full and light clients into existence. But there are many shared components to these two tracks. The Ewasm project is being broken down into two main components: the Kernel Layer, which handles IPC and manages the state, and the core VM. This should enable us to use the same framework for different VM implementations.

    So to recap, the major tasks for ewasm are:

    • Build an ewasm test network
    • Creating a reusable “kernel” module
    • Revamp ethereumjs-vm
      • Use ewasm-kernel for the message passing
      • Implement the latest EIPs
    • Ewasm integration tools
    • Solidity-ewasm integration (upcoming effort for the solidity hackathon!)

    Please come join the implementation effort! We have semi-weekly meetings on Tuesdays. Our communication channel is on Matrix at prima:matrix.orggitter)


    There are several reasons to have an Ethereum networking implementation in JS. For one, it would allow us to implement a full and light Ethereum JS node. These light clients would run both in a node.js environment and in a browser. A prerequisite for an in-browser light client is “bridge” nodes. These nodes might also act as signaling serverswebrtc network that the browser light clients would use to relay  messages from the RLPx network to the webrtc network. This work is being spearheaded by Metamask using IPFS’s libp2p. Also the RLPxfanatid.


    Ethereum’s blockchain and on-chain state can be understood as a graph of hash-linked data. IPFS/IPLD is proposed as a generic system to describe and distribute hash-linked data. Therefore we can describe Ethereum as an application layer on top of the hash-linked data availability platform. As a proof of concept, KumavisIPLD resolvers for the Ethereum data formats that define where hash-links are encoded inside the canonical Ethereum formats (e.g. block and state trie node). This, combined with other generic features of libp2p (IPFS’s generic p2p networking stack), enables the creation of minimal Ethereum clients that focus on the consensus protocol and state transition mechanism. One advantage of this approach is that the networking layer is transport-agnostic and can be used in environments that don’t have access to tcp/udp (such as the browser) that the standard Ethereum clients require. This project is still in the research phase. MetaMask hopes to use this approach to implement a browser compatible Ethereum light client via a secondary network, bridged by hybrid nodes.

    Web3.js 1.0 incoming!

    A new version of web3.js is in the making. It is the biggest refactor of the codebase since the inception of the popular Ethereum library. It will have a lot of convenience features like confirmation and receipt event on transactions, a nice subscription API, and checksum checks on address inputs.

    The API is still not yet finalized, but if you are eager to have a look you can check out the docs here.

    The new version will also have quite a few breaking changes, but those updates are necessary to get the new API right and remove some some deprecated methods along the way, like synchronous calls. 1.0 will only have promises and in some events “PromiseEvents” to better reflect multiple events on a transaction’s execution. For those who are thinking of transitioning their apps to the new web3, there will be a migration guide upon launch to help make the transition from 0.x.x as easy as possible.

    In Mist there will be no web3 exposed by default anymore, as this encourages the bad habit of relying on the Mist-provided web3, which makes breaking changes disastrous for dapps. Instead, there will be an “ethereumProvider”, which libraries like web3 can use to talk to the underlying node. Web3.js will automatically detect any given provider and expose it on its API for easy instantiation.

    For those who can’t wait and want to try it right now, checkout the 1.0 branch in the web3.js repo. Be aware there might be dragons!


    EthjsEthereum geared to working with the json RPC, much like web3.js but lighter, async only and using bn.js. The current ongoing activity includes:

    • Adding the ABI methods for decoding logs in ethjs-abi
    • Having fixed a small decoding bug in ethjs-abi (handling 0x addresses)
    • Merged new schema for personal recover and sign ethjs-schema
    • Looking for help making ethjs-filter stateless (infura ready)
    • Bug fixing in ethjs-contract
    • Documentation updates all around
    • Upcoming ethjs version 0.2.7 release!


    Working on the 4.0.0 release! This release will include:

    • Database persistence. Now you can create a test chain and save that data, just like any other private chain!
    • Clean up of how data is stored in memory, which should reduce memory issues significantly. Although there will be a slight cost in some performance, which mostly be unnoticeable unless you’re making thousands of transactions, it will bring a huge increase in stability.
    • Bundling for the browser (provider only).
    • Easier installs on Windows, and possibly other platforms.

    We’ll be moving the TestRPC to the Truffle github organization since it’s primarily maintained by Truffle developers. There are significant new TestRPC add-ons coming. And we’re investing significant energy in documentation and branding that unifies it under the Truffle brand. Any feedback on this move is appreciated.  Lastly, the TestRPC needs a new name that exudes everything it can do. If you have an idea let us know!


    The Ethereum JS community is an exciting and wonderful thing to be a part of. There are many great projects happening. If you are interested in plug in we have weeklyFriday meetings at 3:00 EST / 10:00 PST / 18:00 UTC. Watch our gitter channelupcoming hackathon. Let us know if you are interested.


    Martin Becze

  • Ethereum  Trading Now Available in New York

    We are excited to announce that GDAX customers in New York can now trade Ether (ETH).

    New York hosts many of the world’s largest financial institutions and we have been working closely with the New York Department of Financial Services to expand the services we offer there. We are committed to operating the most secure and compliant digital asset exchange and are excited to offer this new asset to our customers.

    To get started trading ETH, simply login to your GDAX account and select the ETH/USD or ETH/BTC order book from the “select product” dropdown menu.


    Adam White

Log in to reply

Looks like your connection to Cryptocentral was lost, please wait while we try to reconnect.