<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Dan Robinson on Medium]]></title>
        <description><![CDATA[Stories by Dan Robinson on Medium]]></description>
        <link>https://medium.com/@danrobinson?source=rss-10c4e6618569------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*ZpCB4PGu_qBpoyer.jpg</url>
            <title>Stories by Dan Robinson on Medium</title>
            <link>https://medium.com/@danrobinson?source=rss-10c4e6618569------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 21:08:00 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@danrobinson/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Ethereum Is a Dark Forest]]></title>
            <link>https://medium.com/@danrobinson/ethereum-is-a-dark-forest-ecc5f0505dff?source=rss-10c4e6618569------2</link>
            <guid isPermaLink="false">https://medium.com/p/ecc5f0505dff</guid>
            <category><![CDATA[smart-contracts]]></category>
            <category><![CDATA[ethereum]]></category>
            <dc:creator><![CDATA[Dan Robinson]]></dc:creator>
            <pubDate>Fri, 28 Aug 2020 17:38:42 GMT</pubDate>
            <atom:updated>2021-06-17T13:16:55.841Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eh1qpGbtYVilaGqPUVvrOQ.png" /></figure><h3>Ethereum is a Dark Forest</h3><h4>By Dan Robinson and Georgios Konstantopoulos</h4><p><a href="https://www.paradigm.xyz/2020/08/ethereum-is-a-dark-forest/">This story has moved to the Paradigm blog.</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ecc5f0505dff" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Joining Paradigm]]></title>
            <link>https://medium.com/@danrobinson/joining-paradigm-ce3b6167dfa?source=rss-10c4e6618569------2</link>
            <guid isPermaLink="false">https://medium.com/p/ce3b6167dfa</guid>
            <category><![CDATA[bitcoin]]></category>
            <category><![CDATA[cryptocurrency]]></category>
            <category><![CDATA[ethereum]]></category>
            <category><![CDATA[venture-capital]]></category>
            <dc:creator><![CDATA[Dan Robinson]]></dc:creator>
            <pubDate>Wed, 09 Jan 2019 19:58:49 GMT</pubDate>
            <atom:updated>2019-01-09T19:58:49.037Z</atom:updated>
            <content:encoded><![CDATA[<p>‪I’m excited to announce that I’m joining <a href="https://twitter.com/paradigm">Paradigm</a> as a Research Partner, to help <a href="https://medium.com/u/f3b49a429096">Matt Huang</a>, <a href="https://medium.com/u/b947efe0a51a">Fred Ehrsam</a>, and <a href="https://medium.com/u/868d3026194c">Charlie Noyes</a> build a new kind of investment firm.‬</p><p>I’ve always hoped I would get a chance to work alongside Matt, who has been one of my closest friends for almost twenty years, and who first introduced me to Bitcoin six years ago. But I’m equally thrilled to be joining Fred, who has already had a legendary impact on this small industry, and Charlie, one of the sharpest people I’ve ever met.</p><p>‪Another thing that drew me to this opportunity is Paradigm’s long-term perspective, and their commitment to pushing the entire industry forward by investing in basic research. In addition to helping Matt, Fred, and Charlie think about investments, an explicit part of my role will be contributing to research and development on open-source protocols and projects.</p><p>I’m looking forward to continuing to work on Bitcoin, Ethereum, Plasma, Interledger, Ivy, and Stellar, as well as getting to explore other areas more deeply, including decentralized finance, proof-of-stake consensus, and zero-knowledge proofs. If you’re working on something interesting, please reach out to me at <a href="mailto:dan@paradigm.xyz">dan@paradigm.xyz</a>!</p><p>‪I have been blessed to have worked with some extraordinary people at <a href="https://medium.com/u/7b84c87e9045">Chain</a> and <a href="https://medium.com/u/b494e5ddf9ff">Interstellar</a> over the past 2.5 years‪ and am beyond grateful for the opportunities <a href="https://medium.com/u/34456653833b">Adam Ludwin</a> and <a href="https://medium.com/u/5964ed5fbf9e">Jed McCaleb</a> have given me to work on transformative and cutting-edge projects. Adam, and the company he built, changed my life, and taught me countless lessons that I hope to carry forward.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ce3b6167dfa" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Starlight: payment channels on Stellar]]></title>
            <link>https://medium.com/interstellar/starlight-payment-channels-on-stellar-3ff833c0d0ca?source=rss-10c4e6618569------2</link>
            <guid isPermaLink="false">https://medium.com/p/3ff833c0d0ca</guid>
            <category><![CDATA[blockchain]]></category>
            <category><![CDATA[stellar]]></category>
            <category><![CDATA[lightning]]></category>
            <category><![CDATA[payment-channels]]></category>
            <category><![CDATA[crypto]]></category>
            <dc:creator><![CDATA[Dan Robinson]]></dc:creator>
            <pubDate>Thu, 25 Oct 2018 18:29:07 GMT</pubDate>
            <atom:updated>2018-10-25T18:29:07.158Z</atom:updated>
            <content:encoded><![CDATA[<h3>Starlight: Payment channels on Stellar</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/750/1*VWoJX57jrYGn7neBZtWBaQ@2x.png" /></figure><p>Interstellar is pleased to announce a preview release of <a href="https://github.com/interstellar/starlight">Starlight</a>, an implementation of bidirectional payment channels on <a href="https://www.stellar.org/">Stellar</a>. Payment channels allow parties to transact privately, instantly, and securely, while paying zero fees.</p><p>Normally, making a payment on a network like Stellar involves publishing details of the payment to all observers, paying a small fee, and waiting for the network to reach consensus and confirm the payment.</p><p>A payment channel, on the other hand, uses the network to “lock up” some funds for use by the channel’s participants. They may then pay each other these funds without further involving the network. Such payments are thus private, instant, and free.</p><p>The security of the channel is ensured by special information exchanged between the participants with each payment. This information includes signed Stellar transactions that are <em>not</em> published to the network until one party chooses to close the channel. When the channel is closed, these “settlement transactions” send to each party’s Stellar account their respective share of the balance, taking into account the channel’s history of payments back and forth.</p><p>Only the final settlement balances are revealed to the network when the channel closes. All other activity in the channel remains private and known only to its participants.</p><p>Starlight payment channels are analogous to the Bitcoin payment channels used in <a href="https://lightning.network/">the Lightning Network</a>. As we extend the Starlight project to support not only payment channels but also multi-hop payments <em>across</em> those channels, we plan to build in compatibility with other payment-channel networks, such as Lightning and <a href="https://interledger.org/">Interledger</a>.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fround-lake.dustinice.workers.dev%3A443%2Fhttps%2Fplayer.vimeo.com%2Fvideo%2F297145195%3Fapp_id%3D122963&amp;dntp=1&amp;url=https%3A%2F%2Fround-lake.dustinice.workers.dev%3A443%2Fhttps%2Fvimeo.com%2F297145195&amp;image=https%3A%2F%2Fround-lake.dustinice.workers.dev%3A443%2Fhttps%2Fi.vimeocdn.com%2Fvideo%2F734749394_1280.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=vimeo" width="1920" height="1143" frameborder="0" scrolling="no"><a href="https://medium.com/media/ee30d38cf887db4ce5ea0f072ab056f7/href">https://medium.com/media/ee30d38cf887db4ce5ea0f072ab056f7/href</a></iframe><p>This preview release supports bilateral channels (channels with exactly two participants). It includes the Starlight payment channel software as well as a built-in wallet application. It allows transacting in lumens only (the native asset of the Stellar network). Future versions will support any asset issued on the Stellar network.</p><p>This is an early demo release, and you should expect bugs as well as frequent incompatible upgrades. Until we work out the kinks, Starlight connects only to the Stellar testnet, not the mainnet, to eliminate the risk of losing real funds to a software bug. Please do not attempt to use this application with the Stellar mainnet.</p><p>You can download the Starlight application, read the source code, and try the demo <a href="https://github.com/interstellar/starlight">here</a>. You can learn more about the Starlight payment channel protocol by reading the <a href="https://github.com/interstellar/starlight/blob/main/starlight/doc/Protocol.md">specification</a>.</p><p>Thank you to Jeremy Rubin, Jed McCaleb, Nicolas Barry, David Mazières, Akash Khosla, and others for inventing and developing the designs for payment channels on the Stellar protocol.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3ff833c0d0ca" width="1" height="1" alt=""><hr><p><a href="https://medium.com/interstellar/starlight-payment-channels-on-stellar-3ff833c0d0ca">Starlight: payment channels on Stellar</a> was originally published in <a href="https://medium.com/interstellar">Interstellar</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Understanding Simplicity: implementing a smart contract language in 30 lines of Haskell]]></title>
            <link>https://medium.com/@danrobinson/understanding-simplicity-implementing-a-smart-contract-language-in-30-lines-of-haskell-827521bfeb4d?source=rss-10c4e6618569------2</link>
            <guid isPermaLink="false">https://medium.com/p/827521bfeb4d</guid>
            <category><![CDATA[bitcoin]]></category>
            <category><![CDATA[blockchain]]></category>
            <category><![CDATA[smart-contracts]]></category>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[programming-languages]]></category>
            <dc:creator><![CDATA[Dan Robinson]]></dc:creator>
            <pubDate>Wed, 20 Dec 2017 18:22:09 GMT</pubDate>
            <atom:updated>2017-12-20T21:55:05.155Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*p8gYho-0-GB1JGXZdsdfFA.png" /><figcaption>An <a href="https://repl.it/@danrobinson/core-simplicity">online REPL for core Simplicity</a>, using only the code from this post</figcaption></figure><p>Last Monday, Chain <a href="https://blog.chain.com/ivy-for-bitcoin-a-smart-contract-language-that-compiles-to-bitcoin-script-bec06377141a">released</a> our <a href="https://github.com/ivy-lang/ivy-bitcoin">open-source</a> smart contract language for Bitcoin, <strong>Ivy</strong>. Ivy is a higher-level language that can compile to <strong>Bitcoin Script</strong>, the low-level language used by the Bitcoin protocol to determine whether a transaction is authorized. Ivy makes it easier for humans to read, write, and use Bitcoin smart contracts. But since it is designed to be compatible with Bitcoin today, its features are limited by the current capabilities of Bitcoin’s virtual machine.</p><p>What if those limits could be expanded? What if it were possible to get almost all of the safety, simplicity, and efficiency of a small, non-Turing-complete execution language like Bitcoin Script, while gaining much of the flexibility and power of a more expressive programming language?</p><p>For this post, we’re going to take a peek at a distant possible future of the Bitcoin protocol, in the form of an exciting <a href="https://blockstream.com/simplicity.pdf">paper</a> from Russell O’Connor of Blockstream. O’Connor’s paper proposes a possible replacement for Bitcoin Script, called <strong>Simplicity</strong>. Like Bitcoin Script, Simplicity is a low-level execution language, intended to be a compilation target for higher-level languages like Ivy. (To learn more about the possible advantages of Simplicity over Bitcoin Script and alternative low-level languages, you can see <a href="https://blockstream.com/2017/10/30/simplicity.html">Blockstream’s announcement</a>, or <a href="http://wadler.blogspot.com/2017/12/simplicity-and-michelson.html">this review</a> from Philip Wadler.)</p><p>O’Connor’s paper lays out everything you need to implement a Simplicity interpreter, but doesn’t provide an executable reference implementation (although he is working to release an SDK in the near future). And following along with the paper can be a little daunting if, like me, you’re not very familiar with the syntax of Coq or sequent calculus.</p><p>This post attempts to address both these issues, by demonstrating how to implement core Simplicity using Haskell. Our implementation will use only elementary Haskell — specifically, material from chapters 2, 4, 7, and 11 of <a href="http://haskellbook.com/">Haskell Programming from First Principles</a>. If you’ve ever used Haskell or another functional language like Elm, F#, PureScript, or OCaml, you’ll probably be able to follow along.</p><p>You can try out this implementation of Simplicity in your browser, and see the full code, at <a href="https://repl.it/@danrobinson/core-simplicity">https://repl.it/@danrobinson/core-simplicity</a>.</p><p>In future posts, I might take a look at implementing some of the other features of Simplicity, embedding Simplicity in a less hospitable (but more popular) language, and even building part of a compiler from Ivy to Simplicity.</p><h3>Goals</h3><p>We’ll be implementing core Simplicity as a Haskell module. This module exports functions that allows you to write and execute Simplicity expressions as Haskell code, with almost no translation. For example, this Simplicity program from section 2.5 of the paper:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/326/1*rp76lDC8P0qCMAGyPCWG0w.png" /></figure><p>Can be translated into the following Haskell code:</p><pre>not :: Bit -&gt; Bit<br>not = comp (pair iden unit) (match (injr unit) (injl unit))</pre><p>Our implementation will be a <a href="https://alessandrovermeulen.me/2013/07/13/the-difference-between-shallow-and-deep-embedding/">shallow embedding</a>. This means every Simplicity combinator and expression will correspond to a Haskell function, and every Simplicity value will correspond to a Haskell value. This allows us to piggyback on Haskell’s AST, as well as its type inference and type checker. If an expression is a valid Haskell expression, we know it is also a valid Simplicity expression.</p><p>In this post, we’ll only implement the nine basic combinators of core Simplicity (described in section 2 of O’Connor’s paper). We won’t touch the more sophisticated features of Simplicity, such as sub-expression sharing, merklized abstract syntax trees, and jets.</p><h3>Types and values</h3><p>Simplicity has a unit type, 𝟙. (A “unit type” means a type with only one inhabitant.) To represent this type, we will use Haskell’s built-in unit type, () (pronounced “unit”).</p><p>In Simplicity, the sole value of the unit type looks like ⟨⟩. In Haskell, the value has the same name as the type itself, ().</p><p>Simplicity also has sum types, written A + B, where A and B are other Simplicity types. Each inhabitant of this type is a value of either type A or B, along with a tag indicating whether it is from the left or the right type. For sum types, we will use Haskell’s canonical sum type, Either, which is defined as data Either a b = Left a | Right b.</p><p>In Simplicity, the values of this type look like σᴸ(a) (when the contained value is a value of the first type, type A) or σᴿ(b) (when the contained value is a value of the second type, type B). In Haskell, they look like Left a and Right b. For example, the two values that inhabit type Either () () are Left () and Right (). The three inhabitants of type Either (Either () ()) () are Left (Left ()), Left (Right ()), and Right ().</p><p>Finally, Simplicity has product types, written A x B. Each inhabitant of such a type is a pair of values — one of type A, and one of type B. We will use Haskell’s built-in tuple type, (a, b).</p><p>In Simplicity, values of a product type look like ⟨a, b⟩. In Haskell, they look like (a, b). For example, the four inhabitants of type (Either () (), Either () ()) are (Left (), Left ()), (Left (), Right ()), (Right (), Left ()), and (Right (), Right ()).</p><p>Unlike in Haskell, sum and product types cannot be defined recursively. This means that every Simplicity type has a fixed, finite number of possible inhabitants.</p><h3>Numbers and strings</h3><p>You’ll notice that Simplicity does not have any built-in support for common primitive types like booleans, integers, or strings. Instead, the Simplicity paper defines such types as combinations of the types described above.</p><p>For example, the paper defines a “bit” — a type with two inhabitants, zero and one — as the sum type 𝟙 + 𝟙. In Haskell, this corresponds to the type Either () (), and the two values of it are Left () and Right (). Following the convention used in the paper, we will define these values to mean 0 and 1, respectively.</p><p>For our convenience, we can define Bit as a type synonym, along with more descriptive names for its two inhabitants:</p><pre>type Bit = Either () ()</pre><pre>zero :: Bit<br>zero = Left ()</pre><pre>one :: Bit<br>one = Right ()</pre><p>What if we want to represent not just one bit, but a two-bit “word” — something that can represent any number from 0 to 3? We can take a product type of two bits, (Bit, Bit).</p><pre>type Word2 = (Bit, Bit)</pre><p>This type can have 4 possible values: (zero, zero), (zero, one), (one, zero), and (one, one). We can interpret these as the integers 0, 1, 2, and 3, respectively. Alternatively, we could interpret them as bitstrings of length 2.</p><p>The Simplicity paper defines larger word sizes as products of two smaller word size types. A 4-bit word is defined as the product of two 2-bit words, an 8-bit word is defined as the product of two 4-bit words, and so on.</p><pre>type Word4 = (Word2, Word2)<br>type Word8 = (Word4, Word4)</pre><h3>Expressions and combinators</h3><p>A Simplicity “expression” is a <em>function</em> from one Simplicity value to another. This is a little unusual — you’re probably accustomed to expressions that can evaluate to single values. (Simplicity also does not have first-class functions — Simplicity expressions are not themselves Simplicity values.)</p><p>Simplicity expressions look like this:</p><pre>pair iden unit</pre><pre>take (take iden)</pre><pre>comp (pair iden unit) (case (injr unit) (injl unit))</pre><p>Simplicity expressions are composed of <em>combinators</em>. A combinator is a primitive in Simplicity that turns 0 or more expressions into a new expression. There are only nine combinators in core Simplicity.</p><pre>iden :: a -&gt; a<br>iden a = a</pre><p>The iden combinator is not parameterized with any other expressions — iden by itself is a valid Simplicity expression. The expression iden is a function that takes a Simplicity value and returns the same value.</p><pre>unit :: a -&gt; ()<br>unit _ = ()</pre><p>The unit combinator, similarly, does not take any other expressions. unit is a function that ignores its input and returns a single value of type unit, ().</p><pre>comp :: (a -&gt; b) -&gt; (b -&gt; c) -&gt; a -&gt; c<br>comp s t a = t (s a)</pre><p>The comp combinator takes two expressions, s and t. Remember, each of these expressions is itself a function from one Simplicity value to another. When partially applied to s and t, comp returns an new expression that takes some value a, applies the s expression to it, and then applies the t expression to that result.</p><p>Note that the last argument to comp, a, is a Simplicity value. In contrast, all of the previous arguments are Simplicity expressions (i.e., Haskell functions). Because of Haskell’s automatic currying, you can also think of comp as a function that takes two expressions s and t, and returns a new expression (i.e., a new Haskell function from one value to another).</p><pre>                                    [         expression          ]<br>combinator   expression  expression     input value   output value<br>             (* -&gt; *)    (* -&gt; *)    -&gt; *          -&gt; * <br>comp ::      (a -&gt; b) -&gt; (b -&gt; c)    -&gt; a          -&gt; c<br>comp         s           t              a          -&gt; t (s a)</pre><p>This is a useful perspective, and arguably the “correct” one, not only because of the different nature of the arguments but also because of the difference in <em>when</em> these arguments are passed. The expressions s and t are provided at the time the Simplicity program is written (i.e., by the programmer or compiler), and the value a is provided at runtime, when the program is run.</p><pre>injl :: (a -&gt; b) -&gt; a -&gt; Either b c<br>injl t a = Left (t a)</pre><pre>injr :: (a -&gt; c) -&gt; a -&gt; Either b c<br>injr t a = Right (t a)</pre><p>The injl and injr combinators each take one expression, t. When applied to a value, they first apply the expression t, and then inject the result into a sum type by adding a Left or Right tag, respectively.</p><pre>match :: ((a, c) -&gt; d) -&gt; ((b, c) -&gt; d) -&gt; (Either a b, c) -&gt; d<br>match s t (Left a, c) = s (a, c)<br>match s t (Right b, c) = t (b, c)</pre><p>The match combinator (renamed from Simplicity’s case because case is a reserved word in Haskell) takes two expressions, s and t. When applied to a value, which must be a product (ab, c), it pattern-matches on ab, and applies either s or t to the contained value (along with the extra state c) based on whether the tag is a `Left` or `Right`, respectively.</p><pre>pair :: (a -&gt; b) -&gt; (a -&gt; c) -&gt; a -&gt; (b, c)<br>pair s t a = (s a, t a)</pre><p>The pair combinator takes two expressions, s and t. When applied to a value, it creates a pair whose first value is the result of applying s to a, and whose second value is the result of applying t to a.</p><pre>take :: (a -&gt; c) -&gt; (a, b) -&gt; c<br>take f (a, _) = f a</pre><pre>drop :: (b -&gt; c) -&gt; (a, b) -&gt; c<br>drop f (_, b) = f b</pre><p>The take and drop combinators each take one expression, f. When applied to a value — which must be a product (a, b) — they apply the expression f to the first or second value, respectively, and throw the other value away.</p><h3>Example Simplicity programs</h3><p>Now we can use these combinators to define expressions that represent arbitrary functions from inputs to outputs.</p><p>The following examples are taken almost verbatim from the Simplicity paper (just translating the type names and type annotation syntax, and changing case to match).</p><pre>not :: Bit -&gt; Bit<br>not = comp (pair iden unit) (match (injr unit) (injl unit))</pre><p>This function takes one bit (zero or one, i.e., Left () or Right ()) and converts it into the opposite bit.</p><p>How does this work? Suppose we apply this expression to the value Left (). We can use equational reasoning to gradually simplify this expression, one combinator at a time:</p><pre>comp (pair iden unit) (match (injr unit) (injl unit)) (Left ())<br>-- comp s t a = t (s a)<br>match (injr unit) (injl unit) ((pair iden unit) (Left ()))<br>-- pair s t a = (s a, t a)<br>match (injr unit) (injl unit) (iden (Left ()), unit (Left ()))<br>-- iden a = a<br>match (injr unit) (injl unit) (Left (), unit (Left ()))<br>-- match s t (Left a, c) = s (a, c)<br>injr unit ((), unit (Left ()))<br>-- injr s a = Right (s a)<br>Right (unit ((), unit (Left ())))<br>-- unit _ = ()<br>Right ()</pre><p>To try this out, you can use the online REPL at <a href="https://repl.it/@danrobinson/core-simplicity">https://repl.it/@danrobinson/core-simplicity</a>, or download the code from there and try it yourself in ghci:</p><pre>&gt; not zero<br>=&gt; Right ()<br>&gt; not zero == one<br>=&gt; True<br>&gt; not one == zero<br>=&gt; True</pre><p>This next function takes two one-bit numbers, adds them, and returns an overflow bit and a result:</p><pre>halfAdder :: (Bit, Bit) -&gt; (Bit, Bit)<br>halfAdder = match (drop (pair (injl unit) iden)) (drop (pair iden not))</pre><p>You can use this half-adder to build a full-adder, which takes two one-bit numbers and an overflow bit and returns a new overflow bit as a result:</p><pre>fullAdder1 :: ((Bit, Bit), Bit) -&gt; (Bit, Bit)<br>fullAdder1 = comp (pair (take halfAdder) (drop iden))<br>            (comp (pair (take (take iden))<br>            (comp (pair (take (drop iden)) (drop iden))<br>              halfAdder))<br>            (pair (match (drop (take iden)) (injr unit))<br>              (drop (drop iden))))</pre><p>You can try it out too:</p><pre>&gt; fullAdder1 ((one, one), zero)<strong><br></strong>=&gt; (Right (),Left ())<br>&gt; fullAdder1 ((zero, zero), one)<br>=&gt; (Left (),Right ())</pre><p>These last two functions implement adders for 2-bit words and 4-bit words. (The Simplicity paper defines these recursively, but doing so in Haskell would require some type-level magic that’s beyond the scope of this post.)</p><pre>fullAdder2 :: ((Word2, Word2), Bit) -&gt; (Bit, Word2)<br>fullAdder2 = comp (pair (take (pair (take (take iden))<br>                                   (drop (take iden))))<br>            (comp (pair (take (pair (take (drop iden))<br>                                    (drop (drop iden))))<br>                        (drop iden))<br>                   fullAdder1))<br>            (comp (pair (drop (drop iden))<br>                  (comp (pair (take iden)<br>                              (drop (take iden)))<br>                        fullAdder1))<br>            (pair (drop (take iden))<br>                  (pair (drop (drop iden)) (take iden))))</pre><pre>fullAdder4 :: ((Word4, Word4), Bit) -&gt; (Bit, Word4)<br>fullAdder4 = comp (pair (take (pair (take (take iden))<br>                                    (drop (take iden))))<br>            (comp (pair (take (pair (take (drop iden))<br>                                    (drop (drop iden))))<br>                        (drop iden))<br>                    fullAdder2))<br>            (comp (pair (drop (drop iden))<br>                  (comp (pair (take iden)<br>                              (drop (take iden)))<br>                        fullAdder2))<br>            (pair (drop (take iden))<br>                  (pair (drop (drop iden)) (take iden))))</pre><h3>Conclusion</h3><p>Hopefully this post has made it easier to understand and try out core Simplicity. I also hope it demonstrated some of the power and flexibility that Haskell provides when working with domain-specific languages.</p><p>Thanks to Russell O’Connor, Boyma Fahnbulleh, Bob Glickstein, and Keith Rarick for reviewing a draft of this post.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=827521bfeb4d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The cost of supporting the B2X fork: how to lose $100m in ten days]]></title>
            <link>https://medium.com/@danrobinson/the-cost-of-supporting-the-b2x-fork-how-to-lose-100m-in-ten-days-6797f7ef52da?source=rss-10c4e6618569------2</link>
            <guid isPermaLink="false">https://medium.com/p/6797f7ef52da</guid>
            <category><![CDATA[bitcoin]]></category>
            <dc:creator><![CDATA[Dan Robinson]]></dc:creator>
            <pubDate>Mon, 06 Nov 2017 19:59:33 GMT</pubDate>
            <atom:updated>2017-11-09T07:57:33.449Z</atom:updated>
            <content:encoded><![CDATA[<p>Sometime next week, Bitcoin nodes running the <a href="https://github.com/btc1/bitcoin">BTC1</a> client are expected to mine a block that would be invalid under the rules of <a href="https://github.com/bitcoin/bitcoin">Bitcoin Core</a>, thus creating a fork of the Bitcoin blockchain. The names for the fork and non-fork currencies are at least as controversial as the fork itself, so I’ll just call them “B2X” and “B1X”. Over 80% of Bitcoin miners have <a href="https://coin.dance/blocks">signaled their intent</a> to mine the B2X chain, but <a href="https://www.bitfinex.com/order_book/bt2btc">futures markets</a> have indicated that investors expect B1X to retain over 80% of Bitcoin’s value, with B2X retaining less than 20%.</p><p>Would such a divergence between hashrate and price be sustainable? I’m sure that some miners, traders, and exchanges have analyzed this exhaustively, but such analysis doesn’t seem to have filtered out to the broader community beyond the conclusion that “hashrate will ultimately follow price.” This post tries to justify that conclusion, arguing that <strong>supporting a less-valuable fork would likely be unsustainably expensive for miners, even in the short run</strong>. My estimate is that if the price predictions hold, subsidizing the B2X chain rather than calling off the fork could cost miners as much as <strong>$100 million </strong>in the first 10 days.</p><p>We’ll just be looking at the 10 days following the fork — or, more precisely, the period before either chain adjusts its difficulty — with a focus on what would happen if the futures prices and miner signaling both turn out to be approximately accurate, and B2X starts out with 80% of BTC’s mining power but only 20% of its value. My primary goal will be to estimate the short-term opportunity cost miners would be sacrificing if they mine the B2X chain in that scenario.</p><p>I’m not considering the longer-term incentives that miners might have for choosing to sacrifice this much to support the chain. I also do not consider any more sophisticated strategies that a mining cartel might undertake collectively, such as launching a 51% attack—or <a href="http://fc14.ifca.ai/papers/fc14_submission_82.pdf">selfish mining attack</a>—against one or both chains, or dedicating mining power to other coins such as Bitcoin Cash. Such a development is certainly possible, but will have to be covered in a future post. Finally, I’m not making any estimates of miner <em>expenses</em>, which are hard to determine, and are essentially irrelevant to the opportunity cost of mining one chain rather than another.</p><h3>Estimating revenue</h3><p>First, let’s estimate how much an individual miner would earn by mining the B2X chain versus the B1X chain until the first difficulty adjustment.</p><p>We can estimate a given miner’s revenue over a period of time using the following formula:</p><p><strong>Rate of block generation ⋅ Time ⋅ (Block reward+ Fees) ⋅ Price</strong></p><p>Let’s examine each of these components in turn.</p><h4>Rate of block generation</h4><p>The first component in the formula is the rate at which a given miner generates blocks on the chain on which they are mining.</p><p>This depends on two factors, the <strong>difficulty</strong>—a measure of how hard it is to generate a new block—and the miner’s own hashrate. Difficulty is ultimately based on total mining power of the network—as the total hashrate dedicated to mining Bitcoin grows or shrinks, the protocol adjusts the difficulty (or more precisely, the <a href="https://en.bitcoin.it/wiki/Target">target</a> that miners must hit) to keep the rate of new block creation close to once every 10 minutes. But difficulty is only adjusted every 2016 blocks (every two weeks, when blocks are being created at their normal rate).</p><p>It turns out that before the difficulty adjusts, the rate at which a particular miner generates blocks is <em>independent </em>of the actions of other miners. This is because the rate at which you generate blocks is a function of only two things: the block difficulty, and your own hashes per second. If other miners abandon the chain you are mining, then the rate at which the whole chain generates new blocks will slow down, but <em>your </em>rate of generating new blocks will not change until the difficulty adjusts.</p><p>This means that a miner who is earning 1 BTC per hour pre-fork in block rewards would, immediately after the fork, have the choice between earning 1 B1X per hour and 1 B2X per hour, <em>no matter what other miners are doing</em>.</p><p>(One caveat is that a slower blockchain may have a slightly lower orphan block rate, but orphan blocks are sufficiently rare under ordinary circumstances that this will probably not be material.)</p><p>So, an individual miner’s rate of block generation does not depend on which fork they mine or how many other miners are mining that chain (until the difficulty adjustment). However, each <em>chain</em> will generate blocks slower or faster, based on the total hashrate committed to that block. With 80% hashrate, the B2X chain would, on average, mine <strong>one block every 12.5 minutes</strong>. With 20% hashrate, the B1X chain would, on average, mine <strong>one block every 50 minutes</strong>.</p><h4>Time</h4><p>How long will it take until the difficulty adjustment?</p><p>The fork is scheduled to occur at block 494,784. For both the B1X and B2X chains, difficulty is scheduled to adjust 1152 blocks later, at block 495,936. With mining power split between two chains, it will likely take significantly longer than normal, particularly for the chain with minority hashrate.</p><p>The amount of time before the first difficulty adjustment will probably be somewhere between 8 days (if all miners join one chain, which therefore generates blocks every 10 minutes) and 16 days (if mining power is evenly split between the two chains, which therefore generate blocks every 20 minutes). It could conceivably be longer, if some BTC miners stop mining altogether after the fork, or temporarily defect to another coin such as Bitcoin Cash.</p><p>If about 80% of pre-fork BTC miners start mining B2X after the fork, the B2X fork will be about 4 times faster, and will therefore adjust its difficulty much sooner. At a rate of one block every 50 minutes, the difficulty adjustment for B1X would happen only <strong>40 days</strong> after the fork. At a rate of one block every 12.5 minutes, the difficulty adjustment for B2X would happen approximately <strong>10 days</strong> after the fork, so let’s consider that to be our cutoff.</p><h4>Block reward</h4><p>One component of coins earned per block is the block reward, which amounts to <strong>12.5 coins per block</strong>. This will be the same for both chains — the B1X chain will give miners 12.5 B1X per block, and the B2X chain will give miners 12.5 B2X per block.</p><h4>Fees</h4><p>The other component of coins earned per block is transaction fees. Total transaction fees per block have mostly ranged between 1 and 4 BTC <a href="https://blockchain.info/charts/transaction-fees?timespan=180days">over the past six months</a>, averaging around 2 BTC per block. Transaction fees are difficult to estimate, but since they are the less significant component of miner income, it’s not essential that we get this exactly right.</p><p>Transaction fee revenue depends, of course, on the demand for transacting on each chain. There may be more desire to transact on the faster, more secure chain (although, since B1X and B2X will be different assets, its not clear that transactions on the two chains will be treated as substitutes), and some businesses will likely follow through on their stated intention to favor the B2X chain.</p><p>On the other hand, slower blocks will mean more transactions per block, and thus higher transaction fees per block. If the B1X network only mines a block every 50 minutes but the B2X network mines a block every 12.5 minutes, then, all other things equal—and in the absence of a block size limit—transaction fees per block would be about 4 times higher for the B1X chain than for the B2X chain.</p><p>Of course, the block size is not unlimited, and it’s likely that if B1X blocks are mined only every 50 minutes, most blocks would be full, which complicates the analysis. Complicating it further is the fact that the situation is not symmetrical between B1X and B2X, because B2X increases the block size by a factor of 2. But the effect of block size on total transaction fees per block is <a href="https://bitcoinmagazine.com/articles/are-bitcoin-miners-making-more-money-small-blocks/">unclear</a>, since smaller blocks tend to have higher fees per transaction. After the effective block size increase imposed by SegWit activation in late August, transaction fees per block actually went <em>down (</em>although there were likely some confounding factors)<em>.</em></p><p>Given all these counteracting factors, predicting transaction fee revenue per chain precisely is a difficult task. If B1X is significantly slower, I would predict that the latter effect would dominate and transaction fees per block on B1X would be higher, but let’s be generous and assume that transaction fees are approximately equal, and that the existing transaction fees per block for BTC are evenly split between B1X and B2X. (Additionally, if we avoid making too much use of assumptions about the total mining power on each chain—which, recall, did not affect the rate at which each miner generate blocks—our analysis will be more generally applicable to other scenarios.)</p><p>So let’s imagine that transaction fees are the same for each chain: around <strong>1 coin per block</strong>.</p><h4>Price</h4><p>By the assumption we made in the introduction, B1X maintains 80% of BTC’s current price, and B2X maintains 20%. (This is actually more conservative than the futures markets, which have tended to put B1X’s share at closer to 85%.) So based on today’s price of $7200, the price of B1X would be about <strong>$5760</strong>, and the price of B2X would be about <strong>$1440</strong>.</p><p>Some might question whether it’s plausible for B1X to maintain its price for 10 days even if it has only 20% of mining power. The futures markets certainly seem to indicate an expectation that it will. Rather than go into an exhaustive analysis of this question, which is somewhat outside the scope of this post, I’ll just note that there doesn’t seem to be any direct mechanism by which a temporary drop in hashrate would drive an immediate drop in price, whereas a temporary drop in price has a clear effect on miners’ immediate incentives.</p><h3>Estimating opportunity cost</h3><p>Let’s now try to estimate the opportunity cost of mining the B2X chain rather than the B1X chain, assuming our assumptions about mining power and price hold.</p><p>Our main conclusion above is that for the first ten days, a miner will earn approximately the same number of coins whether they choose to mine B1X or B2X, <em>regardless</em> of how many other miners choose to mine each coin. This is very convenient for our analysis.</p><p>First, let’s examine the opportunity cost for an individual, “marginal” miner, who needs to decide which chain to mine, but is too small to have an impact on the speed of the chain. The calculation is simple—since the B1X coin is worth four times as much, the miner’s revenue will be four times higher if they mine B1X as if they mine B2X.</p><p>To put it in concrete terms, let’s imagine a miner who currently mines $1,000 of BTC a day. In the 10 days following the fork, thry will have to choose between mining a total of $8,000 worth of B1X, or $2,000 worth of B2X.</p><p>It seems clear that if the above assumptions hold, then until the difficulty adjustment, it will probably be individually rational to mine the chain of the most valuable coin, regardless of what other miners do. Note that this is true even if a miner disagrees with the market on the future value of the currencies— if a miner would rather hold B2X, they could earn it four times faster by mining B1X and trading it for B2X.</p><p>Does it change our analysis if we consider the short-term interests of the entire 80% of miners currently signaling support for mining B2X, as a group? After all, there is evidence that miners sometimes act more like a cartel than like a collection of individual independent actors. What is the opportunity cost for those miners, compared to abandoning B2X and continuing to mine the B1X chain?</p><p>It turns out that considering this entire group as a single actor only strengthens the conclusion that abandoning the less-valuable chain would be the rational move.</p><p>If these 80% of miners choose to mine B2X, then in the ten days following the fork, they will mine a total of 1152 blocks. If, as we estimated above, each of these blocks pays 12.5 B2X in block rewards and 1 B2X in transaction fees, for a total of 13.5 B2X, then their total revenue over those 10 days would be 15,552 B2X. If the price of B2X is $1440, that’s a total of <strong>$22 million</strong>.</p><p>In contrast, if they choose to mine B1X, those miners would still mine a total of 1152 blocks in 10 days, but would be paid in B1X. Even under the above assumptions about transaction fees and prices for B1X, they would expect to earn 15,552 B1X for a total of <strong>$89 million</strong>—making <strong>$67 million </strong>more by mining B1X rather than B2X.</p><p>But in fact, since this would effectively be equivalent to abandoning the B2X fork, the most likely outcome might be that B1X would maintain the price and transaction quantity of BTC (although, since the recent run-up in price may have anticipated some fork, it’s possible that the price would pull back a little). If those 80% of miners call off the fork, but the BTC price remains stable, and total transaction fees per block remain around 2 BTC per block, then their expected revenue would be 14.5 * $7200 * 1152 = <strong>$120 million</strong>, making the opportunity cost around <strong>$98 million </strong>for those 10 days.</p><h3>Conclusion</h3><p>Supporting an unpopular fork by mining it instead of a more valuable chain turns out to be extraordinarily expensive at Bitcoin’s current price. This situation is likely to be unsustainable—individual miners would have a strong incentive to defect, and cartels would need to sacrifice considerable returns to maintain a higher hashrate.</p><p>Of course, a cartel might be willing to sacrifice substantial short-term gains now if it guaranteed higher revenues in the future. In a follow-up post, I’ll examine what would happen after the B2X difficulty adjustment 10 days after the fork—which would likely make mining B2X slightly less unprofitable — and the B1X difficulty adjustment 30 days after that—which would likely make mining B1X <em>dramatically </em>more profitable. I may also take a closer look at other strategies that powerful miners might consider, such as 51% attacks or selfish mining attacks. [<strong>UPDATE, November 8</strong>: Turns out the follow-up post would be moot, because the 2x fork <a href="https://lists.linuxfoundation.org/pipermail/bitcoin-segwit2x/2017-November/000685.html">has been abandoned by its primary supporters</a>.]</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6797f7ef52da" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>