<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Will Cosgrove</title><description>Writing on software, Ruby, and Bitcoin.</description><link>https://blog.willcosgrove.com</link><item><title>Changes</title><link>https://blog.willcosgrove.com/changes</link><guid isPermaLink="true">https://blog.willcosgrove.com/changes</guid><description>The times, they are</description><pubDate>Mon, 05 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I noticed my blog stopped working for some reason. I’m sure you noticed before me because of how diligently you check it for updates. So I had Claude scrape my old posts and import them into some new static site generator. I didn’t really care what it was. I would have used to care, because I would have wanted full creative control and understanding over what was going on. But now I know I can change any aspect of anything, just by prompting.&lt;/p&gt;
&lt;p&gt;I looked at my most recent post, it was about &lt;a href=&quot;https://blog.willcosgrove.com/a-tale-of-two-phlexes&quot;&gt;designing pleasing APIs for building UI components&lt;/a&gt;. I laughed. I haven’t written a UI component in almost 9 months now.&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;It’s been strange to have a machine start doing what I do, and doing it so efficiently that &lt;em&gt;not&lt;/em&gt; giving up control to it would be a form of negligence.&lt;/p&gt;
&lt;p&gt;I know my experience is not unique. An entire industry worth of people are experiencing the same things I’m experiencing. It’s frightening and exciting. It’s empowering and deflating. In a way I’m almost no longer constrained by time because of how fast the machines are. And at the same time I’m uncertain of how much longer I will have any economic utility at all.&lt;/p&gt;
&lt;p&gt;For now at least, I’m in possession of a language that isn’t known to the general population. A language of describing exactly how a software system should work.&lt;/p&gt;
&lt;p&gt;There exist AIs to create any image you can describe, and AIs to create any song you can describe. But both still require a human who knows the language of art and music to describe something beautiful. I love music but I’m not a musician. I can’t describe what I want in a song. I just know it when I hear it.&lt;/p&gt;
&lt;p&gt;Anyone can describe an app idea and get something back from an AI. But, for now at least, my own tastes and experiences and sensibilities that I’ve developed over the last 15 years still work as a competitive edge when describing to a machine what I want built.&lt;/p&gt;
&lt;p&gt;But it seems inevitable that any taste, experience, and sensibility will eventually be fully distilled into the models, and they will be able to take a generic description of a problem and produce something great. When that does happen, I don’t know what’s left for me to bring to the table.&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;I am excited about the future, though I don’t know my place in it. Claude’s been teaching me how to take care of our pool. So maybe I can pivot to that. It should be stable until the robot bodies are done.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This blog post, with all its grammatical imperfections, was written by a human with &lt;strong&gt;no&lt;/strong&gt; AI pass.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title>A Tale of two Phlexes</title><link>https://blog.willcosgrove.com/a-tale-of-two-phlexes</link><guid isPermaLink="true">https://blog.willcosgrove.com/a-tale-of-two-phlexes</guid><pubDate>Wed, 24 Jan 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;There are two types of components you can write in Phlex. The standard component exposes a “builder” style API. The second type is a component that uses &lt;code&gt;DeferredRender&lt;/code&gt;, which fully consumes the render block before its own template is rendered.&lt;/p&gt;
&lt;p&gt;Let’s take a look at both types by building two different Table components.&lt;/p&gt;
&lt;p&gt;The first component will use a builder style API.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rb&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt; Table&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; &amp;lt; &lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;Phlex::HTML&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  def&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt; template&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    table &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;      yield&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  def&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt; head&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    thead &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;      tr &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;        yield&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;      end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  def&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt; column_heading&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    th { &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;yield&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  def&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt; body&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    tbody { &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;yield&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  def&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt; row&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    tr { &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;yield&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  def&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt; cell&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    td { &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;yield&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we can imagine how we might use it:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rb&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;render &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;Table&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt; do&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; |t|&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;  t.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    t.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;column_heading&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    t.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;column_heading&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;Age&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;  t.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    t.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;row&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;      t.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;cell&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;Alice&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;      t.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;cell&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;28&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    t.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;row&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;      t.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;cell&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;Bob&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;      t.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;cell&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;32&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this simplistic example of a table, it may seem like the component isn’t doing a lot for us. But imagine if the component was applying predefined classes to each row, and cell, and column heading. It could considerably clean up our invocations of the table by abstracting away the specific DOM details of the table. It does not abstract away the structure of the table however.&lt;/p&gt;
&lt;p&gt;Now lets take a look at a component that uses &lt;code&gt;DeferredRender&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rb&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt; Table&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; &amp;lt; &lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;Phlex::HTML&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  include&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt; Phlex&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;DeferredRender&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  def&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt; initialize&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;rows:&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    @data &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; rows&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    @columns &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  def&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt; template&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    table &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;      thead &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;        tr &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;          @columns.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;each&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt; do&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; |column|&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;            th { column[&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;:heading&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;] }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;          end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;        end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;      end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;      tbody &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;        @data.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;each&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt; do&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; |row|&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;          tr &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;            @columns.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;each&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt; do&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; |column|&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;              td { column[&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;:content&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;][row] }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;            end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;          end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;        end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;      end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  def&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt; column&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(heading, &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;block)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    @columns &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;heading:&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; heading, &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;content:&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; block }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We would use this component differently:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rb&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;render &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;Table&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;rows:&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; users) &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;do&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; |t|&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;  t.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;column&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;) { |user| user.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;  t.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;column&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;Age&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;) { |user| user.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;age&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This component not only abstracts away the details of the DOM, but also the structure of the final table. With this component, the renderer of the Table has no say in how the final markup is put together, just the content.&lt;/p&gt;
&lt;p&gt;Both of these styles have their utility. The builder style component retains the most flexibility for the renderer at the cost of some verbosity. The &lt;code&gt;DeferredRender&lt;/code&gt; style component is able to provide a terser API but can’t offer as much in the way of flexibility.&lt;/p&gt;
&lt;p&gt;I have found a pattern where I will actually have both types of components for the same “thing”. An example from my own application is that I have a &lt;code&gt;Table&lt;/code&gt; component that uses the builder style API, and I have a &lt;code&gt;DataTable&lt;/code&gt; component that uses &lt;code&gt;DeferredRender&lt;/code&gt;. &lt;code&gt;DataTable&lt;/code&gt; uses &lt;code&gt;Table&lt;/code&gt; internally. For most usecases I can use &lt;code&gt;DataTable&lt;/code&gt; to render out my tabular data, but if I need a table that is more complex, maybe it needs to have sortable columns, or selectable rows, I can fall back to &lt;code&gt;Table&lt;/code&gt; and maintain the styling of the table.&lt;/p&gt;
&lt;p&gt;I think of the two styles existing on a spectrum between imperative and declarative. The builder style API is more imperative, and the &lt;code&gt;DeferredRender&lt;/code&gt; style is more declarative.&lt;/p&gt;
&lt;p&gt;To answer the question of “Why isn’t the &lt;code&gt;DeferredRender&lt;/code&gt; style the default?”, I think it’s because the builder style is more intuitive, and makes your components work the way normal HTML elements work inside of Phlex.&lt;/p&gt;
&lt;p&gt;In the block of a &lt;code&gt;DeferredRender&lt;/code&gt; component’s render call, all you have available to you is the component’s own API. Any additional markup or content you try to add outside of it’s API will be ignored.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rb&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;render &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;Table&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;rows:&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; users) &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;do&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; |t|&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;  t.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;column&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;) { |user| user.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;  t.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;column&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;Age&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;) { |user| user.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;age&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;  h1 { &lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;This will not be rendered&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;when-to-use-one-over-the-other&quot;&gt;When to use one over the other&lt;/h2&gt;
&lt;p&gt;As a general rule of thumb, I try to use a builder style API as much as I can, because it affords me the most flexibility with the component as I continue using it. I very often don’t know all the different ways I will want to use my component when I am first creating it.&lt;/p&gt;
&lt;p&gt;When I am using a builder style component in many places and all the invocations are all very similar, I will try extracting out a more declarative terser component that will usually need to use &lt;code&gt;DeferredRender&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A case where &lt;code&gt;DeferredRender&lt;/code&gt; is my first choice is when I’m building a component that needs to repeat the provided “structure” the renderer will give us. Take this &lt;code&gt;PageHeader&lt;/code&gt; component for example.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;TailwindUI’s Page Header&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1367&quot; height=&quot;512&quot; src=&quot;https://blog.willcosgrove.com/_astro/image-1.B9AwZTn5_Z2i1K4z.webp&quot;&gt;&lt;/p&gt;
&lt;p&gt;It has a set of actions that are rendered as buttons when the screen is large enough. But as the viewport shrinks the actions get tucked into a dropdown menu. The final markup will need to include these actions multiple times: once as buttons, and again as menu items within the dropdown.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;dropdown.png&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;790&quot; height=&quot;888&quot; src=&quot;https://blog.willcosgrove.com/_astro/image-2.BaIoXUgq_ZO58hV.webp&quot;&gt;&lt;/p&gt;
&lt;p&gt;Using a &lt;code&gt;DeferredRender&lt;/code&gt; component, we can abstract away the details of the DOM, and the structure of the final markup, and only take concern with the content.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rb&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt; PageHeader&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  include&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt; Phlex&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;DeferredRender&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  def&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt; initialize&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    @actions &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  def&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt; template&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    div &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D;--shiki-dark:#6A737D&quot;&gt;      # ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;      div&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;class:&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt; &quot;action-buttons hidden lg:block&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;        @actions.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;each&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt; do&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; |action|&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;          render &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;Button&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;action[&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;:attributes&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;]) &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;            render action[&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;:content&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;          end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;        end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;      end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;      div&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;class:&lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt; &quot;dropdown-menu lg:hidden&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;        @actions.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;each&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt; do&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; |action|&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;          a&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;action[&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;:attributes&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;]) { render action[&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;:content&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;] }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;        end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;      end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;    end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  def&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt; action&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;**&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;attributes, &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;content)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;    @actions &lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;attributes:&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; attributes, &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;content:&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; content }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;  end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then (ignoring the other parts of the page header for simplicity here), we can use that page header component like this:&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;rb&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;render &lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;PageHeader&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt; do&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; |h|&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;  h.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;action&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;href:&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt; edit_listing_path&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(@listing)) { &lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;Edit&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;  h.&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt;action&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#005CC5;--shiki-dark:#79B8FF&quot;&gt;href:&lt;/span&gt;&lt;span style=&quot;color:#6F42C1;--shiki-dark:#B392F0&quot;&gt; listing_path&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt;(@listing)) { &lt;/span&gt;&lt;span style=&quot;color:#032F62;--shiki-dark:#9ECBFF&quot;&gt;&quot;View&quot;&lt;/span&gt;&lt;span style=&quot;color:#24292E;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#D73A49;--shiki-dark:#F97583&quot;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>On Scarcity and Value</title><link>https://blog.willcosgrove.com/on-scarcity-and-value</link><guid isPermaLink="true">https://blog.willcosgrove.com/on-scarcity-and-value</guid><pubDate>Mon, 30 Jan 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img alt=&quot;DALL·E 2023-01-30 11.50.46 - an empty beer bottle with a sticker on it that says _free_ sitting next to a bitcoin.png&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1024&quot; height=&quot;1024&quot; src=&quot;https://blog.willcosgrove.com/_astro/image-1.E3x2Ed7h_ZPVQKu.webp&quot;&gt;&lt;/p&gt;
&lt;p&gt;I had dinner with some friends recently and the topic of Bitcoin came up, as it does when I’m a part of these sorts of things. Someone asked me why I thought bitcoin was valuable. I said, because it is scarce. We were on round three of our drinks at this point in the evening so I tried to keep my answer brief. Another friend then set his empty beer bottle down on the table and proclaimed: “This bottle is one of a kind. Why isn’t it valuable?” I fumbled an answer that was trying to make the point that I had another one in my fridge that I could drink that would be indistinguishable from his, casting shadows on his “one of a kind” claim. It wasn’t the clearest question, but I also didn’t give a great answer in return.&lt;/p&gt;
&lt;p&gt;If I could distill his question down to something a bit more straightforward, I would state it as: Why does scarcity make something valuable? There are plenty of things that are scarce that have no value.&lt;/p&gt;
&lt;p&gt;And he’s right, scarcity does not impute value. My son Graham has produced many one of a kind pieces of art at his school, but I haven’t been able to get anything for them at auction. The limited supply of them has not translated into value.&lt;/p&gt;
&lt;p&gt;Why does scarcity have anything to do with Bitcoin’s value proposition? It is one dimension used to measure the properties of a good money. It’s been the one dimension that current money, fiat, most lacks. Bitcoin also has the other dimensions but I would argue it’s less notable since it’s not novel in a money. Graham’s artwork scores poorly on the other dimensions of money, which I think is primarily why they’re not being fought over at Sotheby’s.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;In addition to scarcity, the other dimensions of a good money are: portability, verifiability, divisibility, durability, and fungibility&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. Fiat scores well on all of these attributes, which is why it has supplanted the previous money, Gold. Gold scored highly on scarcity, durability, fungibility, but it is not very portable, it takes great effort to verify it, and it is difficult to use in small quantities, so it is not very divisible.&lt;/p&gt;
&lt;h2 id=&quot;portability&quot;&gt;Portability&lt;/h2&gt;
&lt;p&gt;Bitcoin is the most portable money that has ever existed. I can send it across the world over the internet. I can broadcast it on a short wave radio. I can put it on hardware device and hand it over in person. If you’re fleeing a collapsing country, you could much more easily make that move with your bitcoin than you could with cash or gold. You can store bitcoin in your head, if need be, by memorizing 12 words. It’s difficult to imagine something more portable than that.&lt;/p&gt;
&lt;h2 id=&quot;verifiability&quot;&gt;Verifiability&lt;/h2&gt;
&lt;p&gt;Bitcoin is extremely easy to verify. A computer running bitcoin software can verify a transaction instantaneously. If you do not have your own trusted bitcoin setup running, you can rely on freely available 3rd party services that can verify bitcoin transactions. All you need is a communication line to verify a bitcoin transaction.&lt;/p&gt;
&lt;h2 id=&quot;divisibility&quot;&gt;Divisibility&lt;/h2&gt;
&lt;p&gt;Bitcoin is highly divisible. At present 1 bitcoin is divisible into 100 million fractional units. If this was determined not to be enough, it would be a very straightforward change to allow further subdivision. Changes to bitcoin require buy off of the whole network (via willfully updating the software that is being run). But a change of this nature would be likely to be uncontroversial.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;People sometimes confuse divisibility and scarcity as being competing ends. People will say, if something is infinitely divisible, how can it be scarce? This can be unpacked many ways, but maybe the easiest is to ask that person why you can’t feed the world with a single pizza since we can continue dividing the pizza into smaller and smaller slices until there are enough slices for everyone in the world. Cutting something in half is not the same as having two of something. A change to bitcoin’s decimal place would result in everyone’s “number” growing. As opposed to the Fed creating a trillion dollars out of thin air, where that trillion dollars is then given (in part or in whole) to some entity. Your personal number of dollars didn’t change.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;durability&quot;&gt;Durability&lt;/h2&gt;
&lt;p&gt;Bitcoin has an advantage in the durability category over physical forms of money. Digital things have a very high degree of durability because they can be copied and backed up. The same is true of Bitcoin. You can miraculously copy and back up your bitcoin without being able to double spend it. This is one of the main technical breakthrough achieved by bitcoin, through it’s blockchain data structure.&lt;/p&gt;
&lt;p&gt;However Bitcoin durability is not a given. You must take the effort to store it responsibly or it could be lost. In the same way that it would be unwise to store large quantities of paper money in a location where it could catch fire, it’s unwise to store bitcoin on internet connected devices that are prone to attacks. Any sufficiently large bitcoin stack should be secured on an offline hardware wallet, with multiple backups to prevent a single point of failure. Bitcoin can be extremely durable, but it does require some effort.&lt;/p&gt;
&lt;h2 id=&quot;scarcity&quot;&gt;Scarcity&lt;/h2&gt;
&lt;p&gt;In scarcity, bitcoin will score the highest. It is currently slightly less scarce than Gold, and at the 2024 halving it will be almost twice as scarce as Gold. It will continue gaining scarcity exponentially until its stock to flow ratio hits infinity. There has never been a resource with a predictable finiteness like Bitcoin. Time&lt;sup&gt;&lt;a href=&quot;#user-content-fn-2&quot; id=&quot;user-content-fnref-2&quot; data-footnote-ref aria-describedby=&quot;footnote-label&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; is the only other thing that comes close in terms of finiteness, but the time resource is unpredictable at the individual level.&lt;/p&gt;
&lt;p&gt;Scarcity is important because it measures the lossiness of value over time. Scarcity could also be thought of as “portability” but for time instead of space. I read a news article about someone who found in their attic a lockbox that was dated to the 1910s. Inside there was $15,000 USD, which would have been equivalent to, at the time it was stored, the entire economic output of someone’s life. Now, you probably couldn’t buy a new car with it. The ability to store your economic energy for later is valuable for protecting yourself and your family from future uncertainty, or for providing a better life for your future generations. But you cannot do this in a money which has an inflating supply. This is why modern conventional wisdom for saving is to put your money into investments. It is not enough to store it, because it will lose purchasing power over time.&lt;/p&gt;
&lt;p&gt;The last point I will make about scarcity is that sometimes people will confuse bitcoin for cryptocurrencies in general and make the claim that because cryptocurrencies in whole are not scarce, bitcoin is not scarce. But this is comparing apples to oranges. Gold is scarce, and aluminum is abundant. My claim of Gold being scarce is not undercut by someone pointing out that metals are abundant. Gold is a metal but not all metals are Gold.&lt;/p&gt;
&lt;h2 id=&quot;fungibility&quot;&gt;Fungibility&lt;/h2&gt;
&lt;p&gt;I left fungibility last because it is the dimension that bitcoin scores the worst on. Fungibility means that one unit of a thing is equal to another one unit of the thing. One gram of Gold is equal in value to people as another gram of Gold. The same is not true of a diamond. A one carat diamond is not necessarily equal in value to another one carat diamond. There are other factors such as color, and clarity that come into play when determining value.&lt;/p&gt;
&lt;p&gt;Fungibility is up to the market. As far as bitcoin the software/protocol is concerned, bitcoin is perfectly fungible. But it would not be hard to imagine that if a bitcoin transaction occurred that was known to be paid to a terrorist organization, that exchanges might refuse to accept that transaction. Either by rule of government regulation or personal ethical reasons by the leaders of that exchange.&lt;/p&gt;
&lt;p&gt;Because the transaction history of every bitcoin is fully known and auditable, bitcoin that is associated with known illicit activity could become tainted in the eyes of the market and not be worth as much as an untainted bitcoin. The main way to improve this is to improve the privacy of the network. Another way to improve this is by scaling transactions to a different layer. Lightning is a layer-2 network that runs on top of the bitcoin protocol. Unlike the base layer, lightning functions without needing to keep a public ledger of transaction history. People are not able to audit the source of the money coming into them over lightning. They are able to verify that the transaction is valid, but not its intermediate lightning transactions that it has been a part of. This protects institutions like exchanges from being on the hook for censoring transactions. Exchanges are already adding support for deposits and withdrawals over lightning. In part for the added privacy layer, and in part because transactions are cheaper on Lightning.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Scarcity alone does not make a thing valuable, but it is one component that makes something a good money. It is also the main component we are currently lacking in with our current money system. Society will eventually converge on the best money, and I believe bitcoin is the best money.&lt;/p&gt;
&lt;section data-footnotes class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;For more on the properties of money and how this applies to Bitcoin, see &lt;a href=&quot;https://vijayboyapati.medium.com/the-bullish-case-for-bitcoin-6ecc8bdecc1&quot;&gt;The Bullish Case for Bitcoin&lt;/a&gt; by Vijay Boyapati &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-2&quot;&gt;
&lt;p&gt;For more on this idea, see &lt;a href=&quot;https://dergigi.com/2021/01/14/bitcoin-is-time/&quot;&gt;Bitcoin is Time&lt;/a&gt; by Gigi &lt;a href=&quot;#user-content-fnref-2&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 2&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content:encoded></item><item><title>Misconceptions About Bitcoin Exchanges</title><link>https://blog.willcosgrove.com/misconceptions-about-bitcoin-exchanges</link><guid isPermaLink="true">https://blog.willcosgrove.com/misconceptions-about-bitcoin-exchanges</guid><pubDate>Thu, 28 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;There is a common misconception I hear when talking to people who are newer to bitcoin. It concerns exchanges and how they fit into Bitcoin. People hear about the blockchain, and how transactions go on it; they assume that when they log on to their exchange of choice and make a purchase of some bitcoin, that a transaction has been added to the blockchain ledger.&lt;/p&gt;
&lt;p&gt;This isn’t an unreasonable assumption. But in reality, exchanges have nothing to do with Bitcoin, the network, or the protocol. They are their own entity, operating however they please. That isn’t to say that an exchange &lt;em&gt;couldn’t&lt;/em&gt; operate in a way so that every trade that happened on their platform had some corresponding entry in the blockchain. But it would be slow and costly to do so.&lt;/p&gt;
&lt;p&gt;When you buy bitcoin on an exchange, what is happening? I’m going to generalize; some exchanges may work differently than this. But on the whole, this is what’s going on: Before you decided to buy, someone else decided to sell. Before they could sell their bitcoin on the exchange, they had to give their bitcoin to the exchange. The exchange requires that the seller have bitcoin in their account on the exchange, in order to place the sell order. So the seller would have told the exchange that they want to deposit some bitcoin into their account, and the exchange would provide them with an address to send the bitcoin to. When the exchange verifies on the blockchain that the funds have been sent to the address that they provided, they add the amount received to your account balance. The seller now no longer has control of that bitcoin, as far as the bitcoin network is concerned. The owner of the bitcoin is now the exchange. Now that the bitcoin is with the exchange, the seller can put in a sell order up to the amount that they deposited.&lt;/p&gt;
&lt;p&gt;Now you come along looking to buy. Depending on the exchange, you may be required to deposit USD (or whatever currency you’re buying with) before you can put in a buy. Other more customer-friendly exchanges will offer to let you buy the bitcoin instantly and will begin the process of moving your money over from your debit card or bank account when you make the purchase. In either case, after the trade happens, what the exchange is doing internally is just as simple as subtracting some numerical amount from the seller’s account, and adding some numerical amount to your account. But no bitcoin moved as far as the bitcoin network is concerned. No activity has occurred on the blockchain. Because both before the trade, and after the trade, the entity holding the bitcoin remains the same: the exchange.&lt;/p&gt;
&lt;p&gt;The only time &lt;em&gt;you&lt;/em&gt; have bitcoin, is when you request to withdraw the bitcoin off of your account with the exchange. At that point, you’ll give the exchange &lt;em&gt;your&lt;/em&gt; address, and they will send bitcoin to you and subtract the numerical amount out of your account balance with them. Once that transaction broadcasts out and then gets confirmed in a block, &lt;em&gt;then&lt;/em&gt; you have bitcoin.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;So what do you get when you buy bitcoin on an exchange? Paper bitcoin. An IOU from the exchange. Not the real thing. If anything happens to that exchange (assets seized, bankruptcy, the owner dies suddenly&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;) there isn’t much anyone can do to make you whole again. This kind of problem gave rise to a saying in the bitcoin community:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“Not your keys, not your bitcoin”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I don’t think it’s inherently bad that exchanges work this way, it’s the simplest way for them to work. But it can become a problem if the exchanges get greedy.&lt;/p&gt;
&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Unpopular Opinion: The supply of &lt;a href=&quot;https://twitter.com/hashtag/Bitcoin?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#Bitcoin&lt;/a&gt; is higher than 21 million. Exchanges leverage the existing supply of any &lt;a href=&quot;https://twitter.com/hashtag/crypto?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#crypto&lt;/a&gt; asset in much the same way banks leverage the supply of fiat money. The only protection is to hold your own crypto. Not your keys, not your crypto.&lt;/p&gt;— Weiss Crypto Ratings (@WeissCrypto) &lt;a href=&quot;https://twitter.com/WeissCrypto/status/1264860045386407942?ref_src=twsrc%5Etfw&quot;&gt;May 25, 2020&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;What WeissCrypto is insinuating here that exchanges are not holding 100% of their reserves. So if all of their customers tried to withdraw all of their funds at once, the exchange would not be able to fulfill all the requests. In order to force exchanges to be honest, it would be best for the bitcoin economy if more people did not leave bitcoin on exchanges.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;When I first got into bitcoin, I didn’t understand why you would withdraw bitcoin from an exchange. It seemed riskier to me than leaving it on the exchange. I figured that the people at the exchange were experts at storing and protecting crypto assets, and I was not. So I thought if I was managing my own bitcoin, the odds of me losing it was higher than if I left it on the exchange. But as I began to look into what would be required to self-custody bitcoin, I realized it wasn’t as difficult as I had imagined. And to be sure, there is a potential for loss if it’s not done carefully, but it can be done carefully.&lt;/p&gt;
&lt;p&gt;Now I understand that the reason you withdraw it from the exchange is that if you don’t, you don’t have bitcoin. You have an IOU of bitcoin from an exchange. An exchange that may fail, or get hacked, or suffer any other of a number of bad endings. And in that event, your IOU will not be worth much. There is no FDIC insured bitcoin account. If the exchange goes under and you don’t have your bitcoin, it is unlikely that you will ever see that bitcoin.&lt;/p&gt;
&lt;p&gt;I don’t think there’s an imminent danger to your bitcoin if it’s currently sitting on an exchange. But I do think that it reduces your risk for you to store your own bitcoin, and I think it forces exchanges to conduct themselves more carefully. If your bitcoin is currently stored with an exchange, I would encourage you to research what it would take to store your own bitcoin securely. &lt;a href=&quot;https://blog.willcosgrove.com/beginners-guide-to-hardware-wallet&quot;&gt;I’ve written some thoughts about that here.&lt;/a&gt;&lt;/p&gt;
&lt;section data-footnotes class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;In December 2018, &lt;a href=&quot;https://en.wikipedia.org/wiki/Quadriga_Fintech_Solutions&quot;&gt;QuadrigaCX’s&lt;/a&gt; CEO/Founder was suddenly declared dead. It was then discovered that he was the only person with access to the private keys, and 115,000 customers weren’t able to access and withdraw their bitcoin holdings. &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content:encoded></item><item><title>An Exploration of Bitcoin Transactions, the Blockchain, and Miners</title><link>https://blog.willcosgrove.com/an-exploration-of-bitcoin-transactions-the-blockchain-and-miners</link><guid isPermaLink="true">https://blog.willcosgrove.com/an-exploration-of-bitcoin-transactions-the-blockchain-and-miners</guid><pubDate>Sun, 24 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;What will follow is a walk-through of bitcoin’s circular lifecycle as it gets transacted from person to person. Because of the circular nature, there’s not an ideal starting point, because you must always know what came before to truly make sense of where you currently are. So we will start with some unexplained givens, and work our way around the circle from there until we finally understand what we at first had to take for granted.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.willcosgrove.com/_astro/image-1.DUQNkazt_13nCfA.webp&quot; alt=&quot;Bitcoin Lifecycle&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;879&quot; height=&quot;680&quot;&gt;&lt;/p&gt;
&lt;p&gt;We will be working our way around this circle, starting at &lt;em&gt;Build&lt;/em&gt;, and taking some detours along the way to explain certain concepts in more detail.&lt;/p&gt;
&lt;h2 id=&quot;whats-in-a-transaction-build&quot;&gt;What’s in a Transaction? (Build)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;h4 id=&quot;wallet-vs-address&quot;&gt;Wallet vs Address&lt;/h4&gt;
&lt;p&gt;Addresses are a surprisingly complex topic, and I won’t be covering exactly how they work here. But the distinction between a wallet and an address is important. An address is where bitcoin is sent, and a wallet has many addresses. When you view your wallet, you’re able to see all the funds sent to all the addresses available under the wallet.&lt;/p&gt;
&lt;p&gt;I’ll interject with these asides to define terms from time to time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Transactions are how bitcoin moves. You can move it from your wallet to a friend’s wallet, or from an exchange’s wallet to your wallet, or from one of your wallets to another one of your wallets, maybe even the same wallet. At its core, a transaction is just a list of inputs and a list of outputs. The inputs are the bitcoin that is going to be spent, and the outputs are where the bitcoin is going. When an input is used in a transaction, all of it is used. So if you have an input of 1 BTC, your transaction is going to have to do something with that entire amount. “But what if I only want to spend 0.1 BTC?” No problem, just add an output to pay yourself back the remainder.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.willcosgrove.com/_astro/image-2.DF4MVaKa_Z1ALMP.webp&quot; alt=&quot;Simplified Transaction&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;972&quot; height=&quot;540&quot;&gt;&lt;/p&gt;
&lt;p&gt;This is the basics of what a transaction looks like. A transaction can have one or more inputs and one or more outputs. We’ll get to know why you might have more than one input when we talk about where inputs come from.&lt;/p&gt;
&lt;h2 id=&quot;prove-yourself-sign&quot;&gt;Prove Yourself (Sign)&lt;/h2&gt;
&lt;p&gt;Now that you’ve built your transaction, it must be signed. Specifically, the inputs must be signed to be considered valid to spend. This is what keeps other people from spending your bitcoin. Only you have your private key, and therefore only you can produce a valid signature for the inputs. If you are using a software wallet, this step (and possibly even the build step) is hidden away from you. You would just have specified an amount and a destination address, and it would have built and signed the transaction behind the scenes. If you are using a hardware wallet, these steps are more manual because the computer or phone you use to build the transaction does not possess the private key to create the signature. This inconvenience is actually a security feature, and why you would use a hardware wallet. You cannot spend your bitcoin without using the hardware wallet to sign the transaction. This added requirement makes it impossible for a remote hacker to access your private keys. Someone would need physical access to your hardware wallet to access your bitcoin.&lt;/p&gt;
&lt;p&gt;In the case of someone using a &lt;a href=&quot;https://coldcardwallet.com/&quot;&gt;Coldcard&lt;/a&gt;, you would build your transaction, export it, and copy it to a Micro SD card. Then you would power up and log in to the Coldcard, insert the Micro SD, and select “sign a transaction”. It would find the unsigned transaction on the Micro SD and display the primary information about the transaction: amount being transacted, addresses it’s being paid to, and fee (we haven’t talked about this, but we will come back to it). Once you confirm that everything looks correct, you tell it to sign the transaction. It will sign it using the private key stored in the device’s secure element and write the signed transaction back to the Micro SD.&lt;/p&gt;
&lt;p&gt;Then finally, you would take that signed transaction back to your computer and…&lt;/p&gt;
&lt;h2 id=&quot;telling-the-world-broadcast&quot;&gt;Telling the World (Broadcast)&lt;/h2&gt;
&lt;p&gt;Now that you have a signed transaction, you can broadcast it on the bitcoin network. Broadcasting can happen through your own node if you’re running one and are connected to it, or through other nodes. Most wallet software (be it for computer or phone) is designed to work without the user running their own node. That means that the app developers have a node that they are operating that you can use to broadcast transactions through.&lt;/p&gt;
&lt;p&gt;When you pass it to the first node, that node (whether it’s yours or some 3rd party’s) will validate the transaction. Once it has validated it, it will broadcast the transaction to all the nodes that &lt;em&gt;it&lt;/em&gt; is connected to. That cycle will continue until all nodes on the network have received and independently verified the transaction. This process takes about 12 seconds for a majority of the nodes to see the transaction, but it can take upwards of a minute for every node to receive the transaction&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;true&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h2 id=&quot;dont-trust-verify-validation&quot;&gt;Don’t Trust, Verify (Validation)&lt;/h2&gt;
&lt;p&gt;Each node will look at the transaction and will validate it against the &lt;strong&gt;consensus rules&lt;/strong&gt;. The consensus rules are the rules that all nodes in the network must agree on to remain cooperative in the same network. A node that does not follow the consensus rules will eventually get banned by its peer nodes.&lt;/p&gt;
&lt;p&gt;What do the consensus rules consist of? Mostly of rules to consider a block valid or not, but a subset of the rules are concerned with checking if a transaction is valid or not. The rules that apply to transactions are that the inputs and outputs are balanced (you can’t spend more than the inputs) and that the signatures provided for the inputs are valid. The signature is a &lt;strong&gt;cryptographic signature&lt;/strong&gt; that is computed using some math that is out of the scope of this blog post, and out of the scope of my understanding. The critical thing to know is that the cryptographic verification mathematically proves that the private key that created the original address is the same private key that is signing the spend authorization to send that bitcoin to another address.&lt;/p&gt;
&lt;blockquote&gt;
&lt;h4 id=&quot;confirmed-vs-valid&quot;&gt;Confirmed vs. Valid&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Valid Transaction&lt;/strong&gt;: a transaction that passes the consensus rules&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Confirmed Transaction&lt;/strong&gt;: a transaction that has been included in a block on the blockchain. After it has appeared in a new block, it is said to have one confirmation. Each block that gets mined after its inclusion in the blockchain is counted as an additional confirmation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So the inputs need to match or exceed the outputs, and they all need to be signed. But we haven’t actually talked about what an input is or where it comes from.&lt;/p&gt;
&lt;h3 id=&quot;origin-of-an-input&quot;&gt;Origin of an Input&lt;/h3&gt;
&lt;p&gt;Every input is the output of a previous transaction. That makes sense, every input you spend had to come from someone paying you at some point. Bitcoin wallet balances may work differently than how you mentally model your USD bank account. You may conceptually think of your bank account as a balance. Your paycheck comes in; the balance goes up. You buy dinner; your balance goes down. When money comes into your bank account, you imagine it adding to the balance. And when you spend, you don’t think about where the origin of that money came from, whether it was from this paycheck or that Venmo from a friend. It just comes out of the balance, the sum of all the money you have.&lt;/p&gt;
&lt;p&gt;That is not how bitcoin is managed. Every payment you receive is kept track of individually. Each one is called a UTXO: Unspent Transaction Output. It is precisely what the name implies, an unspent output from a transaction. Someone paid you in a prior transaction, your address was in one of the outputs of that transaction, and you have not spent it yet. So it’s a UTXO. When you build a transaction, the inputs are UTXOs. Transactions consume UTXOs as inputs and produce new UTXOs as outputs. It also may become clear now why you would have more than one input in a transaction. If you want to spend an amount greater than what you’ve ever been paid in one output, you would need to use multiple UTXOs to have enough bitcoin available in the transaction.&lt;/p&gt;
&lt;p&gt;Ok, that’s all well and good, but how did the first input happen? Where did that come from? What a perfect segue into our next lifecycle stage!&lt;/p&gt;
&lt;h2 id=&quot;this-isnt-your-minecraft-block-confirm&quot;&gt;This isn’t your Minecraft Block (Confirm)&lt;/h2&gt;
&lt;p&gt;Before we get to mining, we should probably step back to the broadcast and verification process briefly. You broadcasted the transaction from some initial node. That node verified the transaction, according to the consensus rules. Once that node verified that the transaction was valid, it sends the transaction on to each node that it is connected to. This process repeats until every node in the bitcoin network has seen the transaction, and has validated it. If any node deems the transaction invalid, it does not pass the transaction on to other nodes. Why might one node consider a transaction valid, while another does not? That sounds like a topic for another post.&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;Eventually, after propagating through the network, your transaction will arrive at the node of a miner. A miner is a member of the bitcoin network that is trying to create blocks. What are blocks? They are the fundamental element of the blockchain, which is the immutable distributed ledger that contains all bitcoin transactions.&lt;/p&gt;
&lt;p&gt;Let’s break down a couple of words in that description so that they’re clear. &lt;strong&gt;Immutable&lt;/strong&gt;: the blockchain does not change; it only gets added on to over time. &lt;strong&gt;Distributed&lt;/strong&gt;: there is no one authoritative source of truth for the blockchain. It is spread out over each full node on the network. Each node verifies that the chain is valid, and maintains its own copy.&lt;/p&gt;
&lt;p&gt;The blocks contain transactions. Miners collect transactions that are being broadcast around the network put them in a block that they are trying to build. Now we arrive at the question of “what exactly is a miner doing when they mine a block?” First, we need a quick detour into the world of hash functions.&lt;/p&gt;
&lt;h3 id=&quot;hash-functions&quot;&gt;Hash Functions&lt;/h3&gt;
&lt;p&gt;Hash functions play a central role in the mining process. They are another element brought in from cryptography and use lots of complex math that I won’t go over here. But there are a few key things to know about hash functions, specifically &lt;strong&gt;SHA-256&lt;/strong&gt;, which is the function used in bitcoin mining.&lt;/p&gt;
&lt;p&gt;Hash functions take in an arbitrary amount of data and spit out a &lt;strong&gt;fixed amount of data&lt;/strong&gt;. In the case of SHA-256, it outputs 256 bits of data, regardless of the input size. They are also &lt;strong&gt;deterministic&lt;/strong&gt;, which means a given input will always produce the same output. Another critical thing about &lt;em&gt;cryptographic&lt;/em&gt; hash functions is that changes to the input should produce unpredictable changes to the output. You shouldn’t be able to look at two outputs and tell “how close” their inputs were. A piece of data with a single difference will produce a completely different looking hash output. Another key thing about hash functions is that they do not work in reverse. You cannot take an output of a hash function and run it backwards to arrive at the original input. This can be reasoned about intuitively: you can’t expect to take some arbitrarily large input and output a small hash and be able to reverse back into the full input. Information is lost through the hashing process. If someone told you to summarize Leo Tolstoy’s War and Peace into one sentence, it would not be reasonable to expect someone who had never read War and Peace to be able to read your one-sentence summary and then work backward to rewrite all of War and Peace with 100% accuracy. The same principle applies to hash functions.&lt;/p&gt;
&lt;p&gt;I’ve embedded a little hash function playground below. You can type into the box and view the SHA-256 output. You can see how the output size is fixed, no matter your input, and that the changes in the output vary wildly even when making incremental changes to the input. You can also see that if you delete characters and go back to a previous input, that you get the same output as before.&lt;/p&gt;
&lt;p&gt;It is also helpful to note that the output here is a hexadecimal number. It is a number, but it’s base-16, so you count up past &lt;code&gt;9&lt;/code&gt; using the letters &lt;code&gt;a&lt;/code&gt; through &lt;code&gt;f&lt;/code&gt;. You don’t have to understand base-16, but it is important to know that these outputs can be compared numerically (greater than, less than, equal to).&lt;/p&gt;
&lt;p&gt;(Here’s a “fun” game to play: see how long it takes you to find an input where the output starts with two zeros &lt;code&gt;00...&lt;/code&gt;. I promise this will be relevant, and it’s ok to give up.)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https://blog.willcosgrove.com/an-exploration-of-bitcoin-transactions-the-blockchain-and-miners&quot;&gt;Interactive demo: open the post to try it.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;script type=&quot;module&quot; src=&quot;https://blog.willcosgrove.com/opt/buildhome/repo/src/components/HashPlayground.astro?astro&amp;type=script&amp;index=0&amp;lang.ts&quot;&gt;&lt;/script&gt;
&lt;h3 id=&quot;mining-a-block&quot;&gt;Mining a Block&lt;/h3&gt;
&lt;p&gt;With that basic understanding of hash functions, we can start to look at what mining is. A miner takes transactions that it has validated and groups them together into a block. But the block is not yet valid. For the block to be valid, it needs to have an SHA-256 hash output value less than some amount.&lt;/p&gt;
&lt;p&gt;You may be wondering since hash functions are deterministic, how a miner gets different hash outputs if they’re dealing with the same set of transactions. Wouldn’t they always get the same output? There is a space in the block, for something called a &lt;strong&gt;nonce&lt;/strong&gt;. The nonce is a throwaway value that, by definition, doesn’t mean anything. Its only purpose is to alter the input so that you get a different hash output. So the miners “mine” by trying a nonce value, hashing the block, and checking to see if the hash output is less than the set target. An individual miner will do that process trillions of times per second. We’ll talk more about the target in a minute.&lt;/p&gt;
&lt;p&gt;If you tried out my “two zeros” exercise above, you might have found it very difficult (maybe not, depends how lucky you were with your input). The lower your target value is, the harder it is to find a valid hash. This can be reasoned about intuitively: if you limit the valid hashes to only hashes that start with &lt;code&gt;0&lt;/code&gt;, you are only allowing ¹⁄₁₆th of all the possible hashes (Because it could have started with 0, 1, 2, …, 9, a, b, c, d, e, f. Starting with zero is just one out of a possible sixteen values). If you require two zeros, you’re now only accepting ¹⁄₂₅₆th of all possible hashes. When you get to 19 zeros (which is about where the target is at the time of writing), you are only accepting &lt;code&gt;~1.3e-23&lt;/code&gt; of all possible hash values. If you were going to try and find a valid hash with that level of difficulty in a reasonable amount of time (say about 10 minutes), you would need to be trying about 98 exahashes/sec. That’s &lt;code&gt;exa-&lt;/code&gt; the SI prefix for Quintillion, or a billion billion. &lt;code&gt;98,000,000,000,000,000,000&lt;/code&gt;. It’s a lot.&lt;/p&gt;
&lt;p&gt;And that amount is currently how many hashes the network of bitcoin miners tries &lt;strong&gt;each second&lt;/strong&gt;, to find valid blocks.&lt;/p&gt;
&lt;p&gt;This process is often referred to as &lt;strong&gt;proof of work&lt;/strong&gt;. A phrase which is referring to the fact that because the block hashes to an incredibly rare hash output, there is proof that work was done since it almost certainly would not have happened by accident.&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;I made a demo to show what mining looks like. It’s like the earlier demo, but here, you provide some data that will be our fake transaction data. Then you set the difficulty that you want, represented here as the number of leading zeros, and click start. The miner will iterate through nonces trying to find a matching hash output. So it’s hashing &lt;code&gt;your input + the nonce value&lt;/code&gt;, and this is how it’s getting new hash outputs. Remember that hash outputs are deterministic, so the only way to get a new output is to have a new input. That is precisely the function that the nonce serves.&lt;/p&gt;
&lt;p&gt;You can adjust the difficulty from one leading zero to six. One to three leading zeros can be found pretty quickly on most hardware. Four to five might take a minute to find. With six, you may be waiting for several minutes. You can stop the search by clicking the button again.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https://blog.willcosgrove.com/an-exploration-of-bitcoin-transactions-the-blockchain-and-miners&quot;&gt;Interactive demo: open the post to try it.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;script type=&quot;module&quot; src=&quot;https://blog.willcosgrove.com/opt/buildhome/repo/src/components/MiningSimulator.astro?astro&amp;type=script&amp;index=0&amp;lang.ts&quot;&gt;&lt;/script&gt;
&lt;hr/&gt;
&lt;p&gt;Now let’s talk more about that target that determines which hash outputs are valid and which are not. This is referred to as the &lt;strong&gt;difficulty&lt;/strong&gt;, and it fluctuates over time, every 2,016 blocks, to be precise. The goal of the network is to mine a block, on average, every 10 minutes. To achieve this, every 2,016 blocks (2 weeks if each block took 10 minutes to mine) a difficulty is computed by taking the last difficulty number used, and the time it took to mine the last 2,016 blocks and moving the difficulty up or down a magnitude proportional to the difference in actual time vs. desired time. So if the previous 2,016 blocks were mined in 13 days, but the goal was 14 days, then the next 2,016 blocks will have a greater difficulty, which translates to a smaller difficulty number (because the goal is to find a hash less than or equal to the difficulty number, so making the number smaller reduces the amount of valid hash outputs, and makes finding one more difficult).&lt;/p&gt;
&lt;blockquote&gt;
&lt;h4 id=&quot;difficulty-epoch&quot;&gt;Difficulty Epoch&lt;/h4&gt;
&lt;p&gt;A period of 2,016 blocks is referred to as the difficulty epoch.&lt;/p&gt;
&lt;p&gt;You can view a visualization of the current difficulty epoch at &lt;a href=&quot;https://diff.cryptothis.com&quot;&gt;diff.cryptothis.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It also can move the other direction. If the previous difficulty epoch took 18 days instead of the desired 14 days to complete, the difficulty would drop (meaning the difficulty number goes up, increasing the amount of valid hash outputs, making finding one easier). This is how the network maintains a consistent interval on the mining process even while the miners on the network are constantly increasing in number and efficiency.&lt;/p&gt;
&lt;p&gt;When bitcoin first started, mining was done using CPUs (central processing unit), the generalized processors you find in any computer or phone. Then people moved on to using GPUs (graphics processing unit), a more specialized processor capable of working much faster, but less flexible in the types of tasks it can do. Finally, mining moved on to where it is now, which is done by ASICs (application-specific integrated circuit). ASICs are the least adaptable of the processors, it can literally only do one thing, but it does that one thing extremely quickly. The ASICs are used to compute the SHA-256 hash at the speed of electrons, which is to say: very fast.&lt;/p&gt;
&lt;p&gt;Because of this, and the fact that there are so many miners on the network, it is virtually impossible for someone to mine a block using their home computer. The additional hash rate provided by your computer would be so minuscule compared to the existing hash rate. The odds of your computer finding a valid hash before any of the other miners on the network are such that you would be much better off saving the electricity cost and using it to buy a lottery ticket.&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;I skipped over some important parts of what goes into a block. We know that transactions go into a block. We know that there’s a nonce that lets us fiddle with the hash output of the block. Another crucial thing the block contains is the hash output of the previous block. This is what makes it a block_chain_. Because each block contains within it a reference to the previous block, any attempt to change the data in a prior block will render all the proceeding blocks invalid, because the next block in the chain will be referencing a hash that no longer matches the hash output of its previous block.&lt;/p&gt;
&lt;figure class=&quot;chain wide&quot; data-astro-cid-qpcftqtx&gt;&lt;ol aria-label=&quot;Blocks in the chain&quot; data-astro-cid-qpcftqtx&gt;&lt;li class=&quot;link link-start&quot; aria-hidden=&quot;true&quot; data-astro-cid-qpcftqtx&gt;&lt;svg viewBox=&quot;0 0 100 100&quot; preserveAspectRatio=&quot;none&quot; data-astro-cid-qpcftqtx&gt;&lt;path d=&quot;M0 82 C60 82 40 22 100 22&quot; data-astro-cid-qpcftqtx&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/li&gt;&lt;li class=&quot;block&quot; data-astro-cid-qpcftqtx&gt;&lt;p class=&quot;block-height&quot; data-astro-cid-qpcftqtx&gt;630400&lt;/p&gt;&lt;div class=&quot;block-data&quot; data-astro-cid-qpcftqtx&gt;&lt;span data-astro-cid-qpcftqtx&gt;previous block’s hash&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot; data-astro-cid-qpcftqtx&gt;+&lt;/span&gt;&lt;span data-astro-cid-qpcftqtx&gt;nonce&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot; data-astro-cid-qpcftqtx&gt;+&lt;/span&gt;&lt;span data-astro-cid-qpcftqtx&gt;transaction data&lt;/span&gt;&lt;/div&gt;&lt;p class=&quot;block-hash&quot; aria-label=&quot;hash 00a9e4255a5b63067b76cbfb9fd67f26bdb91be802d5ffcb177ec1b7a8d4c623&quot; data-astro-cid-qpcftqtx&gt;00a9e4255a5b63067b76cbfb9fd67f26bdb91be802d5ffcb177ec1b7a8d4c623&lt;/p&gt;&lt;/li&gt;&lt;li class=&quot;link&quot; aria-hidden=&quot;true&quot; data-astro-cid-qpcftqtx&gt;&lt;svg viewBox=&quot;0 0 100 100&quot; preserveAspectRatio=&quot;none&quot; data-astro-cid-qpcftqtx&gt;&lt;path d=&quot;M0 82 C60 82 40 22 100 22&quot; data-astro-cid-qpcftqtx&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/li&gt;&lt;li class=&quot;block&quot; data-astro-cid-qpcftqtx&gt;&lt;p class=&quot;block-height&quot; data-astro-cid-qpcftqtx&gt;630401&lt;/p&gt;&lt;div class=&quot;block-data&quot; data-astro-cid-qpcftqtx&gt;&lt;span class=&quot;block-prev&quot; aria-label=&quot;previous block’s hash 00a9e4255a5b63067b76cbfb9fd67f26bdb91be802d5ffcb177ec1b7a8d4c623&quot; data-astro-cid-qpcftqtx&gt;00a9e4255a5b63067b76cbfb9fd67f26bdb91be802d5ffcb177ec1b7a8d4c623&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot; data-astro-cid-qpcftqtx&gt;+&lt;/span&gt;&lt;span data-astro-cid-qpcftqtx&gt;nonce&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot; data-astro-cid-qpcftqtx&gt;+&lt;/span&gt;&lt;span data-astro-cid-qpcftqtx&gt;transaction data&lt;/span&gt;&lt;/div&gt;&lt;p class=&quot;block-hash&quot; aria-label=&quot;hash 004b372cb547494db2f62d4b28602329781f2b358e5dbb14a62ad7e5767b3b4a&quot; data-astro-cid-qpcftqtx&gt;004b372cb547494db2f62d4b28602329781f2b358e5dbb14a62ad7e5767b3b4a&lt;/p&gt;&lt;/li&gt;&lt;li class=&quot;link&quot; aria-hidden=&quot;true&quot; data-astro-cid-qpcftqtx&gt;&lt;svg viewBox=&quot;0 0 100 100&quot; preserveAspectRatio=&quot;none&quot; data-astro-cid-qpcftqtx&gt;&lt;path d=&quot;M0 82 C60 82 40 22 100 22&quot; data-astro-cid-qpcftqtx&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/li&gt;&lt;li class=&quot;block&quot; data-astro-cid-qpcftqtx&gt;&lt;p class=&quot;block-height&quot; data-astro-cid-qpcftqtx&gt;630402&lt;/p&gt;&lt;div class=&quot;block-data&quot; data-astro-cid-qpcftqtx&gt;&lt;span class=&quot;block-prev&quot; aria-label=&quot;previous block’s hash 004b372cb547494db2f62d4b28602329781f2b358e5dbb14a62ad7e5767b3b4a&quot; data-astro-cid-qpcftqtx&gt;004b372cb547494db2f62d4b28602329781f2b358e5dbb14a62ad7e5767b3b4a&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot; data-astro-cid-qpcftqtx&gt;+&lt;/span&gt;&lt;span data-astro-cid-qpcftqtx&gt;nonce&lt;/span&gt;&lt;span aria-hidden=&quot;true&quot; data-astro-cid-qpcftqtx&gt;+&lt;/span&gt;&lt;span data-astro-cid-qpcftqtx&gt;transaction data&lt;/span&gt;&lt;/div&gt;&lt;p class=&quot;block-hash&quot; aria-label=&quot;hash 00080a3203fe58f70b16e857765ff5c7bead5a9b7a9e9dd2b85adc4ca124b9d4&quot; data-astro-cid-qpcftqtx&gt;00080a3203fe58f70b16e857765ff5c7bead5a9b7a9e9dd2b85adc4ca124b9d4&lt;/p&gt;&lt;/li&gt;&lt;li class=&quot;link link-end&quot; aria-hidden=&quot;true&quot; data-astro-cid-qpcftqtx&gt;&lt;svg viewBox=&quot;0 0 100 100&quot; preserveAspectRatio=&quot;none&quot; data-astro-cid-qpcftqtx&gt;&lt;path d=&quot;M0 82 C60 82 40 22 100 22&quot; data-astro-cid-qpcftqtx&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/li&gt;&lt;/ol&gt;&lt;figcaption data-astro-cid-qpcftqtx&gt;&lt;p&gt;A chain of blocks. A blockchain, if you will.&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;There are scenarios that can cause the blockchain to diverge, referred to as &lt;strong&gt;forking&lt;/strong&gt;. I’ll save those details for another post. But the most important thing to know about forks is how they are resolved. Nodes will accept the chain that was the most difficult to make, which generally just translates to whichever chain is longest.&lt;/p&gt;
&lt;h3 id=&quot;where-does-bitcoin-come-from&quot;&gt;Where does bitcoin come from?&lt;/h3&gt;
&lt;p&gt;When a miner is working on a block, the first transaction in their block is one that they create, called the &lt;strong&gt;coinbase&lt;/strong&gt; transaction. It’s used to pay themselves a reward, which is how new bitcoins get introduced into circulation. The coinbase transaction is different from other transactions, &lt;strong&gt;it has no inputs&lt;/strong&gt;. The output goes to the miner’s address, and its amount is for the current block reward + transaction fees from the transactions in the block.&lt;/p&gt;
&lt;blockquote&gt;
&lt;h4 id=&quot;block-reward-and-halvings&quot;&gt;Block Reward and Halvings&lt;/h4&gt;
&lt;p&gt;The reward amount is part of the consensus rules. If someone mined a block and tried to pay themselves an incorrect reward amount, no nodes would accept the block as valid.&lt;/p&gt;
&lt;p&gt;The reward was initially 50 BTC. Every 210,000 blocks (~ 4 years), the reward is halved. It halved for the first time to 25 BTC in 2012, and then again in 2016 to 12.5 BTC, and most recently in May 2020 down to the current reward (as of this writing) of 6.25 BTC. These reward halvings are referred to as a &lt;strong&gt;halving&lt;/strong&gt; or more tongue-in-cheekily as a &lt;strong&gt;halvening&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We skipped over fees earlier. Remember that example transaction I showed you at the beginning of this post where you used a 1 BTC input, and gave 0.9 BTC back to yourself, and 0.1 BTC to a friend? Well, in actuality you would need to include some kind of fee. The fee amount is recorded into the transaction implicitly by the difference between the sum of the inputs and the sum of the outputs. So in our example transaction, the difference is 0 (&lt;code&gt;1 - (0.9 + 0.1) = 0&lt;/code&gt;). If you needed to pay your friend 0.1 BTC, then you would receive back less than 0.9, probably something more like 0.899999, which would leave 0.000001 for a fee (or 100 sats).&lt;/p&gt;
&lt;blockquote&gt;
&lt;h4 id=&quot;satoshis-sats&quot;&gt;Satoshis (sats)&lt;/h4&gt;
&lt;p&gt;A bitcoin is divisible up to eight decimal places. The smallest possible amount of bitcoin is one one-hundred-millionth of a bitcoin, and it is called a sat, short for Satoshi, the pseudonymous creator of Bitcoin.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So the miner gets to pay themselves in the coinbase transaction for the block reward (which is currently 6.25 BTC) and for the sum of all the fees in the transactions. The fee amount of the transaction is what incentivizes miners to include your transaction in their block. The blocks have a limited capacity, and if more transactions are needing to be confirmed than there is space in the upcoming block, the miners will prioritize including transactions that give them the most reward.&lt;/p&gt;
&lt;h2 id=&quot;recap&quot;&gt;Recap&lt;/h2&gt;
&lt;p&gt;We covered a lot of things, so let’s run through it all briefly to solidify our mental model.&lt;/p&gt;
&lt;h3 id=&quot;build&quot;&gt;Build&lt;/h3&gt;
&lt;p&gt;When we transact with bitcoin, we build a transaction that consists of inputs and outputs. Inputs are UTXOs (unspent transaction outputs) that belong to us; they are outputs that were paid to us in earlier transactions. They are used as inputs to this transaction, and we create new outputs using the address(es) that we are sending bitcoin to. When we add inputs to a transaction, all of its value must be “spent” in the transaction, so any amount left over that we don’t intend to spend will be paid back to us. This is called the “change output” but there’s nothing special about it, it’s just a normal output; it just happens to be paid to an address that we control.&lt;/p&gt;
&lt;h3 id=&quot;sign&quot;&gt;Sign&lt;/h3&gt;
&lt;p&gt;Once we’ve built the transaction, we can sign it. Specifically, we’re signing the inputs, communicating to the network that we are indeed the owner of the address that the bitcoin was originally paid to, and we are authorizing the spending of them now, in this transaction. If you are using a software wallet, signing will probably happen transparently and seamlessly. If you are using a hardware wallet, this will involve more ceremony, as you need to get the unsigned transaction to the hardware wallet so that it can sign it, and get the signed transaction back to your computer or phone for broadcasting.&lt;/p&gt;
&lt;h3 id=&quot;broadcast--validate&quot;&gt;Broadcast &amp;amp; Validate&lt;/h3&gt;
&lt;p&gt;Then we broadcast the transaction to the network, using either our own node or someone else’s. That node will validate the transaction, and if it determines it to be valid, it will forward it along to all the nodes it’s connected to. Each of those nodes will do the same thing, validating the transaction before continuing to broadcast it out to their connected nodes. Eventually, our transaction will have made its way around the world to each bitcoin node on the network. Some of those nodes will be miners.&lt;/p&gt;
&lt;blockquote&gt;
&lt;h4 id=&quot;mempool&quot;&gt;Mempool&lt;/h4&gt;
&lt;p&gt;The mempool is the name for the set of transactions that are valid but are still awaiting being included in a block.&lt;/p&gt;
&lt;p&gt;You can view a visualization of the mempool at &lt;a href=&quot;https://mempool.space&quot;&gt;mempool.space&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;confirm&quot;&gt;Confirm&lt;/h3&gt;
&lt;p&gt;Miners take transactions from the mempool and try to build a block containing them. If there are more transactions in the mempool than will fit in a block, the miners will preferentially try to include transactions that net them a higher fee. Each miner will iterate through nonce values, hashing the block, and testing to see if its output fits under the current difficulty threshold. If it finds a valid block, it broadcasts it on the network the same way a transaction is broadcast. Each node will validate the block and each transaction within it. Transactions in the new block are removed from the node’s mempool.&lt;/p&gt;
&lt;p&gt;Additionally, every 2,016 blocks a new mining difficulty is calculated. If the mining were happening too quickly (on average faster than 10 minutes per block), it would get more difficult. If the mining were happening too slowly (on average longer than 10 minutes per block), the difficulty would drop.&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;Hopefully if you made it through all of that, you feel like you have a better understanding of what is going on when you transact with bitcoin. And hopefully you also feel like you understand a bit more about what mining looks like, why it’s difficult, and why you’re unlikely to make any money mining on your home computer.&lt;/p&gt;
&lt;p&gt;If this left you with more questions, I highly recommend &lt;a href=&quot;https://www.amazon.com/Mastering-Bitcoin-Programming-Open-Blockchain-dp-1491954388/dp/1491954388&quot;&gt;Andreas Antonopoulos’ book &lt;em&gt;Mastering Bitcoin&lt;/em&gt;&lt;/a&gt;. It covers almost every aspect of Bitcoin in great detail. I think it’s readable for non-software developers, while still being useful to those who are software developers. Definitely check it out if you found this post interesting. And I mean, you’re reading the bottom, so you probably were, or you’re one of my poor loved ones who is proofreading this for me for the umpteenth time. ❤️&lt;/p&gt;
&lt;section data-footnotes=&quot;true&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;Christian Decker, Roger Wattenhofer, &lt;a href=&quot;https://tik-old.ee.ethz.ch/file//49318d3f56c1d525aabf7fda78b23fc0/P2P2013_041.pdf&quot;&gt;&lt;em&gt;Information Propagation in the Bitcoin Network&lt;/em&gt; (PDF)&lt;/a&gt; &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>A Beginners Guide to Using a Hardware Wallet</title><link>https://blog.willcosgrove.com/beginners-guide-to-hardware-wallet</link><guid isPermaLink="true">https://blog.willcosgrove.com/beginners-guide-to-hardware-wallet</guid><pubDate>Sat, 16 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;preface&quot;&gt;Preface&lt;/h2&gt;
&lt;p&gt;The terminology can get a bit confusing, especially with the overuse of the word “wallet” which means different things in different contexts. Just a quick glossary:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wallet - Some data that can be used to generate receive addresses, and sign transactions. It can be serialized into a “backup phrase” or “seed words”, these or variations of these are used around the internet to describe the same thing.&lt;/li&gt;
&lt;li&gt;Hardware Wallet - A device that generates and stores a wallet using some kind of secure element.&lt;/li&gt;
&lt;li&gt;Software Wallet - Software running on a computer or phone that can generate/store/recover a wallet.&lt;/li&gt;
&lt;li&gt;Steel Wallet - a cute name for a very durable recording of the seed words of a wallet, usually in actual steel.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The terminology is not great. People hear “wallet” and imagine the thing they store in their pocket, and this is conceptually quite a bit more complex than the folded dead cow that may spring to mind.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I’m going to take it as a given that you want to custody your own bitcoin. You may not be in that place yet, or you may not understand why you would want to. There’s enough to say about that for it to be its own blog post, so I will leave it alone for now and just assume that you have made the decision that owning your own private keys is the way to go, now you just want to make sure you do it properly.&lt;/p&gt;
&lt;p&gt;There are risks associated with being your own bitcoin custodian. To be sure, there are risks with &lt;em&gt;not&lt;/em&gt; having custody of your own bitcoin. This guide is going to help minimize risks with the former. When you are the sole owner of your bitcoin, there is no one to call if something goes wrong. No customer support or government insurance program can make you whole again. You can, and people do, lose bitcoin. But if you follow this guide, you should be well on your way to not losing it.&lt;/p&gt;
&lt;h2 id=&quot;why-a-hardware-wallet&quot;&gt;Why a hardware wallet?&lt;/h2&gt;
&lt;p&gt;You can custody bitcoin many ways. The easiest way is with a software wallet, either on your computer or on a phone. This is a fine thing to do if it’s something that you’re spending frequently, or it’s an amount low enough that it wouldn’t be catastrophic to lose. This kind of wallet is sometimes referred to as a “hot wallet”. It’s hot because it’s on a device connected to the internet. It’s fast to use, but it’s vulnerable to attacks. Every few weeks you download software updates for your computer and your phone. Often those updates are patching security vulnerabilities that have been discovered. There are always going to be security vulnerabilities in any device that is sufficiently complex. For this reason, it’s not wise to store large amounts of bitcoin on a hot wallet, for any extended period of time.&lt;/p&gt;
&lt;p&gt;Then you have a “cold wallet” or “cold storage”. This is a storage mechanism that is offline, and ideally is never online. This can also be referred to as being air gapped. This completely removes entire classes of security vulnerabilities. Almost certainly an attacker would need physical access to a device like this to be able to hack it.&lt;/p&gt;
&lt;p&gt;A hardware wallet is a form of cold storage. It is a device that stores the private key for your wallet, and is responsible for signing transactions. My preferred hardware wallet is a &lt;a href=&quot;https://coldcardwallet.com/&quot;&gt;Coldcard&lt;/a&gt; from Coinkite.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://coldcardwallet.com/&quot;&gt;&lt;img alt=&quot;coldcard-mk3-onoff.png&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;700&quot; height=&quot;295&quot; src=&quot;https://blog.willcosgrove.com/_astro/image-1.DmqY2KrM_Z1LA8bC.webp&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Coldcard is special among hardware wallets because it is the only one (that I know of) that can operate 100% air gapped. It never has to be plugged into a computer, which is a huge security win.&lt;/p&gt;
&lt;p&gt;Since all of my experience with hardware wallets comes from using a Coldcard, I’m going to be speaking from that perspective, but the general concepts should still apply no matter which hardware wallet you use.&lt;/p&gt;
&lt;h2 id=&quot;creating-your-wallet&quot;&gt;Creating your wallet&lt;/h2&gt;
&lt;p&gt;When you initially set up your hardware wallet, you will create a new wallet. This is basically just a very very large random number. This large random number effectively [&lt;em&gt;is&lt;/em&gt;][1] your bitcoin. Anyone can spend your bitcoin if they have your random number. You will not interface with this large random number as a random number. There is a &lt;a href=&quot;https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki&quot;&gt;translation algorithm&lt;/a&gt; for turning this large random number into a set of 24 words.&lt;/p&gt;
&lt;pre class=&quot;astro-code astro-code-themes github-light github-dark&quot; style=&quot;background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;txt&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;enact neutral lawsuit dutch ramp royal prosper vessel zebra volcano coyote derive bulb day gorilla chimney joy marble hazard parrot obey thrive pool spy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div style=&quot;text-align:center;&quot;&gt;&lt;em&gt;&lt;small&gt;example seed words&lt;/small&gt;&lt;/em&gt;&lt;/div&gt;
&lt;p&gt;These words are referred to as your “seed words” or “backup phrase”. They are order dependent, but not case dependent. The words in the phrase come from a &lt;a href=&quot;https://github.com/bitcoin/bips/blob/master/bip-0039/english.txt&quot;&gt;word list&lt;/a&gt; defined in the algorithm. The words in the list are unique after 4 letters (meaning you only need at most 4 letters of the word to be able to know with 100% certainty which word it is). This random tidbit will become relevant once we get to steel wallets.&lt;/p&gt;
&lt;p&gt;Again, these seed words basically [&lt;em&gt;are&lt;/em&gt;][1] your bitcoin. If anyone got these words, they would be able to type them into any bitcoin wallet software and pull up all of your transaction history and spend any or all of your bitcoin. So security of these words is paramount.&lt;/p&gt;
&lt;p&gt;When you create your wallet using the hardware wallet, it will present you with your seed words, and ask you to back them up. It is common for the hardware wallet to then quiz you on the words to ensure that you have, in fact, backed them up. This back up is crucial because if anything were to happen to your hardware wallet (lost, stolen, broken, etc.), these seed words will allow you to recover your bitcoin.&lt;/p&gt;
&lt;p&gt;You should not store them in a password manager on a computer (otherwise you might as well not be using a hardware wallet at all). It is common to use something referred to as a “steel wallet” to back up these words. Steel wallets come in all different designs, but the general goal of them is to be very resilient to physical damage while still being readable. Often times these designs will only have space to store the first four letters of each word.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;steelwallets.jpg&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1500&quot; height=&quot;692&quot; src=&quot;https://blog.willcosgrove.com/_astro/image-2.IYUm23bL_19SLOB.webp&quot;&gt;&lt;/p&gt;
&lt;p&gt;I don’t have much to personally recommend here. I have a &lt;a href=&quot;https://www.amazon.com/Cobo-Tablet-Storage-Compatible-Supports/dp/B07RZW8CWY&quot;&gt;Cobo Tablet&lt;/a&gt;, which I primarily got because it had Prime shipping on Amazon, and was on the cheaper end of the spectrum. If I was doing it again, I would get the &lt;a href=&quot;https://blog.coinkite.com/seedplate-backup&quot;&gt;Seedplate&lt;/a&gt; from Coinkite. It’s brand new, and wasn’t available when I was shopping for my steel wallet.&lt;/p&gt;
&lt;p&gt;Jameson Lopp does a great job of reviewing and testing steel wallets. He grades them on heat, corrosion, and crush tests. You can see his catalog of reviewed wallets here: &lt;a href=&quot;https://jlopp.github.io/metal-bitcoin-storage-reviews/&quot;&gt;https://jlopp.github.io/metal-bitcoin-storage-reviews/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I’ll save you some time and say that the best reviewed style of wallet is the Seedplate style. It scores the highest grade given in each category. Though the Seedplate itself has not been tested, the &lt;a href=&quot;https://www.blockplate.com/collections/frontpage/products/blockplate&quot;&gt;Blockplate&lt;/a&gt; is tested and appears to be the same thing, though only storing 12 words, instead of 24 like the Seedplate.&lt;/p&gt;
&lt;p&gt;But for most cases, you probably (hopefully) won’t need the world’s strongest steel wallet. Just having it stored on a medium more durable than paper is great. Having this backup gives you peace of mind that if anything happens to your hardware wallet, you can always recover your funds.&lt;/p&gt;
&lt;p&gt;There is of course a security problem now with the steel wallet. Since it is [&lt;em&gt;basically&lt;/em&gt;][1] your bitcoin, you do need to keep it safe. What that looks like will be different for different people, and different for how much bitcoin is stored with it.&lt;/p&gt;
&lt;h2 id=&quot;adding-a-passphrase&quot;&gt;Adding a passphrase&lt;/h2&gt;
&lt;p&gt;If it concerns you to have these seed words backed up somewhere, and needing to keep them safe from prying eyes, there is something that can help with that. With the Coldcard (and possibly others, any that support &lt;a href=&quot;https://github.com/bitcoin/bips/blob/master/bip-0038.mediawiki&quot;&gt;BIP-38 wallets&lt;/a&gt;), you can add a passphrase to your wallet. Essentially, a 25th word to your seed words.&lt;/p&gt;
&lt;p&gt;This part can be a bit like the movie, Inception, where the world starts to fold over on top of itself. I’ll try not to lose anyone here.&lt;/p&gt;
&lt;p&gt;Your wallet is backed up, or serialized, using 24 words. Well, in actuality there are 25 words. You can use your wallet without a passphrase, and the 25th word is considered blank, or nothing, or an empty string &lt;code&gt;&quot;&quot;&lt;/code&gt; if you’re familiar with computer data types. But you can add a passphrase and this essentially becomes your 25th word. And each different passphrase that you use, deserializes into a completely different wallet. So your 24 words with no passphrase is a wallet, your 24 words and the passphrase &lt;code&gt;cat&lt;/code&gt; is a different wallet, and your 24 words and the passphrase &lt;code&gt;dog&lt;/code&gt; is yet another wallet. You can make as many wallets as you can invent passphrases. And I’ve referred to it as a “25th word”, but it is not limited to being a word, it can be anything, &lt;code&gt;password&lt;/code&gt;, &lt;code&gt;monkey&lt;/code&gt;, &lt;code&gt;abc123&lt;/code&gt;, &lt;a href=&quot;https://xkcd.com/936/&quot;&gt;&lt;code&gt;correct horse battery staple&lt;/code&gt;&lt;/a&gt;. (If it feels like I’m reading your mind here, you should get some better passwords)&lt;/p&gt;
&lt;p&gt;This passphrase protected wallet has a few implications. It means that now, if someone steals or other wise stumbles upon your seed words, all is not lost. They are about twenty-four twenty-fifths towards having your bitcoin, but they won’t have your passphrase. Additionally, they won’t &lt;em&gt;know&lt;/em&gt; you used a passphrase (well, they might if the non-passphrase wallet is empty). Nothing indicates that a passphrase has been used, the seed words are still the seed words, whether or not a passphrase is used.&lt;/p&gt;
&lt;p&gt;Obviously, to reap the benefit of this, you should not ever store your passphrase in the same location as your seed words. I think it’s safe to store a passphrase in a normal password manager.&lt;/p&gt;
&lt;p&gt;The other implication is that you can use your hardware wallet, and the corresponding seed words to create as many other wallets as you want. Having other wallets, all able to run off of one hardware wallet, is nice for a couple of reasons. You can use extra wallets to divide up funds, like you might use multiple bank accounts, or multiple savings accounts. You can also use it to store bitcoin for less technically savvy friends or family (assuming there’s a high level of trust there).&lt;/p&gt;
&lt;p&gt;I haven’t said much about how the passphrase works with the actual hardware wallet itself. I can only speak about the Coldcard, but here is what that process looks like:&lt;/p&gt;
&lt;p&gt;You power on the device and log in like normal. At this point you are “at” the non-passphrase wallet. You can select a menu item on the screen to add a passphrase, and type in any passphrase. Once you confirm, it uses the passphrase and the seed words stored in its secure element to arrive at a different wallet. This is the passphrase wallet, corresponding to the passphrase you typed in. The Coldcard by default does not remember this passphrase, it gets completely cleared from memory every time you power off the device. This is a security feature, it gives nothing away that a passphrase has ever been used.&lt;/p&gt;
&lt;p&gt;(There is a new feature added in the latest firmware that allows you to store the passphrase encrypted on an SD card, and load it in on demand. This makes using a passphrase more convenient, you don’t have to type it in every time, but if someone was watching you use the device, or got access to the SD card, they would be able to see that you were using passphrases.)&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Between the added security of not having to worry as much about someone finding your seed words, and the added flexibility of being able to easily create new wallets as needed, I think using a passphrase is a great idea.&lt;/p&gt;
&lt;p&gt;If you’re an ultra-paranoid type, you can use the non-passphrase seed word wallet to store a small amount of bitcoin that you would be willing to lose, as a decoy to throw someone off of thinking that you have a passphrase wallet holding bitcoin. IE: if the thief finds something, they may assume that’s all you have, and leave you alone. If they find nothing and they &lt;em&gt;know&lt;/em&gt; you have something, they may keep digging.&lt;/p&gt;
&lt;p&gt;But hopefully it doesn’t come to that.&lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;And that’s about it. So to recap real quick:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use a hardware wallet (air gapped, like a Coldcard, if possible)&lt;/li&gt;
&lt;li&gt;Back up your seed words using some kind of durable medium, &lt;strong&gt;but not a computer&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;(optional) Use a passphrase to improve the security of your seed word backup. This passphrase is safe to save on your computer, ideally in some kind of password manager. (I like, and use &lt;a href=&quot;https://1password.com/&quot;&gt;1Password&lt;/a&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you do all of this, it should be difficult to lose your bitcoin.&lt;/p&gt;
&lt;p&gt;I did not cover recovery, or actual steps to set up your hardware wallet. There are guides online for that that go through those processes in detail better than I can. But as long as you have your seed words (and your passphrase if you used one), you can recover your bitcoin. As long as someone else hasn’t “recovered” them first.&lt;/p&gt;
&lt;p&gt;Thanks for reading, if you have any questions, feel free to reach out on Twitter or email me.&lt;/p&gt;
&lt;p&gt;[1]: #appendix-1&lt;/p&gt;
&lt;h2 id=&quot;appendix-1-it-basically-is-your-bitcoin&quot;&gt;Appendix 1: “It basically &lt;em&gt;is&lt;/em&gt; your bitcoin”&lt;/h2&gt;
&lt;p&gt;I’ve said this numerous times over the course of this post. I feel the need to explain that for anyone who may not know what I mean. Answering the question “what is a bitcoin?” is not exactly straightforward. What does it mean for you to have possession of bitcoin? And how can a device that is never connected to the internet, never connected to a computer, &lt;em&gt;store&lt;/em&gt; your bitcoin?&lt;/p&gt;
&lt;p&gt;I’m going to gloss over the technical details, mostly so that I don’t accidentally get them wrong and embarrass myself on the internet. But the conceptual model you need in your head to be able to understand what is going on is this:&lt;/p&gt;
&lt;p&gt;The bitcoin blockchain is a ledger. It contains entries, like a ledger does, that says Alice is paying Bob 1 BTC. So you &lt;em&gt;could&lt;/em&gt; say that your bitcoin is stored on the blockchain. There is a ledger entry someone can look up that says you have some bitcoin. But one problem: it doesn’t have your name. It doesn’t know who you are. It doesn’t say “Alice is paying Bob”, it says something more like “the person who held the private keys to this bitcoin, is paying the person who has the private key that can provide the correct signature, 1 BTC”.&lt;/p&gt;
&lt;p&gt;Ok, there’s a lot to unpack there, but crucially, there’s no identity, and the bitcoin is available to anyone who can provide the correct signature. To provide the correct signature, you have to have the correct private key. Those seed words, that very very long random number, that’s your private key. This is a simplification, but I think it still holds up conceptually. So your hardware wallet does not “receive” bitcoin, at least not as some kind of digital message, like your USB drive might “receive” a file to store. Your hardware wallet contains a private key, and it is able to generate a signature that is valid for the bitcoin you “send” to it, allowing you to spend that bitcoin in a later transaction.&lt;/p&gt;
&lt;p&gt;So are your seed words your bitcoin? &lt;em&gt;Basically&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;appendix-2-coldcard-wallet-backups&quot;&gt;Appendix 2: Coldcard Wallet Backups&lt;/h2&gt;
&lt;p&gt;One really cool feature of the Coldcard is &lt;a href=&quot;https://coldcardwallet.com/docs/backups&quot;&gt;Encrypted Backups&lt;/a&gt;. I have to admit, I did not understand the usefulness of this at first. To give a high level overview of what it does: it generates an encrypted zip file, and a 12 word password. My first thought was: So… now instead of having to protect 24 words, I only have to protect 12? Why is that so helpful?&lt;/p&gt;
&lt;p&gt;The thing I was missing was this: The 24 words of your backup phrase &lt;u&gt;are&lt;/u&gt; your bitcoin. If someone has that, that’s all they need to recreate your wallet (unless you have a passphrase wallet, and then they also need your passphrase). In contrast, the 12 word password for the encrypted back up is completely useless unless you also possess the backup file.&lt;/p&gt;
&lt;p&gt;What this means is you can safely store the 12 word password in a password manager, and you can store the encrypted zip file anywhere else. You don’t want to store them together, because storing them together means a hacker just needs to compromise the one thing that holds both of them. Keeping them split up dramatically improves your security.&lt;/p&gt;
&lt;p&gt;You could opt to do this instead of a steel wallet. But I enjoy the tangibility of the steel wallet. In the event of my untimely demise, I feel better about my loved ones being able to get access to a hunk of steel that I’ve hidden somewhere than I do them logging into my computer and finding a file and locating the corresponding password.&lt;/p&gt;
</content:encoded></item></channel></rss>