<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.0.1">Jekyll</generator><link href="https://raghavsood.com//blog/feed.xml" rel="self" type="application/atom+xml" /><link href="https://raghavsood.com//blog/" rel="alternate" type="text/html" /><updated>2024-08-23T15:22:03+00:00</updated><id>https://raghavsood.com//blog/feed.xml</id><entry><title type="html">Rediscovering Bitbills - The First Physical Bitcoin</title><link href="https://raghavsood.com//blog/2024/08/16/rediscovering-bitbills/" rel="alternate" type="text/html" title="Rediscovering Bitbills - The First Physical Bitcoin" /><published>2024-08-16T00:00:00+00:00</published><updated>2024-08-16T00:00:00+00:00</updated><id>https://raghavsood.com//blog/2024/08/16/rediscovering-bitbills</id><content type="html" xml:base="https://raghavsood.com//blog/2024/08/16/rediscovering-bitbills/">&lt;p&gt;In May 2011, an innocuous post[[&lt;a href=&quot;https://bitcointalk.org/index.php?topic=7724.0&quot; target=&quot;_BLANK&quot;&gt;bitcointalk.org/index.php?topic=7724.0&lt;/a&gt;::lsn]] appeared on the bitcointalk forum. Titled &quot;Introducing Bitbills!&quot;, it became the first stepping stone in what grew to be a thriving collectibles market in the Bitcoin space.&lt;/p&gt;
        &lt;p&gt;Described as &quot;the first physical incarnation of bitcoins&quot;, the premise was simple - A Bitbill is a small, credit card sized plastic card with a private key embedded in it. The private key is hidden behind a tamper-evident hologram, and can be revealed by peeling off the hologram. The card also has a public key printed on it, which can be used to verify the balance of the card.&lt;/p&gt;
        &lt;p&gt;The cards were produced in denominations of 1, 5, 10, and 20 BTC. Intended to be a &quot;bearer instrument&quot;, the concept was simple - you don&apos;t have to teach someone how to set up a bitcoin wallet, nor do you have to wait for multiple confirmations. Just hand over the card, and as long as the tamperevident hologram is intact, the recipient can be sure that the card has not been spent.&lt;/p&gt;
        &lt;p&gt;Given that at the time 20 BTC was approximtely $75, the mode of attack where someone might reveal the key and manufacture a counterfeit card was not considered to be cost effective for the reward.&lt;/p&gt;
        &lt;p&gt;The cards had moderate success - they were produced for nearly a year, with confirmation that production had ceased as of 15th May, 2012.&lt;/p&gt;
        &lt;p&gt;As time passed, more prominent collectibles appeared - Casascius coins, alongside other notable mentions like Satori and BTCC, produced tens of thousands of pieces. However, Bitbills remained unique - they were the first.&lt;/p&gt;
        &lt;p&gt;There was just one problem - just how rare are they? In a collectibles market, scarcity drives a significant portion of premiums, and Bitbills were so early that they didn&apos;t know they were collectibles. In latter years, most creators published address lists, or at least mintages, to let the market make an informed choice. However, Bitbills were more novelty than precious. They were handed out for free at meetups.&lt;/p&gt;
        &lt;p&gt;To unravel this, I turned to on-chain evidence. All Bitcoin transactions are recorded permanently on the blockchain, and with a little bit of data analysis, we can determine how many Bitbills were produced.&lt;/p&gt;
        &lt;h2 id=&quot;on-chain-forensics---tracking-down-bitbills&quot;&gt;On-chain forensics - Tracking down Bitbills&lt;/h2&gt;
        &lt;p&gt;My starting point is to look at the funding source for a Bitbill. I picked one that I knew was definitely a real Bitbill, and looked at the transaction history for its address. &lt;code class=&quot;highlighter-rouge&quot;&gt;1EfjzEoKYp91koXBY8MazraUcapy9mRpLA&lt;/code&gt; is a 1 BTC Bitbill, funded in transaction &lt;code class=&quot;highlighter-rouge&quot;&gt;e912b3a38015b72a38c43e158f78940818908164f988c81bc98f94d7e106fc76&lt;/code&gt;.&lt;/p&gt;
        &lt;p&gt;This immediately gives us a wealth of information. The transaction appears to fund 141 potential Bitbills (and 1 change output). The transaction originates from &lt;code class=&quot;highlighter-rouge&quot;&gt;1FhTe1bMtoKHDbNw13v3BQ9sb2kFTagaRH&lt;/code&gt;. The change is sent to a different address, &lt;code class=&quot;highlighter-rouge&quot;&gt;19XFbTZ2K3JEW2y9GFbeLyikfaKtEUNTds&lt;/code&gt;.&lt;/p&gt;
        &lt;p&gt;Looking at the origin address more closely, we see many similar looking transactions - several outputs matching Bitbill denominations, and a singular change output.&lt;/p&gt;
        &lt;p&gt;Based on this, we can say with some degree of confidence that all Bitbills are funded by transactions originating from &lt;code class=&quot;highlighter-rouge&quot;&gt;1FhTe1bMtoKHDbNw13v3BQ9sb2kFTagaRH&lt;/code&gt;, or from a change output that can be traced back to it.&lt;/p&gt;
        &lt;p&gt;Thus, discovering the total mintage of Bitbills becomes an exercise in following the transactions.&lt;/p&gt;
        &lt;p&gt;I wrote a script that broadly works as follows:[[I&apos;m not the first person to use this approach - Charlie Lee followed a &lt;a href=&quot;https://bitcointalk.org/index.php?topic=3334918.msg50843287#msg50843287&quot;&gt;nearly-identical process&lt;/a&gt; to track down the very same Bitbills in 2013. I only differ in not excluding outputs under one BTC. However, this does not impact the discovered set of addresses, and both Charlie and I end up with the same Bitbill list.::rmn]]&lt;/p&gt;
        &lt;ol&gt;
        &lt;li&gt;Start with the known Bitbill address.&lt;/li&gt;
        &lt;li&gt;Look at outgoing transactions from that address.&lt;/li&gt;
        &lt;li&gt;For each output, categorize it as a Bitbill based on the denomination. The odd-one-out is the change output.&lt;/li&gt;
        &lt;li&gt;For each change address, repeat the process.&lt;/li&gt;
        &lt;/ol&gt;
        &lt;p&gt;This lets us recursively discover change addresses, and build a list of Bitbill addresses.&lt;/p&gt;
        &lt;p&gt;Running this script produced the following tree:&lt;/p&gt;
        &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1FhTe1bMtoKHDbNw13v3BQ9sb2kFTagaRH
        └── 367fa61d75e0581d45fd21c77a17d6c84b3cf63cc401a619ee4754dbd9770336
        └── 1CydWn65Hydy3bk2sja4ca7TNhKgo3ZRya: 4.09000000 BTC
        1CydWn65Hydy3bk2sja4ca7TNhKgo3ZRya
        └── c64d75151a170e7e18241395efde31e838529ba2a1064de5d392a3e03333715b
        └── 1NVwABgxcThGR3B7uzSEuLmwSfeKTJzkUL: 3.08000000 BTC
        1NVwABgxcThGR3B7uzSEuLmwSfeKTJzkUL
        └── 460cf68924d01f4ad52f04917d0a62d8f0aedf2b09024c9d8fb95635d6242508
        └── 1oXcPjQXMPRjUAybP4AUaHcYv1QxvGnCG: 1.00000000 BTC
        └── 13qLxBe75y3CoLc1Yj5xHvGG2LtPpoZNgJ: 2.07000000 BTC
        13qLxBe75y3CoLc1Yj5xHvGG2LtPpoZNgJ
        └── 37f63da2acd5a1d7f6d7632661f63fe097d0f74dadbf385460cabc2c13699fef
        └── 1JSmbryKkZPceMhfRH1bg3nW2pVzsARMLG: 1.00000000 BTC
        └── 1PTmNzMWktFF1PbjULEmzpKG29jfE7bYqU: 1.06000000 BTC
        1PTmNzMWktFF1PbjULEmzpKG29jfE7bYqU
        └── 48ac7c6ce9493e2ba6f86f1d439d5a06cb1089050741bbf78ca254b9a48993da
        └── 1FdHUdCjaRT9UbsztMDDDJsvRihw2VhkEb: 0.05000000 BTC
        1FdHUdCjaRT9UbsztMDDDJsvRihw2VhkEb
        └── 69a39eb32d93639537e6f3321fd60e608225272699a09dad5f511f38139bd6fb
        └── 1Q3yzUYcrMwugWMmnkehoKhM14eftmcdjA: 20.00000000 BTC
        └── 13zFbf7T6YH451M4XuHrhYxjvYLV7GVzFe: 20.00000000 BTC
        └── 1DKVbMk66tfNN13GMekSsnaEsrKPNVAJ9e: 20.00000000 BTC
        └── 1Kt4RRr7a31PAd1QmnU5H2rFUjBo6NAq8e: 20.00000000 BTC
        └── 189Eioo3X61C2SGqLRGbN5DJw5kcx7R3aJ: 20.00000000 BTC
        └── 12svwJEMQQmh7YvmTHS4dzXjG2ft9GoN8B: 20.00000000 BTC
        └── 14oYkqAwgqE9Sy5BjJF7MoAL8HQB6QW5gq: 20.00000000 BTC
        └── 16ySADfFpG2UGLm81bWvuHFN6SKuot9WyL: 20.00000000 BTC
        └── 17vm5mFEieuZKyXueemwnp5XsQZdgVWr29: 20.00000000 BTC
        └── 1Kz52qVU4h5xqSsPfM929KfJa9Bxr5z141: 20.00000000 BTC
        └── 1AyTyB34UGfxdSdeUruWp6DmaBGDy6RByb: 20.00000000 BTC
        └── 1Cf8RTXZz4fHuMT832wmZa7hesF5FHgYXa: 20.00000000 BTC
        └── 15uSGUQ1Jw6VPobnsdZMqP3U3AdCJBFwZj: 20.00000000 BTC
        └── 1DqEotXCZJ5TgY3SpLLWwhq4vZkJ1LLZiH: 0.01700000 BTC
        1DqEotXCZJ5TgY3SpLLWwhq4vZkJ1LLZiH
        └── 88c5e1c51c66ff0e4048911eab494daa07938cf92fba3e972d79c5f3465aebd8
        └── 1PVZG6Sa6DQnSWaz2FGk5FeUrfG4xi7m12: 1.00000000 BTC
        └── 1NjFgqyCPhqMcEZz5y8T276RkY7tEbu4we: 1.00000000 BTC
        └── 13BWXeFq6H9tTSF71PhKfN6XBjyaTxxYg5: 1.00000000 BTC
        └── 1LQwUhQTtTFBEFV41ToecwmhSpasXKUzsX: 1.00000000 BTC
        └── 1LN3WN32M42jrsDmo2EhHSwko5rGqGG332: 1.00000000 BTC
        └── 1AcRdqWy4CjnsUofgDbskRAJJwFsYALHga: 1.00000000 BTC
        └── 18ZjoW9KMEVL8LVpRicDXQCriw5JZHqKcQ: 1.00000000 BTC
        └── 1CukUy9KuRjAZ1HKtCoZQZeTcwmz57RYe2: 1.00000000 BTC
        └── 1DNTLXsxN35vXaVq6zxtFkDw2vreNeYeyE: 1.00000000 BTC
        └── 1DinHSQjvogApZnWQze1BnPVZoRUZvgKVR: 1.00000000 BTC
        └── 1FavxeFH9qeZEj9v2mMP83c1Svq6A5EG4B: 1.00000000 BTC
        └── 1J9gxeE1nsH2qr9qjaawKnbxzrTKHkM6Fp: 1.00000000 BTC
        └── 1A3tCw8eAAXqRJgUszmTC863KodkPGDQ2d: 1.00000000 BTC
        └── 1EBfy7cVDYpKNHUfawqiVzVdVQW9Qv29C4: 1.00000000 BTC
        └── 1LqZtzAAHRR6L7pouB9R1JyXkDZFymBiiZ: 1.00000000 BTC
        └── 142ZiGQzpk4Mt2k1TvE1W7cSqqMinKFaCa: 1.00000000 BTC
        └── 181Af534iERPvtXzo8SypVevMNUqMfG6nu: 1.00000000 BTC
        └── 1HVNTvcwMHSsBHhf3m7NJnGVqxtPijkWyy: 1.00000000 BTC
        └── 1LKSB5mDXjb1sJFtrRJ6AmfFVbWSPWwNKV: 1.00000000 BTC
        └── 1Ne6tk6xS7QGfwM1Z9MaE5JyFhpX2W459h: 1.00000000 BTC
        └── 12UFKkcdfXSudL8tgPkgMjBQQGPR3gb2MD: 1.00000000 BTC
        └── 1DtCS3PtHHjpu5sG3iWptK6utzrC76RYxT: 1.00000000 BTC
        └── 1Pe3xi8mzsfZxjqj5HhqcyFzGb1LJE1Fsj: 1.00000000 BTC
        └── 18jxSCFW9nyo5qLb7yBB2oJQsEbe5ad3NY: 1.00000000 BTC
        └── 19cwJ6KuWWsqcEcYXuoxt6xirVkWWLf4pg: 1.00000000 BTC
        └── 1Fehz9mNyAnrAZZdY7rxsMH5u1v1WXhWZe: 1.00000000 BTC
        └── 12CT1wHCDLCnwg5ktqbxSVWC5BFM5ESaQX: 1.00000000 BTC
        └── 1GALfcSrGT2xHEdUvNMYQ4Ejhfejz8oudC: 1.00000000 BTC
        └── 1Hm5zhGDsfBcpNMwzWi5zuEvyVDY2P5NsE: 1.00000000 BTC
        └── 14fbKUcjNiZc5p7vsxFbqSRBbu7Mc8LMtJ: 1.00000000 BTC
        └── 1N2FiuRoEstuW5zt9T9M5rZG1PseYtajWi: 0.01400000 BTC
        1N2FiuRoEstuW5zt9T9M5rZG1PseYtajWi
        └── d12b522c33ca1d22d070af08ab12280e793f4134c289b834de91e79b2f0f6247
        └── 1KxMfCMeyARRCFNgNP6ZXTKCSFEhAZBYqp: 0.01350000 BTC
        └── 15LAYfbJRHdfYAhmjWToCA8eJQMUeVq6ws: 1.00000000 BTC
        └── 1WABVYtgbEGk4WdvnjoVKEsx8cHwi9uWd: 1.00000000 BTC
        └── 13bc26x5hqXZaYyz6YoHCG75rKq3MDcBgS: 1.00000000 BTC
        └── 14FSdoALMFVzD1jLapd8AWxJUNk7HdVSRb: 1.00000000 BTC
        └── 18389vPe7S58AHEpQcDzEoTMvWpFRtqpgm: 1.00000000 BTC
        └── 1EJ1gKWXgWZddxYCgxgnnzsAh73sAGVobK: 1.00000000 BTC
        └── 1Kpm9wbbqAM2Xw1nnsCNnp94RBdxfztG6M: 1.00000000 BTC
        └── 1ATChD1Aw4PkJV4i3ZXM126D9HUiK5its5: 1.00000000 BTC
        └── 1J36o61grzs9ZoE9DEicRj3sKdBtZ8THTa: 1.00000000 BTC
        └── 1KAEbnRf2NBPm934XJgTddMZs3ZbKoh7Wm: 1.00000000 BTC
        └── 15GqEnkmZSefuyF3gHMVozDrDR6ckkcNrU: 1.00000000 BTC
        └── 13pk2b2yDK4HAHRs3GEXczmPYA5Yx7My4q: 1.00000000 BTC
        └── 19hRG4DL9NrPAJR7QYFfSJxHrSjbM6idPB: 1.00000000 BTC
        └── 1NWAhJPYB2sxir51ynveMUC7un5aj6PmNL: 1.00000000 BTC
        └── 1HB15oV7k27iXfyLqtmUpGGDTmtgo1E2Pt: 1.00000000 BTC
        └── 15gaoDGMZ9Jsq9hSRNHaTDehsd34oKEtua: 1.00000000 BTC
        └── 17hZac21uJ4FrFGsjex3Na4WQ9Smus2Asq: 1.00000000 BTC
        └── 18SjBDJCX8wXCmqaiY1fR8bR6TgovVyCt2: 1.00000000 BTC
        └── 16zWS1tiWNmqRE2c3zTPG1a3V1tDSwwqyu: 1.00000000 BTC
        └── 1Egx48tYRhTwUL2bCn8V8kAY185h7N8vis: 1.00000000 BTC
        └── 1QCcvT8XxQQPcPCs9b7GEtdVX8tZBfv4AC: 1.00000000 BTC
        └── 1Bvj3Y4xdjJ2HfHaoo3aTSVyt7pFkCYLhF: 1.00000000 BTC
        └── 12KamM2fyweJwPV5khXyzH5mSXfPBTBW1G: 1.00000000 BTC
        └── 193yPtrTu968FfZU1mzLhDkmqKaT7iY6WZ: 1.00000000 BTC
        └── 1FCn4W7Vzi16M6X7JHo9D6T1ivtsG5scpg: 1.00000000 BTC
        └── 1KG4SaRUvCaceL8o3k7uWv3dZZFbSgBtkj: 1.00000000 BTC
        └── 1B6EbFUiG4dHoNQsJZ5ExXPvartFfb6G4Q: 1.00000000 BTC
        └── 18CX1UiD9bEtgA4ryMv4t4kqL3ZEhXBubz: 1.00000000 BTC
        └── 1K6CTnb76856RFpd2Tm841ZBePCW1iXRrc: 1.00000000 BTC
        └── 1Em6HGdY55PAqNgLNJTBsBHWSJt35QXNWc: 1.00000000 BTC
        └── 1Q9ChdRvhhgRL1f2u8piXVgCfFN2ejSgiB: 1.00000000 BTC
        └── 1AN1bsc5zo9Mn7XtdtCdyMZyvs1UMWpTNr: 1.00000000 BTC
        └── 12GnxoXDrGZRQC2NGGbP7h4cnn9yunTdLn: 1.00000000 BTC
        └── 1PBGwHD2T95QR4g5z93uz6yqA6n6GjdpdY: 1.00000000 BTC
        └── 14URKVRJzwmSdZkG5C3MuRsEtmNSLpEGTm: 1.00000000 BTC
        └── 13sH4nbcc4j5zgHzLPbDoceHkoBjRFYtHz: 1.00000000 BTC
        └── 151yi9xn8aAzPUGC83f2dzEGefLAqehXb4: 1.00000000 BTC
        └── 18pU9kLmLzLmMJ6JYa1D6pKb5Apa9UXwuu: 1.00000000 BTC
        └── 1597YCDF9GYYHnhv6XnuFKdB39iiHndufJ: 1.00000000 BTC
        └── 1HUcXkydXwDVMVWWYRGqFLK5w53FhXinem: 1.00000000 BTC
        └── 13nA64juTkvTrZUTxxc1i5cnEVTAZD9MLJ: 1.00000000 BTC
        └── 1NtPFbDGNrPA1FJyrifjyvymdmFFiwGBAa: 1.00000000 BTC
        └── 1DFocLf8E1khhsiSYUX6E1VYa1MNYmRkko: 1.00000000 BTC
        └── 1DdXAeZLLHLiJvMK5BabY3qgtajq5NvtzW: 1.00000000 BTC
        └── 13XUpUYMYYAnVA6y6vxPedwrqaJ5MwaF5e: 1.00000000 BTC
        └── 17DNEeaMyZqjw6TnMGuimqeoQd74qrFQ3d: 1.00000000 BTC
        └── 1Hq9SyZ66sKH8ZibcNTS6ozPsSdY35qEqN: 1.00000000 BTC
        └── 1PUAbi7AF8E6chD7F2mrn71UTyiesdzUxs: 1.00000000 BTC
        └── 1AvHKXKTUkujD85zfdxSCSm8UigCCpqTzJ: 1.00000000 BTC
        └── 1JUnFfYdC1N5KCwg9GjfumwLZ6H7pF2QHF: 1.00000000 BTC
        └── 1AoTy4kp9a7dP6aUJpXirdSpnRgrE1W1n1: 1.00000000 BTC
        └── 1GM1VE2E3ezNr1T4xwFeQW99Eue9sL8e1Y: 1.00000000 BTC
        └── 1CNZZcnjP57W9BxgBDcgxk5TcHXmnmhZSA: 1.00000000 BTC
        └── 13XWQCV1wXExsqzL176LGZP2eeyzKhGDAs: 1.00000000 BTC
        └── 112bZCzRbSrzMjtX9x7S6V6H54MPpzZgxH: 1.00000000 BTC
        └── 1ASKSQ6ocjyFyM3RjqTqG2j9szKcPddG8i: 1.00000000 BTC
        └── 18DTGBWg2CJPb13FZ16p9K27LHg9hpfgnQ: 1.00000000 BTC
        └── 1DvicXjKgntsFNEmgS285NHggjGAe8n6K8: 1.00000000 BTC
        └── 1797wgMXediJVZffxgJEAZwsriZEtKdvLi: 1.00000000 BTC
        └── 13E1qhfCo7VwPnC68G8GmP4kEZdeXpESsP: 1.00000000 BTC
        └── 1NjN7UPkSa67yuGJAyS4JoyYnaFvjU2Sr3: 1.00000000 BTC
        └── 178Gey3ZLmkaSFQQLuwhnp4jg7XBnZF5Xd: 1.00000000 BTC
        └── 1LdHvaMML4CyTs26eTQ9aAzmRnswQqLkHt: 1.00000000 BTC
        └── 15WCcXLXVfs5io7TJAeFC3vmE3uaAmaV74: 1.00000000 BTC
        └── 1PxgHJaRqpqT5TMzSvZViJDZKcHqPHDJeo: 1.00000000 BTC
        └── 14T9baKzESj6TVP5wWG24PSxqHG5YZa6Pv: 1.00000000 BTC
        └── 12EiBvbR4RDaBd8vqVhgFeNbPV9C1bm6UW: 1.00000000 BTC
        └── 1FrrRCoUyxihj8SoQHG8RAfB9jkzrUTnX3: 1.00000000 BTC
        └── 1CksXQegbUMm8H5YvKxq5mtyhuU5gb17bQ: 1.00000000 BTC
        └── 127RMjCoWfFqWQ1Wgj5RanB9SCZNunLDRb: 1.00000000 BTC
        └── 13tag4i5MH6cbpFuq9pZogrnbuArqkn5uD: 1.00000000 BTC
        └── 1FnnD36mgf5gQP5atLm57TDVXkVuPxdbRP: 1.00000000 BTC
        └── 1CF75rPnWtm3bAjyncP4EGaLK3SkbQGig3: 1.00000000 BTC
        └── 1LmkYPUmwX4fruZpXKNeuNfvUotVwwyJ3i: 1.00000000 BTC
        └── 169ZhbqeHXNnoaHcVoRQdZXZ6zm8XvbVXf: 1.00000000 BTC
        └── 1Eq3p6hUv3d9z7z1VHvn4m7JLCEM1B53tK: 1.00000000 BTC
        └── 1LKwppAmbmrCzRoUFURKSEWkmdAFFVLsFr: 1.00000000 BTC
        └── 1FJLmGd9hk3UnxWRUHXksZCpXDT1E2CTJc: 1.00000000 BTC
        └── 1HCu9wT3x458Jy7h5RedA8zui2LK8TEhVa: 1.00000000 BTC
        └── 1GBrgwKX2DxL6wDPiibWkSuhXdULfLcqpd: 1.00000000 BTC
        └── 1KUoDdJD4ebvaVTrpY7nAKNuVqr5ZxtDt8: 1.00000000 BTC
        └── 1BBoevCZbPqnRMJSA3Jke5ZYyr8ggVy9oP: 1.00000000 BTC
        └── 1EPcJnfeijJ7Lwbhjxww3x39zbmz8UJwFb: 1.00000000 BTC
        └── 1BuQ67Hyd9xkjMpouT2pZXAwGZSTavYxM8: 1.00000000 BTC
        └── 1CsuZV94Q26sccMD1vrStK6CgSnGXcxwiF: 1.00000000 BTC
        └── 1PSEkNMyvGDVcWXyQEjouGoHBMg36KzDN7: 1.00000000 BTC
        └── 16D29XivzNxUXMEPNLCXAMwtAmQz7Y6A4k: 1.00000000 BTC
        └── 1G5Wj8jZvRfWmxWNAk7DiEfVsMnB76ynho: 1.00000000 BTC
        └── 1MPaUy21dgNHdM4SE1ontvdkiiCAtfBEPN: 1.00000000 BTC
        └── 1CP9ayvaNHzGZHKvmrUzicKW1tLYXGusoo: 1.00000000 BTC
        └── 1LwCEaUQbvnYJLLRBjHwesZQUCSFcn8KZ5: 1.00000000 BTC
        └── 193SeoU1uXUn2XeV6YbCZgjuquqGQNM1Yt: 1.00000000 BTC
        └── 1GpcpfUSXF1GiTsprp733Bskp9kZJGBCvE: 1.00000000 BTC
        └── 1H1XQis9PkwUdyMScppxzJnXwnNdvDWku7: 1.00000000 BTC
        └── 1B3ryRmoza7mrk94xXHVsZ6Lir29rke5Xa: 1.00000000 BTC
        └── 1Q14BHBHhT2pp8Cd666ktHC1azYhFsb82G: 1.00000000 BTC
        └── 1KKpxAF9qySFsocXYFzbGkYqURaq5Pr7eT: 1.00000000 BTC
        └── 1CkPV4wB5nxb7akLccpqoTxeFSJoE4XjYS: 1.00000000 BTC
        └── 1GF5mtRzUsypQn8UYvJV8Y9cy5pStzQmkh: 1.00000000 BTC
        └── 1CpVkoS89dPeCnh4DDxXKFTg532v6wAXpF: 1.00000000 BTC
        └── 1FGS9UtQVHKpmvPYfp7HvKnmBzdqhM5npr: 1.00000000 BTC
        └── 1AABpNhw7povpcWSSYjTxzH82BJg6CLyiv: 1.00000000 BTC
        └── 1F9LSmQDyuFsdDchxjCWBTcthaFVYAVdzi: 1.00000000 BTC
        └── 1GJFNWknw2TXfkPVYD5zjFBs5Fft3t2wUa: 1.00000000 BTC
        └── 1GPvyGpKL8ohGbXEGB7n21DzdfpQnG6e6e: 1.00000000 BTC
        └── 1BkFezai85uzQeaHTcPZYgKWjYmiUMHuj7: 1.00000000 BTC
        └── 1LCxx6rQoBaXP3iHdh1gMJ8bKsEhX2tDLX: 1.00000000 BTC
        └── 19SjKkVCqL6cMCjhDZojD8ekNF6QpJfdFw: 1.00000000 BTC
        └── 14q34CPkftx69b7HwjUAasHjj9GKnffU6B: 1.00000000 BTC
        └── 16wYQ9Zw1QeVAnsMsjXCQtxXMJ4Fzu8hw8: 1.00000000 BTC
        └── 1N6oostJjNXUKDNfE7Y6nmAvHX6sEQmrDj: 1.00000000 BTC
        └── 1BPEDMSjMmFYa1sHPeUTxyfJeHEx3aVSqz: 1.00000000 BTC
        └── 1BDPuhgSZrh6hFJwmd1GBiWVHDxuHMVw3V: 1.00000000 BTC
        └── 1EBaHFpnRucqpGc3sfZQXGrNU7Y1eVTuYN: 1.00000000 BTC
        └── 16QXivCrDANeDPCa1WVXPYLJQeUBazVEeZ: 1.00000000 BTC
        └── 178QLqfczWzGtGKJCBE8gRFMGUYdHR9s7H: 1.00000000 BTC
        └── 18CdahbQyySQhW9F3zHFFoXDpaK3vs5tGR: 1.00000000 BTC
        └── 17WtHjeCfDc3FXY7r8swqHcVNMNtmjo9y6: 1.00000000 BTC
        └── 1KP16kFQr6daG4poDxQdLbjuFAfmEMcV1J: 1.00000000 BTC
        └── 1Lbg6NampnTKzbAtpKXfQbmBeKovpc3pWw: 1.00000000 BTC
        └── 1866Wk1cDj3t15B96oVsB1sEF5mPwfR7Pt: 1.00000000 BTC
        └── 1HBFkbReXtkJewez3tWJaqDSs1FqLZYMyh: 1.00000000 BTC
        └── 19Y2CAmGxKRVYfbK7JEFqkd5fQ49L7hmxQ: 1.00000000 BTC
        └── 13sqd9mtmYvkdK5qYGDx56ESE9KjU97SZn: 1.00000000 BTC
        └── 1C11k4sTFbM3TjF3u7RxSrVQjP3pabaEjb: 1.00000000 BTC
        └── 18JtzcpS3w6FujHu46SFpLdzkW143f9w4F: 1.00000000 BTC
        └── 1Ar1BoAxzRXgxfeoZummJSofZBQWVFhwAw: 1.00000000 BTC
        └── 1Q1CRWGcMbR5vcr5haJ9td8mMEaFnFSwvq: 1.00000000 BTC
        └── 126mEdXokYrsUSAhB6jjLr93EJFbnkc8yj: 20.00000000 BTC
        └── 168jSV5uZp2VtMPyBm1UxdeBuRnBA7cqs7: 1.00000000 BTC
        └── 13C1ucrhTCJGmmAAHAiZSj9ag9ukhaUnmB: 1.00000000 BTC
        └── 17pbedcsbyfa4M26R7WLohK6sxYEovfw4o: 1.00000000 BTC
        └── 4912c531d4b280ef58254cc9788544c9cba5b2eabc377d3feaa66d4cfef0366c
        └── 1BmbdXZBHXttB6asm69rcjpLaUti2onJFo: 20.00000000 BTC
        └── 1Npm2PErEHHcFozWhBd5pa3smU6eyq3Z4q: 20.00000000 BTC
        └── 13vU1X1wnFWAorVKD1MdX9fsorrytrDBAT: 20.00000000 BTC
        └── 1NKg73XiUzAhsDuWTUPLxptY337Sf39yZA: 20.00000000 BTC
        └── 13vxo7WTwWVENDggpsUXYPEkBSQgvppnv5: 20.00000000 BTC
        └── 1CWDNoBFuytK4JAjYRBVtpaMREq8dsXEqF: 20.00000000 BTC
        └── 12ZQ4bnu9KCfWXAQz8YNYKPLtFE4DPwUtZ: 20.00000000 BTC
        └── 1EuttrML1xEvbtcTatxQsEcMKKQS48qsE8: 20.00000000 BTC
        └── 1H33yfS2rLmPVhegnqCxZp3uNaco2wTFqp: 20.00000000 BTC
        └── 151XvxjnBXGpjDWZXST9Kr9gRRC8DXswE8: 20.00000000 BTC
        └── 1BC8QFogYJc2to7xvtPiv8LespAYMQKFQ8: 20.00000000 BTC
        └── 12h3hpoD8ocPDZKd9xkpp3n3WGa5fL2z1e: 1.00000000 BTC
        └── 9f9c271886e860898ca3781b21e20b734fda44c2c5e712bb936da61ca56bfe91
        └── 1HLHk4kMf6YYbykWSVCxjf7z7n6VFjSjoh: 5.00000000 BTC
        └── 1CKDstPd4rTExF9mVH482G5vCm4sMhAKqi: 5.00000000 BTC
        └── 14TNWHAXZM736s1N3HEEd6m5qpK9ZXtxHm: 5.00000000 BTC
        └── 1HTTr6iUrdGCM5eWfX5vSzQwhqDSjeDttG: 5.00000000 BTC
        └── 1D1suRS5hscHpZTxPZYysSBok8stUAKbJ5: 5.00000000 BTC
        └── 18VVd75aUNj4ekXUJKFnhXMWW1qgQvXKoG: 5.00000000 BTC
        └── 1MtefNLWNN6EfAadzSSTQgAVnXbHffGzCA: 5.00000000 BTC
        └── 1Nh48GNL47L4dHiGLK297JiEY3nfymdS1W: 5.00000000 BTC
        └── 1GELDVJJDu4MYqfe9QY1HzdNkTfHkLd1zy: 5.00000000 BTC
        └── 19Abu1ykvFmAGAuRpNoW9EqbigjP7ywJMx: 5.00000000 BTC
        └── 17GoG6opnac8Usw8cVoeti3UcYRcNEtMZS: 5.00000000 BTC
        └── 1BMr1QjZeapsiHUSicY59AGrw29Y5Kw3iV: 5.00000000 BTC
        └── 16xRknaC3iFcRWbBU2GupwNHZELpiExd1E: 5.00000000 BTC
        └── 1GW4xhgKLNbsSb6s6z7xypUY2vSDsFrueR: 5.00000000 BTC
        └── 1M1c5QgfawAeQKFZiMBThDEZtCBAihFmuD: 5.00000000 BTC
        └── 1MYqkSdSwwQPsWNfui24g1d1CxDFvCqswK: 5.00000000 BTC
        └── 1J1F8KinonhhGvMqRV3MGKQcz6tHp39HRo: 5.00000000 BTC
        └── 1HRBu3ePinFFp4bVFMFGQmTsaYao91RoG6: 5.00000000 BTC
        └── 1KpCUtR5gWQ2dXJ8Hr4hjg8DUrLEF66H3J: 5.00000000 BTC
        └── 18LHAhgbtwbjzcpW4vPq42fmPkCkQqJNzD: 5.00000000 BTC
        └── 1MiHec5gxYvrqjPemMhZSWyQvv2nEtJqK7: 5.00000000 BTC
        └── 1NnbkV9yDtgWdhURL3sGNeS1wo44vat1H3: 5.00000000 BTC
        └── 1FdsQoEjt812zfuqf5cc1xU2ocJJqxD7aa: 5.00000000 BTC
        └── 1McUrFKamXvSxPa7wW2jnddyAPs3iEkGrr: 5.00000000 BTC
        └── 14Q9ePcjNsBqemnynvLTwakpEy9inzH2Ck: 5.00000000 BTC
        └── 1MAUwvegfy1jQHZXhGVehCBc2VXbPazhZw: 5.00000000 BTC
        └── 14KVqQ5xgcFmPEKeHsMzYTtecVRhum1eJZ: 5.00000000 BTC
        └── 15MfHXxWM7MKhLrhpCQaDS8KG2SipjuvsK: 5.00000000 BTC
        └── 14qq1ZPU6QWhnLkJibC4VTjCsuH6frTs4Z: 5.00000000 BTC
        └── 16biEJTFy8QtRKTqS4obpZRgvyjTXQsChZ: 5.00000000 BTC
        └── 1KrGmNY2PaWgAx6288RDLkZgst2SvGAN1f: 5.00000000 BTC
        └── 13VzAmJufAEm9beqQwZadtjoDgL5rrTtkX: 5.00000000 BTC
        └── 16FPtWG7v1qnUNHPsUdMLCBRKFnpLTmewY: 5.00000000 BTC
        └── 1LrmHbGt2mQ6NYXLLohqYW3o2ZL6gnhKYk: 5.00000000 BTC
        └── 14bMhmMegveSbbA9oUetX4QDoQrjj6JD5Q: 5.00000000 BTC
        └── 1DWK3AKKmJexn5qzX91cQzAS69Q8LJp5nD: 5.00000000 BTC
        └── 15v54jKVAq2xgwfiz7NGDnu8ku1DLTmCon: 5.00000000 BTC
        └── 195q5ezhRKmxLipwZVQ6LCNivsfetxjvYM: 5.00000000 BTC
        └── 17DmUfdAbrY4NSyhgXgpNQiK34SpNT3Zih: 5.00000000 BTC
        └── 1PHhNNoaXepcXRY6gLsKEV7uYT4JW78rhg: 5.00000000 BTC
        └── 1FcEzRJjSSTRXZAjoZ77eVRupHtVBubMhe: 5.00000000 BTC
        └── 1CrwF3aEiz8wS5QzijP2KG4eDejQUewSd7: 5.00000000 BTC
        └── 17Fggwq8rZrTofHavJJbKvqHWDqH5zBz6X: 5.00000000 BTC
        └── 1MxUAvmQ8h23JyWXeztHmWFhrDJuCDbwNw: 5.00000000 BTC
        └── 166UKfLEVa1rQ4Qs2kKFyN9qdMoqrJe2Sk: 5.00000000 BTC
        └── 1N9aNFukLpicBwXUVyKSTyQ6bzWTK8p1VV: 5.00000000 BTC
        └── 1LxDudGDkiCWc9uwAqfN6ChzYCEwzehbuw: 5.00000000 BTC
        └── 1GPR14YXvz4EmDD7GgozPQ2KvpVGC5hmYd: 5.00000000 BTC
        └── 15BH7XK5Kkbc1Aq1eiXRYAP9Zoa16BJC3M: 5.00000000 BTC
        └── 1QJzhHfPmMMAFSZdPDWU8RosH6iZgtRF8N: 5.00000000 BTC
        └── 1AJAhbR6tpTWPMrhq6jMvwxFCrV8t6qASF: 5.00000000 BTC
        └── 1EmtzwNxWr1o4wkFPirFY6meh9cFufNLo5: 5.00000000 BTC
        └── 1BusxDXMzh9iwPxbgBRVDQwK1Q2X6M6MT3: 5.00000000 BTC
        └── 1DSCyxD8VUVCJYE468UeLZ3DPS5dghgKdN: 5.00000000 BTC
        └── 1335PxG6ywwh9iMWPNZGA39REV5rThWxMi: 5.00000000 BTC
        └── 1J3g31MhuGPR6UVeqRXsdmYhpQqiSj5mn7: 5.00000000 BTC
        └── 1ELd4XLQdLbE8CuTpxM8gkw8Qxiw13TvR2: 5.00000000 BTC
        └── 1EeVJzMoi8VPGbRw6vvjYn1ZFq3PCUP1Aw: 5.00000000 BTC
        └── 14QafEdQYRgcMPiWyFKUJbiAfXWK28G1v3: 5.00000000 BTC
        └── 159f42MrZtDoXZ13S4LzphMAdSGk8CUpRE: 5.00000000 BTC
        └── 1PiWkdL7c2qNGazg42r2maMirQQykGkrKn: 5.00000000 BTC
        └── 1DDnjTq6f1vyc39CcUFUngEGW3SZfpaUXT: 5.00000000 BTC
        └── 1GY3bgZBmobfuoTH6k1xouMveN9iWDVAmR: 5.00000000 BTC
        └── 1PxRZbYriqDpbTNCFHMBQk8FvUPZYuM1Lt: 5.00000000 BTC
        └── 1QKzKDZKgL1VK159AYzLWETRb4k7XSFLsU: 5.00000000 BTC
        └── 1HcKqpjmcZv3zcVS5wocrZhdbk486qiaZo: 5.00000000 BTC
        └── 17huHD7N5bnaXQyrdnG9kp9KhpDv5FUe33: 5.00000000 BTC
        └── 19vjPgQv9bmKZXe7QbibFUzDG9eUjd4xs3: 5.00000000 BTC
        └── 1JRPbUED5uF8iy2qCMeF1tN1yfjHSwig2Y: 5.00000000 BTC
        └── 1L7omrLJEDjRv6W9zX9J4nzKWEva6CUoeZ: 5.00000000 BTC
        └── 1AhJCuPYt5x3rTXtPPo7Rs1Zxtc3w9XwrM: 5.00000000 BTC
        └── 1E84QaKsCU5azaVc5V7XbfAiqefHd4CpR1: 5.00000000 BTC
        └── 1NxrJzL9yS9ZrkdcZidbX3cR7RjpNvCfrN: 5.00000000 BTC
        └── 1NFcnBhUUbSyXMa2gouwTbaFkKMKVBHu7z: 5.00000000 BTC
        └── 1AR4QRUbCGaU5nqgXLiBny6X6soxLpUyB9: 5.00000000 BTC
        └── 1KaSFauEZtcVLUzD2EpfaD9DyCnP9n35bt: 5.00000000 BTC
        └── 1BMPdV8R2d45mTJ771bias1KSoFGwstnsV: 5.00000000 BTC
        └── 1ESK55m8YGjPpDgx8HAqY88HwvvPM26YHJ: 5.00000000 BTC
        └── 1DbEjWit3cDDtViPgFSwqLsbz74HQ1aA3C: 5.00000000 BTC
        └── 1GgroqP7yPEiWP8XVAYztJQokz1izDuaCL: 5.00000000 BTC
        └── 16DUXAPUkUpCcx9Aqbqpi7dK2Tj2XWhPxJ: 5.00000000 BTC
        └── 1ETqQ4KVYHb7LgKkyzzSNYXFSu55h7quJa: 5.00000000 BTC
        └── 18oYCez1RoY6kUpqfgHkcpAnwKm2bC9nmi: 5.00000000 BTC
        └── 161zGiQAaU5pez1wxfEqfSEBo918mQwvp8: 5.00000000 BTC
        └── 1BsRX4BrbdrWowyDgHAe4JBeMBCwC8kxvQ: 5.00000000 BTC
        └── 1E9bRc5SB5Yqpk8gkNzSLWGdjGRU9ZozHQ: 5.00000000 BTC
        └── 14GerdPidfdFvYqXM4ASqYmnx7aAvCpJPi: 5.00000000 BTC
        └── 1NPjMD3ARata6fH379kJN3Ye7bEipC31EB: 5.00000000 BTC
        └── 1EcXRpaM2nsanfDSgcwWxJatFVaD7NgaJY: 5.00000000 BTC
        └── 15zc4Qpu6odRq8UsXZzdUiFDMVBk28mBPX: 5.00000000 BTC
        └── 15qRUEqMukNJTukTyoNjKNKTa8uhqwVLgP: 5.00000000 BTC
        └── 164Tk9pUYAzQ4qe6MJpVs9FFmdtQrYHvKT: 5.00000000 BTC
        └── 12G2ftwiXhMymQTGeZM7AUHQXqpst1qFUU: 5.00000000 BTC
        └── 1Pru8siLqEc5MLWvra1aSHQ96mWuNcCymG: 5.00000000 BTC
        └── 19qK5bhFpD69QxE6Yd388v16ktWWfPK4tx: 5.00000000 BTC
        └── 1MsVRmtrfUsGy2UeuSLn24kuR8X3PD3UH5: 5.00000000 BTC
        └── 14ofEHC9nkZEMqaduq2UBUNTt99vZFCijJ: 5.00000000 BTC
        └── 19apGS9VM5C7QEBcatmLF3vPZTrFXCcGek: 5.00000000 BTC
        └── 1EgqMxDGUJa1zw2fzGV6pTwipD4XbSmKp8: 5.00000000 BTC
        └── 1GHTvv1niRWeuvmuKTPn3w9hD7MH9RRrEu: 5.00000000 BTC
        └── 1AJTxUHN4EP8JubWpR4mRS8obFpF3q6Jjh: 5.00000000 BTC
        └── 1DHbmJrq134NFoRrPtJX227pohzYGQwUzi: 5.00000000 BTC
        └── 1PPuo9o8JrgVdbjyTRnzKwxdiQwe1q1SHK: 5.00000000 BTC
        └── 1APiCU2T5XdzYoKBKut7nQBPxpdJEG1sVz: 5.00000000 BTC
        └── 1LULerHg2AZstsVZ8NnZN2bcdTBgv42nfT: 5.00000000 BTC
        └── 1DWSsvdQABH6jmBhDqb7s6cUcpMQTnqteZ: 5.00000000 BTC
        └── 15YzqERbwS5E7GE3c3QQ9GYRMjGExoWVXM: 5.00000000 BTC
        └── 1MVFuiA8FkWwtpcYAaz4W4cVu5R9rQ6Drj: 5.00000000 BTC
        └── 1Hxcfkfza1snGvJRt9hFf2KymJ6C1XNBYw: 370.00000000 BTC
        1Hxcfkfza1snGvJRt9hFf2KymJ6C1XNBYw
        └── 4f3578642172b157dc254877e958a4b22ab60f079cfa01f5973eea611e33988e
        └── 12bEBR8gBTWv3XdU628ZkRMtJQD9J3Rbbj: 20.00000000 BTC
        └── 1NjP9hx8MemA8AtRXWQxep9X92UvGsXd34: 20.00000000 BTC
        └── 16CL8QXcM5cGukxB8qihnacwbtMrdLvuy8: 20.00000000 BTC
        └── 1PtwJBf7tuZwtyd2vQmMi41SeR8EFwWyEX: 20.00000000 BTC
        └── 1ELpmfYHoDyf3AJwtFhA18DiV9M7hYFpYv: 20.00000000 BTC
        └── 1LKsQSQQsGT4Fhp5PbvmCugWd9heipypKz: 20.00000000 BTC
        └── 13RD6VyyhW5cEmzSBEWVW31ytbki35XiWR: 20.00000000 BTC
        └── 1Mn2JvH77GqM8oSHkwWEJtrgWBnvuFH25g: 20.00000000 BTC
        └── 1HiZAiRELMzsrJsb39LU4WYCSAr1Cnt3VX: 130.00000000 BTC
        1HiZAiRELMzsrJsb39LU4WYCSAr1Cnt3VX
        └── a0fe308fd3c24e098a74fee2cf9d7f6c044e16b2c820e40d913d675c7011f8e6
        └── 15FNFfgkNpesLg4MrTMmAXajgASYSof19j: 1.00000000 BTC
        └── 1K6hw5mgcitK6z32YWkBMZhT2fwcchW2mo: 1.00000000 BTC
        └── 1HJjGhkt8zHv72Vx6dYfHkxXbHEYjpNbss: 1.00000000 BTC
        └── 185PPKrqepcCAkCS4RoHKKu9H75Dxg7yfT: 1.00000000 BTC
        └── 1DcB6ftZv3y9U62wU8nqSRcxjm1My8uWYP: 1.00000000 BTC
        └── 1CwJN4NiZHjH6Yc6GPx7BYAPvSC56BM2SQ: 1.00000000 BTC
        └── 1AA3krdbG7C4bCPvwnQr2gv464GwTfRctE: 1.00000000 BTC
        └── 15qDZ559NZzXVxfWrrpkZG8wJdPvrybdHM: 1.00000000 BTC
        └── 15hoq231zKqZPHwkeJiJZW4AiqdGKMustQ: 1.00000000 BTC
        └── 1B9zMSA5rVqEvdrd2WZsaJcNKuVeQCQ6Ww: 1.00000000 BTC
        └── 1BeuQB4X9FzW3TuVEkRVdhwivYi3Y2QW6K: 1.00000000 BTC
        └── 1DfoA5v1xJRSsRgNMxESjASotFJjJYGX1p: 1.00000000 BTC
        └── 1QBeEYp1NDqx9fxkmMemV488L6LUgWgeGM: 1.00000000 BTC
        └── 13v9mtruBP9UVKff7YLy4fkzccbpVWSBBk: 1.00000000 BTC
        └── 1DBHBdVFMgCiGNkmxSETDNLXA1QrvRi7sF: 1.00000000 BTC
        └── 1AcRvhsyJF9BCxDZWefzMhA4v5Hu2EvT39: 1.00000000 BTC
        └── 1AXux96R5gVKcVsJxQuqSMBwwK7ezam7sj: 1.00000000 BTC
        └── 1GfEoaKGdQs15WSTLdRbt7VZ6rPh1kzfr5: 1.00000000 BTC
        └── 1Hos9Gj7XeCUEA2DmGrN1AiQdkHDa3nUfc: 1.00000000 BTC
        └── 1Er7D9icjbngH2yD5BetJDbUnv9EyasYYo: 1.00000000 BTC
        └── 1158YqLj7MgCA6iiX9x7P242HC8EU3FocZ: 1.00000000 BTC
        └── 15EzqxdK7ZHKen2XHHeHtXtNgexJGh2McC: 1.00000000 BTC
        └── 12pachdY3rBG4C4JZFRF7kUNBfgvKjXZ1h: 1.00000000 BTC
        └── 1CrdVA6KUDLiSUwQC7SFeqBh3mEd4wdp2L: 1.00000000 BTC
        └── 16EEQvBbsTygf1dd98ThKwrQA3w88SPWMf: 1.00000000 BTC
        └── 1Heoiesb13FY6YzeCkr6y9iXvvbsNZrAcK: 1.00000000 BTC
        └── 1C32JqrhwSBP6xH12wjRGcowVq6X452WBt: 1.00000000 BTC
        └── 16Z5J6R83z7GA25oJPvohoXFxaLftC1RKs: 1.00000000 BTC
        └── 1BE5YG8YCzADhVnFMTEFV9YqFbd2BaMVar: 30.00000000 BTC
        1BE5YG8YCzADhVnFMTEFV9YqFbd2BaMVar
        └── 69a39eb32d93639537e6f3321fd60e608225272699a09dad5f511f38139bd6fb&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
        └── 1J3PJmK2sCS7p511frpGGcZv1YhGLo9RLF: 1.00000000 BTC
        └── 14JjMSyD77HU5WPYWw9LhpbcuGgrWrextP: 1.00000000 BTC
        └── 19Ngvmmb7Risp13ScXjxAr7QRQdA9KUp2z: 1.00000000 BTC
        └── 1D9zreP3D9yiaMex43GtdwB5EwwcC9yyfA: 1.00000000 BTC
        └── 1P6xoXyhR8rscftJ1PB5S7vuK9QnimMkqM: 1.00000000 BTC
        └── 1GsrBB8xkUPDp5mxvPevacyS85qydhqMNk: 1.00000000 BTC
        └── 1Ho7ngBHHMpBfQJ5NBh6E5NmrYT1BDsQcd: 1.00000000 BTC
        └── 1EHzU83pTbNr39TkTJSRvygRmsD4c8mkKz: 1.00000000 BTC
        └── 1N62yfzFu965DGY14SqwJ2RSJ2sQMXMdQ5: 1.00000000 BTC
        └── 1AjHfYqXL7erox3JDUP6k9qeQzEU4yEwBc: 1.00000000 BTC
        └── 19MLXMqrpTsQddF42nSZx597R37mAS6T6J: 1.00000000 BTC
        └── 1GiYBrg5CcbFtDz9W8yXTdsW8EXD6kDmQa: 1.00000000 BTC
        └── 17rvvk8dZzZuCtLnRLrGm15fD6DZ89sPF4: 1.00000000 BTC
        └── 14wKRJ7bqWixbyeXxDWurhckQyRyfPUGLi: 1.00000000 BTC
        └── 1B1YN8xUnw7mNJcvSAAJTLKbCncNmyxSog: 1.00000000 BTC
        └── 1Kp4Joh9mUNKRubhzN5ASmwkbY13zgPZ3L: 1.00000000 BTC
        └── 1LeNs9d4KAUe1Z4EEiGJKjew2LKXV2sVi5: 1.00000000 BTC
        └── 1JuS7vPMbhuDLGzHs6JnnzctYnJFFUUXiD: 1.00000000 BTC
        └── 17b4DxLvaRjpbqq9u9y2FJ2yms456FgHqp: 1.00000000 BTC
        └── 13njS9poyn1wC6j94PwG3bfA3yXdktbr8F: 1.00000000 BTC
        └── 1FvbvfW6TypdYt8xGiKWdBf88SX6AD6jtz: 1.00000000 BTC
        └── 1MXwftiUBGVTG35H2JKnCmXCq6ukbjaPgt: 1.00000000 BTC
        └── 18wyH3qL3Cdh4wsTLK9frqHdngKP5iNmbV: 1.00000000 BTC
        └── 1NaYur81Mf7Ukse24TYpLR8LWRh6HVd1cy: 1.00000000 BTC
        └── 1L3qiJAux7hFr4fRgH2Shm5konUuhE2UHv: 1.00000000 BTC
        └── 1DWwc9q4CiFXywpMCCGV2sQpXqiZJX28av: 1.00000000 BTC
        └── 1EM1hVHuifpFgXWcTGnYVUEjnwZYBjxif: 1.00000000 BTC
        └── 1KMfzEDPXfYycQqFKMjfRsaxhiUYefLsi5: 1.00000000 BTC
        └── 1LBdpcLwB62Fx6u3Yj2jhY1KE5Ey7GTWSn: 1.00000000 BTC
        └── 1LZbvvivPMrcYh7DbGymnDkm4u7jDJmocW: 1.00000000 BTC
        └── 1BXo5jRKQYNqmoCJigYdUJrJwsNE65LiB9: 1.00000000 BTC
        └── 15SpqQ1qogye8T1VThr7BZZSBVr2m2SKqB: 1.00000000 BTC
        └── 1MGtWvfjnvNZDAwLpqTT7gKNZyFRp76nHK: 1.00000000 BTC
        └── 1413guUYdoFNcw5eWguHsyBXhmzCyhxirQ: 1.00000000 BTC
        └── 13zkoHWXm99YHVnWWGcusJx6XeCMAAJzzJ: 1.00000000 BTC
        └── 1GYzrjGJD5CkL1B5d5fjmg49jrGYiYC9RZ: 1.00000000 BTC
        └── 16wS59GU2wVVceP9iQLLyAoqeRYsGTETFN: 1.00000000 BTC
        └── 17vGGoMQzPgdfEr994tPzKXFP2deedwsks: 1.00000000 BTC
        └── 19J555qVghj3MiHLHWurUz7f7aDnbfE6cB: 1.00000000 BTC
        └── 1EDchzbPuNK66Vx8SpQfXeZJDUw9oC1gy8: 1.00000000 BTC
        └── 16s4HAUaah6nSynu76UwrHDHQv9f1boEWu: 1.00000000 BTC
        └── 17we51GMWBEgRhoXJVydDSHa91SFTgdkuG: 1.00000000 BTC
        └── 1D4CwcfWCeJbNo3icbW2asLs4fy2Dp2QSA: 1.00000000 BTC
        └── 1NcnwLzRXKwYezBqvc1RUYFo7yTxC1tQbH: 1.00000000 BTC
        └── 1HG3n6wg3kKUsfeWpAJgE7LytB4T9kLca4: 1.00000000 BTC
        └── 16RN7RXwjsw5wnLtYfgegWaa9RxNXvcVnr: 1.00000000 BTC
        └── 18oE9RbrBmAQemY5J2fMPM7Xyc5MMMAEMo: 1.00000000 BTC
        └── 1A7urLN9Cch8dzBEa45Q71ZL9LUYmq8sPn: 1.00000000 BTC
        └── 1NXar17mxbgzcEmNNiZkKzdD84QVtQk4mT: 1.00000000 BTC
        └── 19QdT6XYsFwMGvm3cZ4neLF7CRYteVr3UX: 1.00000000 BTC
        └── 1F8WNHomqPJHFprvK4eUq2NV1cn3rLAEi4: 1.00000000 BTC
        └── 1FVWAnugRgGgBLsWFzQN7uutnGST2Wd7sQ: 1.00000000 BTC
        └── 1C9DRfENUTsoxszVXbxbtxgxHLbptwCpMQ: 1.00000000 BTC
        └── 1EL6tVPor2Rp2bAhEPGmwgteLBVvkQSWLh: 1.00000000 BTC
        └── 1JkKDN5z9JTUeXCkjj5qH7pfzvbufWFdek: 1.00000000 BTC
        └── 1FsiuiKXBc7vN5qLDVUS3VS3tzxjLxmzw3: 1.00000000 BTC
        └── 1CK1aRBs6g9gFu8FH21qNUh8omVzCH2ggj: 1.00000000 BTC
        └── 1MidwTnWBy1djGrhpgPYyvoDbowgTRF5m4: 1.00000000 BTC
        └── 1Mc5Vc1GK8D8ZcEYM5zzxxeAGgd2NmM5Ce: 1.00000000 BTC
        └── 12jGnrvKts9Hn568YmCyMZ7XiQoJZ1mYbC: 1.00000000 BTC
        └── 1NeaH21nu4uTECbgMB5jipZBSd3YGiT8i3: 1.00000000 BTC
        └── 1J1gu5aATcmFEYBbSij27UjQfDxwguxR8S: 1.00000000 BTC
        └── 1Jp7ih3D7nFKfGFMbUd7JQuRsr5Zm3yijy: 1.00000000 BTC
        └── 1BdXhbp2txKH7XJKcpaYFbb9Pk5SjVdSoD: 1.00000000 BTC
        └── 15PTEYHfm4ZvcnHXps1PH7iapujv5WjjFZ: 1.00000000 BTC
        └── 1HetKyeThQAVtFfqj2bTs5AgRHt32HYzVN: 1.00000000 BTC
        └── 1L7pUvxVYskFx2Tyuo1smExNVyxGG9csTS: 1.00000000 BTC
        └── 11iaPD87dD2KdJPBm7fL4u9JUx48vR9Mg: 1.00000000 BTC
        └── 16o37mKF3wzDca5rWUZrNJ9BAz4B3RbZZs: 1.00000000 BTC
        └── 1F9tP9cpYxsbJH5B15Emrzzsv1mGRHBDeb: 1.00000000 BTC
        └── 15TQmUBG3PVPtHZPuxCwmaE4bTNfKxfQAv: 1.00000000 BTC
        └── 1JksfLRNS9qxbwjCFWYoQko1q2WL7pi3iL: 1.00000000 BTC
        └── 1AkSGB4EZAmbEyQSXN99enreEseR94km2c: 20.00000000 BTC
        └── 161kUKZdFb3mcrCB3ZX43ZDDACiWvDfwc8: 20.00000000 BTC
        └── 1Ft7Ke7T3nDQp7Uq69oLt8FRaRFnGU7erw: 20.00000000 BTC
        └── 1K5LyFjFfYqCnkF6AoFmSWCNMNLMfywte: 20.00000000 BTC
        └── 132LFefLrecHn6epx5DN6AnLBbvyjnyNJH: 5.00000000 BTC
        └── 1CmTxoFiB7iDR5gQDC7MXkx6Byc6fD2mWd: 5.00000000 BTC
        └── 14gdDrghpN9uPV9vhRs2R2hm555uUtb69P: 5.00000000 BTC
        └── 1LkgUDEvmyAVw2RrXyE5vw6eLyXah5An4Z: 5.00000000 BTC
        └── 1D7dybK4p6gzda479AoTHB8fBr4WUHUHWj: 5.00000000 BTC
        └── 1BGXKZ4aiPXaWLid4XhPVPUt4LJxk1LVNd: 5.00000000 BTC
        └── 1BCmwDD4D881cJzios91RYcAvitFCNa2X8: 5.00000000 BTC
        └── 1BgHGM8ESemiLuE4LgBAborbjCrfH8h6Y8: 5.00000000 BTC
        └── 1FAkm7SArhSmnfwJeaYvsG28RZy6aivzan: 5.00000000 BTC
        └── 1JtxsmnnqsDzgbtWZwiZNPToM99Pjq6qxi: 5.00000000 BTC
        └── 13cdmkTeYqmtwG42Jc19jbxa66eEnJX53T: 5.00000000 BTC
        └── 1Lmm1yiDu2VnNQZmZKSvMXCBXez3ZqKkZ7: 5.00000000 BTC
        └── 176Lebg6YzTVDdCTSPhvonNFygmDDBHVW2: 5.00000000 BTC
        └── 1AbQmyCXbUQYx9SG2zPpq1RGaG1abSLbno: 5.00000000 BTC
        └── 1HkkDxdU7JxqtUhgBxu5sKWq5KkZLpJLbh: 5.00000000 BTC
        └── 1JoPTAhoCaG9ewbW7xs8eiffwQdFVXi7np: 5.00000000 BTC
        └── 1CnDeCLcgXMesjEkmRWcJHnyNrqUXCA55C: 5.00000000 BTC
        └── 1DmtcCvmkVqYj116kXQVd3zWKGsi587znt: 5.00000000 BTC
        └── 661c4f738aab05dc57030814dec5b581793967c5a21b845c4ed9ef3dbf3030a3
        └── 16DK8VwwHdGZMUTnokTMRXrxuj1y2KsVF6: 1.00000000 BTC
        └── 1NpcLuQvux8AaerkHtGWNF9iaKtYcUpqBY: 1.00000000 BTC
        └── 1Y8UyLdFqZW5wtee3t2CjSzcqqGFAneSP: 1.00000000 BTC
        └── 1FChmZZzrzs1LtqaLtt6hEV1EpGAdb2UGq: 1.00000000 BTC
        └── 17jzzKVzEuAR3dWVAhXhwtgd9NPaVzanpt: 1.00000000 BTC
        └── 1JVLbdhPBWSf7oqwqZZzRupBSaTCLjLDGK: 1.00000000 BTC
        └── 1CoUDiVJCwgQ9gtDKCdTNsNnLyT6iS9Ghy: 1.00000000 BTC
        └── 1F9iRC3AcDtefmmUqbXLa8DtXSpkwJVQTy: 1.00000000 BTC
        └── 1PvWGyaaeSwVvDGRY1qK2jcx4d1GwnztPv: 1.00000000 BTC
        └── 1Pj1SVcCr2CMLf7g8fvEVXZRY16i79T8jp: 1.00000000 BTC
        └── 1C18WZGx76zEqVKmehsShX4FfLTnD4Dc1H: 1.00000000 BTC
        └── 1EYrv7mzmo6ujRE2TfGyo6QYNoHrHnVdSy: 1.00000000 BTC
        └── 18mA6ZExhU57JNYi8KxMCuwxGCE2BLHU8X: 1.00000000 BTC
        └── 1D4tKZoTbxXn2Mps2Ei9GEzS8aB2mY4rbJ: 1.00000000 BTC
        └── 1JbbSWppx9JVWrecgZ6oe5eiAN6x3Pafwg: 1.00000000 BTC
        └── 17yPZ6xQP1PZsbwU4iKydnBLXVLtwDcfVK: 1.00000000 BTC
        └── 1J1qgUfkp2YNynq4gEG219wUsqEtrxBw44: 1.00000000 BTC
        └── 1BRskJdCLB2iyTZaZKEUzMm11E4xfdYRVU: 1.00000000 BTC
        └── 19yvQuKYc4tYfa9rjmVrTob3S8tsG2oz3H: 1.00000000 BTC
        └── 1NLyh94bdEahVFXuu4pZP6bU5KiM4U39jX: 1.00000000 BTC
        └── 1DsJwZuTJSCqg5uroYKwQmAccfXWAmJeY9: 1.00000000 BTC
        └── 13YHMksJxQV43YXB98cZ29Q3X1vyeWW5m6: 1.00000000 BTC
        └── 17jenHkzeLuPZJeCHr5Gqh1CX6Euv3DAfj: 1.00000000 BTC
        └── 19FUG7YadWbfBcTu2oqVA9tmcaNZDvsnGd: 1.00000000 BTC
        └── 1BG5Hv7p3a7bJCNzuyp4XYGeQZLm1q938v: 1.00000000 BTC
        └── 1AwzNVir6b5T2EdMhp8FvVMkz8ZR1im6wQ: 1.00000000 BTC
        └── 1DP74UTsr9JcXADbXe9amKYwUa2dRfFJTC: 1.00000000 BTC
        └── 15GpwyKMe9nvRKdjTCYCUUMdKvnRYTJN2N: 1.00000000 BTC
        └── 17Vv6bzjnPsaFfZHc3EggJYG1JwwtZ8gob: 1.00000000 BTC
        └── 1LLaYeXYLZivP33zpQ1V7zVCe1ZRRoL2FD: 1.00000000 BTC
        └── 1FZBb4drE4rZt2Y19h6ae7amhZUtbrFqRH: 1.00000000 BTC
        └── 19qDHTrQcrGK6zoJJmbZcTX2NR5eDsptLN: 1.00000000 BTC
        └── 1HCpkGwJ49sZ61ZgxkPE9X9UwBR7GYPQsg: 1.00000000 BTC
        └── 1P5gyVJ3qLLQrPLfCPDTxrNrVvjY6Gm1wS: 1.00000000 BTC
        └── 1JJQWJar9ZbhgiAoLsJf8Rd9aJeLoqaq7X: 1.00000000 BTC
        └── 1MAuMnSDZRM2tjQcVYNUnX2nz511nNFMB4: 1.00000000 BTC
        └── 1N3zwDKnMFWzcPLSxZBvd4BuBP9uWiFF3H: 1.00000000 BTC
        └── 1CTMQj9J6yUF9VNBs4uUddkfdhsANVAj6D: 1.00000000 BTC
        └── 19rbyy4VTwEu3emYj6Ghmeiisny9SHyvPi: 1.00000000 BTC
        └── 17dhFngG6TyJ2rM8jnRoVXruDbHStThdkY: 1.00000000 BTC
        └── 19udbZ7337QmVoMc2qntbvTB3CcuBQtfaK: 1.00000000 BTC
        └── 16MCFX9VkZwNcJLH5uKztyboeyJbrnj3FJ: 1.00000000 BTC
        └── 1GKAt9NUnPZNpNw8UiYY4bfAdUrH1GYZiJ: 1.00000000 BTC
        └── 1CeEGU9YHrF5xLdoSbWHdNDd5Lvj5g2fy5: 1.00000000 BTC
        └── 1EyAdyv6zxmEhnASMGwwkKxfKmXCZFWR6P: 1.00000000 BTC
        └── 176igCu3zN3LgSMJc3K29hiGNs4QZxt3GK: 1.00000000 BTC
        └── 112jfSyLN5NxkSKrBcVfe3xKXeXGEAEXFF: 1.00000000 BTC
        └── 1PxNAcHf5vWUG4PMMYJu7WBpFDq2bmKeER: 1.00000000 BTC
        └── 1BZRjosYJTJGXkh4pb4dUcf3HUgWiHFpiv: 1.00000000 BTC
        └── 1QEk8SCapWttMxSjes5gWm3MtL3MSZcSAN: 1.00000000 BTC
        └── 1NWLRh3gffC7vJFvg61ivvZnnn1fhofNsX: 1.00000000 BTC
        └── 12pyULyrLXBirrCBLMRuaenTZ4Rz9VrLAZ: 1.00000000 BTC
        └── 1NLrPLdMXV765WYPHBZ6it63MS6SkMWQcM: 1.00000000 BTC
        └── 1ARkb11x5qj32dPnWaQhf9sacyLy6GKgS8: 1.00000000 BTC
        └── 17jsMDRqd6WkyxUvmcFvKihLFT7yC9hbuY: 1.00000000 BTC
        └── 18bVAtF7VsW81HSMJqDGv52A1oouVTrx3H: 1.00000000 BTC
        └── 13afbDdkBpMD5vNwzc6SgLdtDrUiYUCSCM: 1.00000000 BTC
        └── 19exe96qyvGoSYdfr4dFdWGQTTjaTs9N8v: 1.00000000 BTC
        └── 1ELv6ooKax7n68xRKvu4tAo1aAa4YUzC6r: 1.00000000 BTC
        └── 1KrxCsjaJzGT9dZ49JnVbQ6M8vnaRgJnPz: 1.00000000 BTC
        └── 1G3sQjsQJ7P736JYX9iWTM2cqsKTv1DLnG: 1.00000000 BTC
        └── 1BKtPB3fuNs9fDBitruAm1tY5m1mA3U7Vo: 1.00000000 BTC
        └── 19dw5aWMVf2W2WVQ8L1g1r55LATQdTVuax: 1.00000000 BTC
        └── 1NmhZCNsVXeAUxQoLhcMxE1hoqJF4SCsKi: 1.00000000 BTC
        └── 1MEuqpmMQVW7Yxj84zQRN8Ths2KiTH9yQd: 1.00000000 BTC
        └── 187N4s3fbgRGSYjimj4HcDLgpQwhyvLR3Y: 1.00000000 BTC
        └── 1FqsfHyERuJu9Mn7TtYvkKhvkrLurfxYTC: 1.00000000 BTC
        └── 1LvtbthdoQkr3cvuXxthwPMLfT8pKsf7a9: 1.00000000 BTC
        └── 1Aogs4DyjfQVQCNBTGQXD8thbAErinSELr: 1.00000000 BTC
        └── 1Bbpr19LQYtVZ9biPGkA8wTPsgcz9cDiA7: 1.00000000 BTC
        └── 1srLft5Bad6trVTQvKprgYW2oCMygoc1z: 1.00000000 BTC
        └── 19xednLgLR4otQbTexgmpiAf9pPeR3pj68: 1.00000000 BTC
        └── 126y22B1acn2SKQZqDPjTxdZALSyiUQynT: 1.00000000 BTC
        └── 16uQLXnCwmCzQagz2CN8pNp9kzddibiW1X: 1.00000000 BTC
        └── 1GHcrzTtRdxqhA9vsN17GxSoTD6fNez223: 1.00000000 BTC
        └── 1K9jZMBuzM2moHACTnm92SywgYh6Dr6gSv: 1.00000000 BTC
        └── 15XbNHudosM26kUF2Tm8RfgHQaUSzRdDeQ: 1.00000000 BTC
        └── 1BggezMH5NH9nUg72osJCuDcBgT3xGaVgT: 1.00000000 BTC
        └── 1MkN8p21AszJVmWyqF2HhvP5mRMxRJPRxC: 1.00000000 BTC
        └── 17v9h1iYKSxggnnwfVJhMVCeVaecEycrZ3: 1.00000000 BTC
        └── 14afdXd5YfqxiyzQeN4sgMw7dVUw9P3Tpn: 1.00000000 BTC
        └── 1BV8Jri21edjN7UmHiKpqqUwTkH5YzcURK: 1.00000000 BTC
        └── 18c8WMw8nsodSVemLk38HrrzugUNybJCva: 1.00000000 BTC
        └── 1FaTPo93jPArCXmteAt6igykVeXKsmy6Xn: 1.00000000 BTC
        └── 12hbAnastn7CTRR2bKys9mtzp56eFmv6JR: 204.00000000 BTC
        12hbAnastn7CTRR2bKys9mtzp56eFmv6JR
        └── c262797f2d7c790db63a4e5ce4b4bb2a511de2c0e1516dd6d7b6b6f0c749f5ea
        └── 1AJvoQz47csmbUZGepV8g7BzniDKsuW2Xq: 20.00000000 BTC
        └── 1KMoQJkzURCwLr3FGDRNegoBXXnw3s71rT: 20.00000000 BTC
        └── 19jSVkc3CimckabiNtzmS3nmST628UVs1Y: 20.00000000 BTC
        └── 13oAMWVYYiyPV6cAixESxntsSETncM59Ld: 20.00000000 BTC
        └── 17tScceuAxJN7gaRN9LLkrawfQody6sgBX: 20.00000000 BTC
        └── 1PmC2f6sJv3xPbgZym8Tp9y1sTtiPCyGLp: 20.00000000 BTC
        └── 13xbLwBrHHGwaUqtKqVm1b3qR6pqBsSmzX: 20.00000000 BTC
        └── 1Pr18hVk4UZhipzFhoRhbETCAsdggiGgyd: 20.00000000 BTC
        └── 13DQkdcd2pU6MhcbioPYagDLRtzy5rWWhW: 20.00000000 BTC
        └── 14Pb6g4jxmbFKHTF4yb78tTjdjDYck2pAM: 13.96000000 BTC
        14Pb6g4jxmbFKHTF4yb78tTjdjDYck2pAM
        └── 69a39eb32d93639537e6f3321fd60e608225272699a09dad5f511f38139bd6fb&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
        └── 12CzE7JZPvS5Vukvo9aabKTBChtggWSVXw: 20.00000000 BTC
        └── 1JCiTRbkgniVbqbeWHtRPg1H3SCCVXrd9X: 20.00000000 BTC
        └── 17SwYcujbxiwmL6GvGD2xamzCppodhuFBS: 20.00000000 BTC
        └── 12QSpHcM8ZWVaKkRvL1Jc1h7zoQoWL2TTp: 20.00000000 BTC
        └── 1J1GvAXaNN5EKatKPx86qq4YngbA9Ya55T: 20.00000000 BTC
        └── 19kCNtz6Nq6rcG19uEpmBRcMwEBTScDicR: 20.00000000 BTC
        └── 1C6Ne9ACY3zFwXBXymYx4mja1oPxKGgbDn: 20.00000000 BTC
        └── 1LX2391AmPrG4tWQTpAZEsRfKu8NLputwZ: 20.00000000 BTC
        └── 1HJ3Px3YFTPZdJge7rRoXdZXRbKPtT8aZC: 20.00000000 BTC
        └── 1242jTyzbB5Z9DnQvttWz9KfJoYyeopaz4: 20.00000000 BTC
        └── 14WQKkQFwzxVMHYx2M2Q3VZRb516SS4dzp: 20.00000000 BTC
        └── 1JBrjjq8dc6b1hveUTLdYWWfiHsfjpsxSE: 20.00000000 BTC
        └── 1CnRCtjajUp6JoB6cYyFjumYv8UgaLiGG2: 20.00000000 BTC
        └── 1MgATq9ZcFM4YtQ7nR1KmPHefoEEkrLdgK: 20.00000000 BTC
        └── 168F8dckWDrBtV6NA3YynMJHz5HLpcFhEt: 20.00000000 BTC
        └── 16hdkmqWPYPgRTFhsaPgRRyiK62jy4H4Uw: 20.00000000 BTC
        └── 1JsgJ5CypEySGRYrkd4oJJCjwmn1faPsyh: 20.00000000 BTC
        └── 14Z5PVYeEEJPfaWNiez47Z9e5reB5xATnS: 20.00000000 BTC
        └── 1A2iVM9HAEEgz1kJ1885AYgBhR27zigcCn: 20.00000000 BTC
        └── 1Hf2xkDqMdghVM8YsfzfHoNnvoHVfqyCnC: 20.00000000 BTC
        └── 18dCiZ44qicPMmi1eoygpHqCPUWQfxQwsG: 20.00000000 BTC
        └── 1EzPchRJwD3dxb2grqufpxMLDSiboLjfCy: 20.00000000 BTC
        └── 13jHwvmnXGPqwP39ue5N7fnDcL8moSBnbA: 20.00000000 BTC
        └── 1Lf4oF4LzrNUsvSoBnnQjLoua5LteK3QiK: 20.00000000 BTC
        └── 1BZHicKhKtM32jJsL6dUi16Jgmhke2z22T: 20.00000000 BTC
        └── 19DtvmRWU7MuwyH4aJwMeNr8bjVmbfcoZR: 20.00000000 BTC
        └── 1FoicoWyw7d9smxWEuVUNXwuUmEENfsXr6: 20.00000000 BTC
        └── 1Daz36oMvzTfaKKHynzs6tFDGbK2vecqp9: 20.00000000 BTC
        └── 1h6tSi7H1wgCP3ogBKPxESwejaxjBG7Tq: 20.00000000 BTC
        └── 1NKAhZhfXqzWkoL83Rfvcci7Nqzwi9GEQc: 20.00000000 BTC
        └── 1K9QXxYkvFiGkh7xmFsCvoTf9FizVzwBwJ: 20.00000000 BTC
        └── 1FpcmNVxnVHdXahWBtndCtH3jBAmVDGoAT: 20.00000000 BTC
        └── 1FsFioeNXT1iTNxnCFyRS598jhbwsUEQou: 20.00000000 BTC
        └── 16C1JmEFf6Bc69B9SujmgLrUaUJXqnRH6v: 20.00000000 BTC
        └── 18DMyfRuhyezH3twKC6BzYUdL248NpFUp7: 20.00000000 BTC
        └── 19fRGerVg965RVxqYD86FcWRVW5xuCnWte: 20.00000000 BTC
        └── 1D5fJbaztBXYMzDfgPfPCKRaZ22Fm5T8oW: 20.00000000 BTC
        └── 167dnNtjeZMKeyJWHZWHUKd5R2Mkfm8hsc: 20.00000000 BTC
        └── 1AHgGcw8LjzhsRKtKxjvyRSUSAnkcAEMjX: 20.00000000 BTC
        └── 1EFMZDCXBMR7qbEh1rWGPBhe9TyPbcEWa6: 20.00000000 BTC
        └── 18vN7swMVLgfcBbexWNiYZCGthFBp4vaqe: 20.00000000 BTC
        └── 15ZFyCSTpfVNNSkuTsPaPkVBteJLovwFQT: 20.00000000 BTC
        └── 1AAqdgbF1dEdA5Lu9gKxjn3zNmn9wNFJzL: 1.00000000 BTC
        └── 1H7iBebgYYczw8h3aiSKx4VpCMviySkdvS: 1.00000000 BTC
        └── 19vAZ8ZkHaSHF2rYtc5aHb52w7CLXpcQoQ: 1.00000000 BTC
        └── 1FMzsCQJSBxJFH6EnbWKhATB1zPE59dpQ6: 1.00000000 BTC
        └── 1LtUFKrqx1JpTKYM1VfzYsjQujxunNtZwV: 1.00000000 BTC
        └── 1EsU1FkWjjAYaGiqz1iRC3KwqmbDXb5mPb: 1.00000000 BTC
        └── 124Ai4MQxY1rg4dLq3zK56gZkaweBCqFHn: 1.00000000 BTC
        └── 1Ga73i2kpWScJgA7gwyx9YZHMwrrPCVKVx: 1.00000000 BTC
        └── 14Ya2HmVEUgwo87c6bxjqwMktiXf7KiLsD: 1.00000000 BTC
        └── 1FgmmkHRVs6BjuPKMZFDccHNN4LsoYMTsG: 1.00000000 BTC
        └── 1CgKDtMjqov8UWL772ePsrhMxQKynomS3p: 1.00000000 BTC
        └── 1PjdhGjwMrdBG66qoWP5FArCt5om6BaLsB: 1.00000000 BTC
        └── e912b3a38015b72a38c43e158f78940818908164f988c81bc98f94d7e106fc76
        └── 17Dc5TeRe2hSTxgFgWX12NScoNg8rAG7dU: 1.00000000 BTC
        └── 1FWmKyRmBqruNgibDujZufkspeHAN2wQZg: 1.00000000 BTC
        └── 16AzRekFURWciL82Fkn5jYYsLMhxykD5NN: 1.00000000 BTC
        └── 1oUvsfzGBQtxCsDstDzqxdR8Wos8QBoM4: 1.00000000 BTC
        └── 1J8CMme5cmKxuhyeUtJ99wB77AUKRXQsDo: 1.00000000 BTC
        └── 17GgKqfUp84127RPNpYg77KoEgUkzdoBtr: 1.00000000 BTC
        └── 1LehBy5PUWWMurx2nALzb4R1VZqvh2m3XX: 1.00000000 BTC
        └── 197G8pnCTGrJkd5dZdMmkVicspd8z2W14y: 1.00000000 BTC
        └── 1CYG2bs6xVXwRasqwEjL8yTB5Bcw1BzpDb: 1.00000000 BTC
        └── 1Cd9i8yboDhPC6Kv83S5ULcYLYmqU7csed: 1.00000000 BTC
        └── 15hAG5TGS4XQiPsLfsnfnJ76xwpyeKuCk8: 1.00000000 BTC
        └── 15zSucU9CU95FK9rjfqNsgSDg5JMWp4xrU: 1.00000000 BTC
        └── 1EegdruSUYz7k61iR4EGWnRXMYNaYVFmBY: 1.00000000 BTC
        └── 1A3WqrfV9Zp2YdyBMPufrtiaybbG9mg7ye: 1.00000000 BTC
        └── 13HEpi6G2te1jx3y3kSRyEzHNhRDAoPR2x: 1.00000000 BTC
        └── 1ARTz8V6naLH7GatrU2Ac6VgZo9Qf5bwDL: 1.00000000 BTC
        └── 1K8ajkCqUZVGNeoynQYB3jDGCvEA2joRBp: 1.00000000 BTC
        └── 1DYZ4LurQ4vrsUedqQ7Ea9As8scc9TA5PA: 1.00000000 BTC
        └── 19LoS4xSAHkViS1B6eRgAKv1g7RW8TbWTK: 1.00000000 BTC
        └── 1JspJikNPyUgiBemKs7xdVAKPcWQA8LNEn: 1.00000000 BTC
        └── 1KgLQsoLwYHZTLhWpQFzDdFY2yJ657KyGY: 1.00000000 BTC
        └── 1LZbdubnNRswUCTg7HXzXB6yj8xa7dg2md: 1.00000000 BTC
        └── 16JGAY49MAf6QYkHAxhZK3v3joe7XpTTQU: 1.00000000 BTC
        └── 16nLqbMTstts8gupT9PfQkza3qRKRGgaPV: 1.00000000 BTC
        └── 19Mrf83EWGetcEmnqmrpNaS63tDfWrbRkT: 1.00000000 BTC
        └── 1BAsPCPXpbo7VMMxrbRGt9KP4qTgL7sQqo: 1.00000000 BTC
        └── 1Du4p2qX9Qjh7LyjKAE5dmBFs5STY7wofb: 1.00000000 BTC
        └── 1N34Ab4nViAuLrZutkX1agJmPmMrDpRC8u: 1.00000000 BTC
        └── 1GiyuBa2AdeRqfJ8fZyN59J98F3wr6sAp3: 1.00000000 BTC
        └── 1Lgm87NDqUh3di4etWCMtKBxXvDB1amBBG: 1.00000000 BTC
        └── 19ZsXQANqS3pTmiRkV8mcG527C5XPmviB5: 1.00000000 BTC
        └── 1EfnZnmfPLMwF8z7RJ1LK7ts7MakiC4b92: 1.00000000 BTC
        └── 12idtys9GpQetfkT49XSdwav3vdoLCDTLr: 1.00000000 BTC
        └── 1CQgyK7YCa5V9TBiy8tRwjfxsdaCkxmA5U: 1.00000000 BTC
        └── 1FgNoCz2Qry7i7WY181b3AUxjset9ZzxH7: 1.00000000 BTC
        └── 1HYAGxHrceXy9TeY8meLdzBpcLgnxDTG7w: 1.00000000 BTC
        └── 1oYfis9tJMUaujfQLoGASmHCpdcexX8xo: 1.00000000 BTC
        └── 1EBBwkXikPbh7uXwJiXEd5AfK5Y4SYd5Np: 1.00000000 BTC
        └── 1Pgbwh8Nvncoqpkr794j6vHsG3wbFePRPR: 1.00000000 BTC
        └── 1BoHTGE5krZuiRMoEwVPt6V4e7CrcYEy6q: 1.00000000 BTC
        └── 1EX3Nyzsa6rs5yxv7UKbVTCqDqp766NHVd: 1.00000000 BTC
        └── 1Q6D2wAfi5yaqxEhr1QYPbkkwrrozj582t: 1.00000000 BTC
        └── 1MVddnLoqc8K7MdnpDjHPCyVUkeencJEUy: 1.00000000 BTC
        └── 1BWeSBVChv5ZtMLvLEfwHiAdu1KZXcX5dV: 1.00000000 BTC
        └── 16bWeyhKQg4SdY8XpfWtCdMRLjp4E9XqYJ: 1.00000000 BTC
        └── 1AquZ68eFQVVfPjFMcALXjpqSGPZbidXXB: 1.00000000 BTC
        └── 1Q49e1Aw4K7AdCr6vzewsPcWbbMC9CTPgt: 1.00000000 BTC
        └── 1vJmruesm6WyVEeheCEX1dTNFjiFo14Ww: 1.00000000 BTC
        └── 14nwhmt3dtUUYbfMxuWbuvUe5wz1xZJeRW: 1.00000000 BTC
        └── 16BYXSPvmV1rAZniiAuagAw9Pbqi4VtTbQ: 1.00000000 BTC
        └── 13uout8HEnCxoFPXiUKqexXNZvxNZVmAH6: 1.00000000 BTC
        └── 1AsYSxYP6PqpL9qhp8F7Tj35MKNNsjwBZA: 1.00000000 BTC
        └── 1MSBoFQPq1qARQCxbLXmWVho9Yxe5hz65m: 1.00000000 BTC
        └── 17VUn7QwqdcxA37QSk6MLrZfdMAS5Y2H4S: 1.00000000 BTC
        └── 1DTMuPhm74D9o4ERSjWcbCcnYpn1EFNuyN: 1.00000000 BTC
        └── 1M6gr69GUm1paDHwe1rW9EstKvhUrsC49N: 1.00000000 BTC
        └── 1Du9RTMtaWDrWWdndzFdwgWkUFEDSY1gzd: 1.00000000 BTC
        └── 1JZf3NsC4tfsi2UQvTzW2rDxjbSt7Ro4BA: 1.00000000 BTC
        └── 1K9zX4K6vANJe6uBBUNMLHELDiNpkXfYLd: 1.00000000 BTC
        └── 14x3z2UjJ6nkDY7BtstyQqWzYsibJkQkX3: 1.00000000 BTC
        └── 1GEn7Mha7mG7z9GHhJw5ipeUQCGFQJKKKq: 1.00000000 BTC
        └── 1Cip9DFjwarbJQGJEREhh9rk3pQhGBv4L9: 1.00000000 BTC
        └── 1Hbr46BDoqznevaPsWAtUpEkK6jS4CxoSR: 1.00000000 BTC
        └── 16gUffoRLAmFQRMHfRFQ9qkcgBUkyGANEV: 1.00000000 BTC
        └── 121kyuMYPKRCmPBbssiP74vmNNKUKcVhxw: 1.00000000 BTC
        └── 13PCUAxTwGmpB7vdiHAdtEDJ6o5VKCnqcP: 1.00000000 BTC
        └── 1E3pNqjFcXRFQ4XD2g3G7GWXXb9BVL9rSE: 1.00000000 BTC
        └── 1Ept7MknRxC2LaT6F3QcvqJ6kGgQTxhGRS: 1.00000000 BTC
        └── 1ADoTNYq7BF5ePMZJw5Jnw2H2qf6er8TAd: 1.00000000 BTC
        └── 1Ccsr6hiWWh8HtfqafnQkRqmHcDNnMgU2K: 1.00000000 BTC
        └── 1Knu7CELYTk6Rt9Powm39YNnrL34PhfLRz: 1.00000000 BTC
        └── 1664Mg1oFShN5ksEYWFjHMRa9nHdCWyesY: 1.00000000 BTC
        └── 1MBK4Hyoxgk1pQJz4XJp8s5JMR5A7x7zpg: 1.00000000 BTC
        └── 17rRUzB27fEhQQLdBjvLSQZRJSATa41UbC: 1.00000000 BTC
        └── 13QvHzFizRgoGP8jQXNMb1FS3XQu4vcYQt: 1.00000000 BTC
        └── 1GZYT3whPiJohehg2Q6CEWeLFyM4Gmoh9n: 1.00000000 BTC
        └── 19XFbTZ2K3JEW2y9GFbeLyikfaKtEUNTds: 233.99700000 BTC
        19XFbTZ2K3JEW2y9GFbeLyikfaKtEUNTds
        └── 69a39eb32d93639537e6f3321fd60e608225272699a09dad5f511f38139bd6fb&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
        └── 13PXaaW9yZqE7wesZYYMqnx4tHbB2KxjGi: 1.00000000 BTC
        └── 126jRsxFerQiWA5GhmATZjqhojwkRcRc6S: 1.00000000 BTC
        └── 1JVy4DoYQW9JNjNDMLWvrCGH5ZaZn6XjXC: 1.00000000 BTC
        └── 1NA1HY3qMvhaPcZ9cLUCqtcBPsSdkfHfGC: 1.00000000 BTC
        └── 18UMqMaZz3YHXUzuYWvaNKv29g6GFLb4V4: 1.00000000 BTC
        └── 1BbMCKydGe1kbaFJpKzZWG54Zvnv5rr7ad: 1.00000000 BTC
        └── 1D9AsegCs68DmVxFx3tzfARDzQhEgVyFcV: 1.00000000 BTC
        └── 1M8uGvfbirE4YGctTAQsuh51yV6LH9dyom: 1.00000000 BTC
        └── 19wMmy8NkVYyUmVL1hGSQnJhu7fa39NG7W: 1.00000000 BTC
        └── 1PvHf31kY9EPhDxi9gGGGG1vyo2NttB3hC: 1.00000000 BTC
        └── 18k74WJGV4MpihLmR7EN7JL44F2n4vYwUv: 1.00000000 BTC
        └── 1AH9imHhiiyahNyLdhnDk3rr9dhDenaTT3: 1.00000000 BTC
        └── 1PzbHnWgibFyQs4M5HaUMsWkL24HsrUnFM: 1.00000000 BTC
        └── 1F6QfciSkNntX9ajqpEAwXqP66YUa84Gzw: 1.00000000 BTC
        └── 18zSs2Z1kksBzvKJ4CD31RxrWBq5dEbYHM: 1.00000000 BTC
        └── 146J1XZ2ijPT7MxiYiLr8cnUT3PYuC8zTa: 1.00000000 BTC
        └── 1JShCtN5KdvRCWjg5Yt1w13gmXb1ap2P2S: 1.00000000 BTC
        └── 1LKisiMowZN7nvGaFsjwKjJH3KcNwPEwpS: 1.00000000 BTC
        └── 1JDAR5KZJezd39knvYAbdAeg6aAQgjdPzr: 1.00000000 BTC
        └── 14bEcpGrqhr8XbJ1LDaFFT8KADPUrqNb8z: 1.00000000 BTC
        └── 18sRJBMSmQ5umnufGgjavFUYAcqZTC4KQb: 1.00000000 BTC
        └── 1D7SQ9RfJhhkbanJBpMdTfzNVEWrNyH1zp: 1.00000000 BTC
        └── 1iqKgxHunryvcTq8yp2CBJc4CnV91LHHj: 1.00000000 BTC
        └── 1gQGbFjupurdhycTDen4AJwen4mWjKj8R: 1.00000000 BTC
        └── 1EX5nYBCh5LLDszkciPVTf9gKp71tvE4T8: 1.00000000 BTC
        └── 1FQYKDpYoAdyYMSajGWn9qdDseFqx69RTc: 1.00000000 BTC
        └── 1MWpCn1QYBvezTqLBH3FSoF3HNhuRQWG5J: 1.00000000 BTC
        └── 1GxmjhEsgL76xT5JPWRVEcK2Ba9texGuq1: 1.00000000 BTC
        └── 13W8WrzGtyKHkvMjBREMfunH9sb7v3J9Tv: 1.00000000 BTC
        └── 1Mq9LbuVEsCyPaiH6ETyEv57F7V9S1SYbV: 1.00000000 BTC
        └── 1KHLKWfuAmb2xFUKi2QQq5h4cMVRRYnuP6: 1.00000000 BTC
        └── 1JP9hRN8eJ5VCGp4S48qEpEZC2Fie1PfXt: 1.00000000 BTC
        └── 15S4uYpV6kwAHwiF5QC99x2kpSQZK8G1r6: 1.00000000 BTC
        └── 1Lb8X1PrDio99ZuNEvNAeQVsYr9Z1f5DTz: 1.00000000 BTC
        └── 1DFuM5M5DsENJwFdn7t4QEVuTHKLhvh5Cx: 1.00000000 BTC
        └── 1CVytN3qrQJ4uKaZcA793AWt5Yg3tafaEm: 1.00000000 BTC
        └── 1CkLtm2si3m9CWLax8KqvBHMkk3tMX49SP: 1.00000000 BTC
        └── 1DK4ErGF8Quf9dviW8FiFByCYbV4QUnbfB: 1.00000000 BTC
        └── 15T6hsNavNXLuZfNhFymsAvBh7PpeoDk7q: 1.00000000 BTC
        └── 123HbKmuHLqvA6U8xJxvyueuZS9LbqBcQ3: 1.00000000 BTC
        └── 1MdLfjZNX9HTJH9bfvexxWYBapqmC2FwUW: 1.00000000 BTC
        └── 1LP29fDMK8mjvbL1zriubmAicg3TaLEaZn: 1.00000000 BTC
        └── 14MunRHFZMwaLJf2zfUtcz8jFHPY7MJY8z: 1.00000000 BTC
        └── 1EfjzEoKYp91koXBY8MazraUcapy9mRpLA: 1.00000000 BTC
        └── 1ETR1dHtPzBYMncpZqEa3k91c6DFk8bjjB: 1.00000000 BTC
        └── 1Pzhdc1NmR1GCmDT24DsePVjWbqBp7oxuw: 1.00000000 BTC
        └── 1RKcn4VBhrMTWYRJ7X75u9SwMqVNDEUaK: 1.00000000 BTC
        └── 1NSyVFa713xLd7copn4yxw8stSvHYoTruS: 1.00000000 BTC
        └── 19mSUtxqprdRFD2CpdrMURVWQDHVZcsCqY: 1.00000000 BTC
        └── 1PWKJ1MUFSuVL2WY9D3b1JS8ttB93SUNef: 1.00000000 BTC
        └── 1MTUJ2yU14io5PHpKVgKAfVvAStFxJcCVP: 1.00000000 BTC
        └── 1Jj4YWvwHetLs3jURYmQVpbqszcbZe1Amw: 1.00000000 BTC
        └── 1JBNJkLSJu7baWEwUEz6xWchr3AnqxhxBq: 1.00000000 BTC
        └── 1BZgPBo462xYUJUgfTubFBcxiZuJfAnHwn: 1.00000000 BTC
        └── 1DDBZT1Lm3q8APzNoamh2ybjTYbBT31qUp: 1.00000000 BTC
        └── 12LZqg93FBEjJuXLo4N8MouLXkSdYf4svS: 1.00000000 BTC
        └── 1M5CAcjeQV3bNKRncytbQFhEDGsNji5cFw: 1.00000000 BTC
        └── 1HEPNnqzaRSqWjqzFgFmLrVsxC4oNfVczy: 1.00000000 BTC
        └── 1D5MTWMPUNpxutNkqJTVamTmNqg5ueRP5m: 1.00000000 BTC
        └── 1PaQPZRU7jdpAzGzNGEgE6aZwWVfT79yjx: 1.00000000 BTC
        └── 1Q1rJCQ4ABTArewGhLE9TYqxuTAWoUssuZ: 1.00000000 BTC
        └── 1DrRg5Ck5ruVmNn8DXjj7SM4DstrKcKfgs: 1.00000000 BTC
        └── 15qMB9Rsqq2mdvELT6tBk8PV3LBjueYtWG: 1.00000000 BTC
        └── 1PiEHXEyB6nxxe6iXcjWiYMPw9yPr6iEZo: 1.00000000 BTC
        └── 1CoZnmsDzPvW9L6RByhV6fWrFSGFxNczcR: 1.00000000 BTC
        └── 88c5e1c51c66ff0e4048911eab494daa07938cf92fba3e972d79c5f3465aebd8&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
        └── 1ebd60c8ee1263501dde868e3856a484a2cae165412622e9882227d64411026d
        └── 1HFyaH3ZayeZrBX6yyU3xeQ9KA1JSTkHX9: 87.00000000 BTC
        1HFyaH3ZayeZrBX6yyU3xeQ9KA1JSTkHX9
        └── 3f6093819980e48688b6e375f646d3956a28749d8d4bcc41a597c6c8ec40778e
        └── 175X7AV6g9UhS8mTPnFTfjLmRAsyJXCVpp: 1.00000000 BTC
        └── 165DRG2beKZsnMdUXYFe1nU2Roi4T5nLu3: 1.00000000 BTC
        └── 1Nu2VpkU1TjzBXVbfvkL7mxDn6itUn4bY2: 1.00000000 BTC
        └── 15AcSLuvNq4vob3hZLyiCTiNX2gmNcgdM5: 1.00000000 BTC
        └── 19VGmDkmHWurCkNJ5Ref5XNF5NBTLnxGwQ: 1.00000000 BTC
        └── 1GqJNmnYrWXftryXVQbRN52Ar31BwHye6H: 1.00000000 BTC
        └── 16azYWxJyoQkjwDrGyMMnD1fo7L8QqjtHS: 1.00000000 BTC
        └── 1BXgaXqV1TKa9nyrHzCWUFarL4R2whvAKn: 1.00000000 BTC
        └── 1A8yLazWAbLTFVFZC8GbAkdvfMX7Qvqfe3: 1.00000000 BTC
        └── 1PYjQowtTYT5aFpnsV7RMaM6k2KxRCMFvV: 57.98000000 BTC
        1PYjQowtTYT5aFpnsV7RMaM6k2KxRCMFvV
        └── 5b7a35a7d2be184ad9932eeda5a7a4c9306c4e43dd70b813b3210e525ae18898
        └── 17U5dJA3Gz16rTtNjkusGeryEwgr7vR5y6: 1.00000000 BTC
        └── 1PDKMaeD9Rk2fW3GZiinkC6aEkoFrcDxB9: 1.00000000 BTC
        └── 13NPpoy24UaNBKFjqCRAv2KqkBCz1zDVVD: 1.00000000 BTC
        └── 12eYqyefcdBZqaYQn8wrjVB9r83KcXfDpr: 1.00000000 BTC
        └── 1GpHRwCfyFNSU2MDHcNNNERMfkU5juUAzs: 1.00000000 BTC
        └── 1KU6z6sz7mG1zDqVeDUrgMM8g8sMA3YKJr: 1.00000000 BTC
        └── 14Ajr3iUzYnTdUeoPpCcj8fCGShnv129KN: 1.00000000 BTC
        └── 18XLgmGUooA5BU4SSd19UetZxAgcQEhaVd: 1.00000000 BTC
        └── 15mKdbgxXfYKj1VUbWjBWqHycBBLEURmL3: 1.00000000 BTC
        └── 1MoLf13DeF1wLtFxJyvyRbTjqMSA9bTYBJ: 1.00000000 BTC
        └── 18odvGqtpsRh27xUxDND3qT7du7hMcS5it: 1.00000000 BTC
        └── 1ArmSvXJddmWW5RRNEqr8xSADFabzp2dZX: 1.00000000 BTC
        └── 13WEYe1sDpvngo47xTgdC2JZFDqJUSkzw7: 1.00000000 BTC
        └── 1Cz82b4whxQX5WqMY5UH6HWghwDisyVGVr: 1.00000000 BTC
        └── 1AydWTkfDjcd5MbJk5x5yHmuCRxwRqyCxu: 1.00000000 BTC
        └── 16yWjx2Uyuo8CYrHKiMb5iitn7akhPALha: 1.00000000 BTC
        └── 1NY7sZg2WwaXAoytJPgx4LjfiuuM3EZKz5: 1.00000000 BTC
        └── 1D6YbPQap17vmvxghWPNfBcuKfLjoz8Z94: 19.96000000 BTC
        1D6YbPQap17vmvxghWPNfBcuKfLjoz8Z94
        └── 4157853bf55daf4c57d6b5ee2ed27859afaf36ef38127cb92a43e4000797f4ff
        └── 16DgzFZiRQKyF6t5JxCDJP8yNmJfv9uZvu: 10.00000000 BTC
        └── 1PaqLwnrPEiuqS2YW5BuEWDFVYfgidfF2r: 10.00000000 BTC
        └── 1CiyaoDihaprxUBGuoxHm563qye1cDghfr: 10.00000000 BTC
        └── 1KFjntF7DEAT5CQiMqrQBFPbHv9seu6TjK: 10.00000000 BTC
        └── 1Fbq1HmzbweYrstLaFbM3dPsUKk1f5P1RE: 10.00000000 BTC
        └── 16NWDVLUyyv8X9zfp8KQVqnh16FAp3TRr4: 10.00000000 BTC
        └── 14WVyyU65THNHkkd9cARbwz78wnS4H99Wr: 10.00000000 BTC
        └── 1BNs3ghuT6JyCWfDQFAQ89Lebf8sxtMBU9: 0.91000000 BTC
        └── 1JUjbTHp4ki6LFPFHYtC8isdteku5N7ZSG: 10.00000000 BTC
        └── 14yaepF9jXpBvh6MkhpULjMLgUeLtTbBBZ: 10.00000000 BTC
        └── 1CtDMjnf9bdWgd3VNAMFLrArCnGNRMNr7d: 10.00000000 BTC
        └── 13rqdpRT8ELktdnRLVyVgmTAW8xZ8A79yV: 10.00000000 BTC
        └── 1PjKgQ5KydwzCnFVtjcr4GGuSC9KNJpucU: 10.00000000 BTC
        └── 163xmvguurRjyy3ZQrcgDsBN82vztxar8y: 10.00000000 BTC
        └── 14MBw3NH1M4Uw3dU2xJRT3BULSsvvSbXQH: 10.00000000 BTC
        └── 1PW2kYYULFFmEieu7RMbxb8Ee8ATSYQkGM: 10.00000000 BTC
        └── 1GrGyxLBzmRgv1pcfYAeTVMDyeWGKUNoJE: 10.00000000 BTC
        └── 1ACq3LQpEp6TmTRwDT3JgbocEWhoTZa2xK: 10.00000000 BTC
        └── 1EHSryS8EhFZizAWWst3SsKjsJUJVGpX3b: 10.00000000 BTC
        └── 1FRqpbosfGijiRtCVz7eVjQpJ31Bsdmeox: 1.00000000 BTC
        └── 18kjQxzYYkUHQ2UCU5uGZca3vXo4bczdT2: 1.00000000 BTC
        └── 1958wxWv5ZQsyzbLCLQWGdDv7YwjiFRyzJ: 1.00000000 BTC
        └── 1GDnSAhbaPPzB9mgid56ADaFr23B3Caeap: 1.00000000 BTC
        └── 1G51yix3MmSFwEzD77cJ6sLgVCoZQgS2nU: 1.00000000 BTC
        └── 1FygYZX2TXqmopRY2WETV1CBZPposoisTM: 1.00000000 BTC
        └── 1DkmN1TK5PgEzALXdBeB8kuWh5XuMHWj7j: 1.00000000 BTC
        └── 1HMDAJJZVYhHnjaXU7qgBcBMv2PfyW1qg2: 1.00000000 BTC
        └── 14PKy4pmxkmjwh2eFGXoWKrUJt5wnor2SP: 1.00000000 BTC
        └── 1AL7o5p9YzGULJHyVC1TA3BzZbGN7bVz8v: 1.00000000 BTC
        └── 1BLriV1zBsnpdiwhtPsaNcy48dw1e6vtNL: 1.00000000 BTC
        └── 1FQyyRYLpSECr365Y4KjTr7zaJQvVGNMTM: 1.00000000 BTC
        └── 1JKYAuZR1NxciUfugiB245ogUqdzjgxGND: 1.00000000 BTC
        └── 1G7wed81PN1wFeSvv4RTfFcb7LP9HruiGY: 1.00000000 BTC
        └── 1Pus867YQv7nwAoqewRtGXqhL9kBsv4RoR: 1.00000000 BTC
        └── 18y1ViTzLzRKopme4pcaCMR4MuG5bBwEtK: 1.00000000 BTC
        └── 1CiKeXdginbbDUmQPV5NrK6QZAoCAtVjvZ: 1.00000000 BTC
        └── 14VKEdUCBsce6x4UucJfGDq5r3Miqs16vb: 1.00000000 BTC
        └── 17R9oKvqR4NJhy5uYEppLnhrPUjpsg5mQ1: 1.00000000 BTC
        └── 1EXoxfEPbH2UrdFVpSihCd2DLe5FEddzgj: 1.00000000 BTC
        └── 17CoutvJ2fxbNbor7KTMaryNgKKXY2jrDt: 1.00000000 BTC
        └── 1ByfjmkjGxGGSKoNKga5yD8ZrocvrNRJZ8: 1.00000000 BTC
        └── 14XkaBu9hbKGgmeiigEgRRDmLmVF7du2Ev: 1.00000000 BTC
        └── 1PvXGhStoTYybGWahaCXXod4xANWeUduda: 1.00000000 BTC
        └── 1DTih2SjeSXi5gdWGjz6EjwxfuokD1XaCj: 1.00000000 BTC
        └── 1JgTdf4iDRer23ZY6rB5epKaxbMLepUHcY: 1.00000000 BTC
        └── 1MbS1N8C7tqtt36F6p3Ud5V9XVE9H8JBgV: 1.00000000 BTC
        └── 1GAQGtYgKG9ztJgfgqcxXPV7ZaU1bVuFfk: 1.00000000 BTC
        └── 1HCbdB7aju63nwN7JSoeZWXwWCgfF4kwRS: 1.00000000 BTC
        └── 1NdnHyv4zqTi8z5XM2W26zf9yTYRmJmxVN: 1.00000000 BTC
        └── 1Lht9pxa9BtfBDSyChzXCc66HTvxwv4NT4: 1.00000000 BTC
        └── 12g1egrBd1hGeD6L5gzZGLMMvsLtKV1xLN: 1.00000000 BTC
        └── 1ArBriNcKD3UTgwLtJ5g899GMB8qVoAtNz: 1.00000000 BTC
        └── 1FjHANXWHrg2tmKxHAKrPQVePNkxN8nw9p: 1.00000000 BTC
        └── 14RXFYoaLsh2SXDKLEMbf2FbpwbA2B38p7: 1.00000000 BTC
        └── 1GM37PjoLLPsXUDgeLkYzzbGYXGkhiNEm7: 1.00000000 BTC
        └── 1Q9MMYcCAbqE3pn6BHNKHbdQWXdy2zBnJ6: 1.00000000 BTC
        └── 1G1KfBiAKPbUzFBPwRqJcyMV23yzc5gSaQ: 1.00000000 BTC
        └── 1L5YaoA5EmMFfAmTF24n4esgijZqLmwR5n: 1.00000000 BTC
        └── 1Aq1wxzZdeRkP7uaffTEYe6tdNd2JGePeS: 1.00000000 BTC
        └── 1PMeL8dAUf7QheALs1KX3qLUMCpALHRJQt: 1.00000000 BTC
        └── 1HsWjgX9N7Vn8boSh12ggTpBjY9vPMDmaQ: 1.00000000 BTC
        └── 5deec1f3d9165a2fcd50e29e2a717bb55fad43147abf9719bed85762b96a8e9d
        └── 1JTZcVy44WmmycHYxkNnvupRpW3VknHfiS: 1.00000000 BTC
        └── 1JVqesXMAGNzxDNQ2TPRSnakmMfXJoNn1B: 1.00000000 BTC
        └── 1L7p6s4Z62XS3PKhXksLjB9MdKbSteJGrd: 1.00000000 BTC
        └── 1A7FjAFzk6UdRG9UMzm73DcpPYU8dTY8gE: 69.99000000 BTC
        1A7FjAFzk6UdRG9UMzm73DcpPYU8dTY8gE
        └── 4157853bf55daf4c57d6b5ee2ed27859afaf36ef38127cb92a43e4000797f4ff&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
        └── 1Jo2DWeEqMx9DEVXfu8Gr2Jy4YzV3ofqUW: 1.00000000 BTC
        └── 1GNWSizCVP7K8kFkTii4D6cWXtZrwMmor5: 1.00000000 BTC
        └── 1D5wUqrcJjvaaPRNjuAVxbnvc3xLyP39ye: 1.00000000 BTC
        └── 1DsJRebJyQHpJ8rLdFEgywyJowUAxVHt8Z: 1.00000000 BTC
        └── 1B7Xe3MKvW2M3Qdt4LS8cr2519g2kxNkKv: 1.00000000 BTC
        └── 17R6pGLf8GbXgnD1vnC1wa7FQ3QwjBLupt: 1.00000000 BTC
        └── 1PQ2VFWW1wz1zDh8oG8EmqD9GuvRCa2J1L: 1.00000000 BTC
        └── 1PNoDnQbtTv7njs5MiHnGcBByAF5338ZKz: 1.00000000 BTC
        └── 13S8vf1UNRbMZteUG2jDs7MnEDQtpVD9eH: 1.00000000 BTC
        └── 18kYwZxAZ87ShL2qjxoch3SFoThrzx9p3u: 1.00000000 BTC
        └── 15bag4QWwQmv53ZSEnQxAPuvbZe6gWuQ8v: 1.00000000 BTC
        └── 1NcsxLQKoFVqUX2qJXiE669qBCWZcEdjpm: 1.00000000 BTC
        └── 15CeXrYxtzRxtLFWvxasydJxor2WcVuKYe: 1.00000000 BTC
        └── 1DG7LxLBu1eZB9jJ5aoC4GBe3t6GPRR8Mu: 1.00000000 BTC
        └── 1B4KEuwPnWYzeAbKWdUX7zasRWkLNnBVDs: 1.00000000 BTC
        └── 1BPmAjYsXvm39cwBcsJqbZ9bRqnCYu8tVX: 1.00000000 BTC
        └── 1FknTPNmVSqj57z84qzHijAnMBWj3Hu79r: 1.00000000 BTC
        └── c0ecaa1869188c0544b33d07b983434f545cf7bfaf669a48ced3951316439616
        └── 1EKYaN9XeW2TLygYE66AcYfGjLT9UGt2dS: 5.00000000 BTC
        └── 126yaPje7RkLYTMLhDdiAwRTLM5qmewJhp: 5.00000000 BTC
        └── 1LpJa4yRw99EVp1tXXB33Y8okqkawENhUr: 5.00000000 BTC
        └── 16tVDDFb13RzeW9qpL4ZDDFcvSa1DqMZyk: 5.00000000 BTC
        └── 1DxtR7FXZnM2xyb8Mae77XNBBW1gXskwGe: 5.00000000 BTC
        └── 1JtAFhqwgAkVJLwkAm8jUXDKfJvCVYvYeM: 5.00000000 BTC
        └── 1EsqUUJXbNfdZPETpqpK9q1XtC8t1juzmy: 5.00000000 BTC
        └── 1NUwqZsbNhMwEA289FEsUrGQLTnLZe7DXT: 5.00000000 BTC
        └── 1CXTquwt54M2nVJkhkXZfVfARxkBo9yAGb: 5.00000000 BTC
        └── 1HJLaR3NRjg8iof8UmdEugiE8y3FUUngAt: 5.00000000 BTC
        └── 14MF8zVKTmx8DZkYApawtNWQL6WTqs8KGZ: 5.00000000 BTC
        └── 1eMfnArLKC2S6VMgsYQB12d1Hn5dd5sYo: 5.00000000 BTC
        └── 1CsNyy7cVRBh9uy2yvgcJvwJGLAFRF7wSL: 90.98000000 BTC
        1CsNyy7cVRBh9uy2yvgcJvwJGLAFRF7wSL
        └── 4157853bf55daf4c57d6b5ee2ed27859afaf36ef38127cb92a43e4000797f4ff&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
        └── 1JzgsHEQfU5W7W4P91cAA86cxHjHbSbc43: 5.00000000 BTC
        └── 1241BdUkDUUBBJmeHSVjQjeHbjiLDZMZdY: 5.00000000 BTC
        └── 1Hqv22oCVNs2JP5tYpAAKTGGvoE8Pjyhkm: 5.00000000 BTC
        └── 1EBm4UvwqssQC67sqHT4fdMe3fu6q5y9GB: 5.00000000 BTC
        └── 195Ps5rxnpvsXjGGFN5xRaCpJndqE1HPdC: 5.00000000 BTC
        └── 1D1zb8ptPVGC6ypn7ZRT4WouMzvX3BPHCu: 5.00000000 BTC
        └── e440fb286972e803bb3ea4c007ef355854174f9bc2025b35cb9ef00a98b6c005
        └── 199nyG8Z5CBVuHZuCoSqYUdcAS4q4BUEHt: 10.00000000 BTC
        └── 1MKP7wFGg6qf5rck8A8mD85TMfzBNnM9YG: 10.00000000 BTC
        └── 1Bwx4Ehu9ywoxQKiYCbtG6mbAkgisW9H6m: 10.00000000 BTC
        └── 1MvX8zhePgq3fkWXtHY4HQUoBdLs4nijzk: 10.00000000 BTC
        └── 1Dk9fosZvvJnee2LCMJLngbtRsGror1p6R: 10.00000000 BTC
        └── 17Zg6YqFP9ftTGyqGAaFk6ZQLDbC4oNen9: 10.00000000 BTC
        └── 1XxUHZrDfbqzYkkRs4dxTvwz9xsaaEgw8: 10.00000000 BTC
        └── 1P6ZWkVZQGcRUR6jSKV165rDQj7mMdnmZn: 10.00000000 BTC
        └── 1EyB63e7YuNqWcjktgbjDth7ncKTBBC3y9: 10.00000000 BTC
        └── 1SzhR4v5hYf3fKu2US5FbuAFhcnY5xUrg: 10.00000000 BTC
        └── 13vmyWMa9kJ7UtsSXSZ61mxgvXQQGX4zwv: 10.00000000 BTC
        └── 173zTWASJjaAFssUSoWjtVA7bTNparfmbg: 10.00000000 BTC
        └── 1GG14EscCgjdRZrk9JrZJRhH5Tb7FFsJBT: 10.00000000 BTC
        └── 1NsQmU61A22xiuSvaDZ6YvZiyFvrSoz2JE: 10.00000000 BTC
        └── 1LJzK4SoL7h3SfmPRnxM71JU81H2kGe6rh: 10.00000000 BTC
        └── 1JyxTFSEaYXXSxWBjjF5XyFPut44VbM2Nn: 829.96000000 BTC
        1JyxTFSEaYXXSxWBjjF5XyFPut44VbM2Nn
        └── c262797f2d7c790db63a4e5ce4b4bb2a511de2c0e1516dd6d7b6b6f0c749f5ea&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
        └── 1NNmdNFEm56tD8ujodrvabfUqoXyY5Q5RP: 10.00000000 BTC
        └── 1CfWyA4bfSwzEhrVnrVNkkxdybxhakN5vZ: 10.00000000 BTC
        └── 1AzDAssrzKrsd2HoJ3mDPQjzqsDSvF8L6M: 10.00000000 BTC
        └── 1FSAkq6EaiFz1mvJAWkCfpC7a9FSr8Ci92: 10.00000000 BTC
        └── 18iNoijWa5cgWbnH1oCkgHrhCMPpJzSEmx: 10.00000000 BTC
        └── 159VjbaYgh9FNTuEHQ7R8igyETqULWSNF4: 10.00000000 BTC
        └── 13BiLzSJFJUp2XjBtGr9bLsFU2pPMsGs5s: 10.00000000 BTC
        └── 1PaxoVGfvgmWAuten4CwE8sKhrwxWX8fu4: 10.00000000 BTC
        └── 1LBbkY51Zywv2m58mXZisVeNkeDQWSh9bN: 10.00000000 BTC
        └── 12NBYNJDjcrZCwFSKGGE4zLk22Xd8a2fz7: 10.00000000 BTC
        └── 1LnFmYZJbZPttqx9gGYFsGnxD68LMyBRm6: 10.00000000 BTC
        └── 1JY8ywzuSH8pPVe3dK39VAFiVPRpgSsVSm: 10.00000000 BTC
        └── 1HDdG7db9epmTTSJ3P9fRGE1JGRGTDRhYG: 10.00000000 BTC
        └── 1KQKxiGioUREcUzhy4US1CRQ69uYjZX42Y: 10.00000000 BTC
        └── 1MQjzqi4NXnXZZRzADNX7cijKqKekaVSff: 10.00000000 BTC
        └── 1N9bQA8gEb2o6uXhaRjaayNPLoKbT41LN3: 10.00000000 BTC
        └── 17zMKhURErHpLBrrdJjvXwV2i631BLoRNQ: 10.00000000 BTC
        └── 19bWHN9vExHt6fo6DGjHf6SQnaSGYTAWiV: 10.00000000 BTC
        └── 1412SvGyy4NqfhggW1GCgdt4m5pv3guEYt: 10.00000000 BTC
        └── 1LTbopgFutYL2ikxpVctmfNb1uEStWDtDF: 10.00000000 BTC
        └── 19TyUYKLxfLaTvywiTQ4x9ihGPi4aB2CrG: 10.00000000 BTC
        └── 1D6MWiZgyNwh4Mp4yAXEcKTZwURzYb1QPJ: 10.00000000 BTC
        └── 1FSr3ELWDdu5PZMoXqaeReqMiV5tZi9Uhu: 10.00000000 BTC
        └── 1DDT4BCsmf2P1RqtAWftT6ksEJsWcBtyPG: 10.00000000 BTC
        └── 1295X25FTRuCg3Pb43QyjLsgRurqHg4J2X: 10.00000000 BTC
        └── 16zBuN3RmJ2FtV2yD75VitCvLgyLU1YQwr: 10.00000000 BTC
        └── 1FcRA7QqknjT1hsNibWtgYenfGrVLkEfx5: 10.00000000 BTC
        └── 1BCJgTM7ot9LQyYvgPrnb7p3CMcWsUh9ps: 10.00000000 BTC
        └── 1GxWo7q1UQoonZfrUmcNqGrsmqtQSPVMcP: 10.00000000 BTC
        └── 13jKUbwHaWQyPF7fY4kEkMUjy1ewKH5Pgv: 10.00000000 BTC
        └── 1PiNWdQARxBpt6g9GdAEYHkPiiGa8EvuYb: 10.00000000 BTC
        └── 19qy4JY44Vb5nbAbEuCd8maJ2mVy5N9ekc: 10.00000000 BTC
        └── 1LFGCWWBqj4MiumH84oxa3HjBUgZmngkrD: 10.00000000 BTC
        └── 18viBXsPt7WFUku7TNgsT9Uz7UQjc31r8g: 10.00000000 BTC
        └── 151HCiHhaTqQAdD93j3c7bdV2r6nJEcC5f: 10.00000000 BTC
        └── 1AhL2PqbSWX9Yy1NRM87zw2Y3HpUDVtCvC: 10.00000000 BTC
        └── 1DhHYLRS5q7yBZyihysrAJnvqN5DtpHX5Y: 10.00000000 BTC
        └── 1i3UQCBscLv3q7xQkk8yka42uXBDTKFwE: 10.00000000 BTC
        └── 19JSinMfcArqu6CkLauocKDVTCdfpAtweT: 10.00000000 BTC
        └── 1QCE3zKKZ1KCuzduYVGDQ55WfEVtnY9Wnh: 10.00000000 BTC
        └── 17QeD5mpxDRJHpsCzagoey9y52WtpcCgoP: 10.00000000 BTC
        └── 1Gg5V8ZjU17aDbr6edCVQFf5ef3Hw3fUSR: 10.00000000 BTC
        └── 13gfPHStgixjzu1vMfhwuitp3Kk65RVGbP: 10.00000000 BTC
        └── 18EypXUsMFGkCGuCJBdwnUXtBFcmmytcQK: 10.00000000 BTC
        └── 1652TSE6k9YU1eZJy77K45bEnhqV7Ms4iX: 10.00000000 BTC
        └── 18BkdfUiuyeQWPofL9ueHeY7UuyZ8hzcVh: 10.00000000 BTC
        └── 135u35xwxjVRjgi7tgdQrwwgGFmeLb8Yb1: 10.00000000 BTC
        └── 17H5HLe2WcjX6S71DA4EmA82q4BjeoBMok: 10.00000000 BTC
        └── 1HDfDJN9KxH9HXqUa9E1xX3Fi4MFrdVgR8: 10.00000000 BTC
        └── 1GCA9ik2mbPKgaUU6pBbXcBFstaHiKSX65: 10.00000000 BTC
        └── 14a9EUNjjeNh9StRbeH16PgvJaGa8dvHkL: 10.00000000 BTC
        └── 149xjEZYKBjsQXfzxWRt3L7bREdEtHMv3b: 10.00000000 BTC
        └── 1MVoXVLvcPq98HKQH1Emd5BMZvVKdGhoXN: 10.00000000 BTC
        └── 16KJzXD4cRqPMt7xzYNu6rZCxikC5HW2CY: 10.00000000 BTC
        └── 1FHkWgKPY3a6eSJjNYQAqgZDRmz55Fh79h: 10.00000000 BTC
        └── 1MWHGSNmKRDMeHCKQ3V1CH6TYvn9hCLBzF: 10.00000000 BTC
        └── 15vb9aeM4Tk3yt9VtwzMxU1jMf1XsPJCTy: 10.00000000 BTC
        └── 14njCxtgWgtU4tM524brM3fJvp6s1yjqS5: 10.00000000 BTC
        └── 17w8MenSniZcDtEaHobKGFB7sVzMDpM67K: 10.00000000 BTC
        └── 15KGEFFWbwafoVRg21CKZnXkn1DtWiwHez: 10.00000000 BTC
        └── 19HW5w72JyGi3cbnRWpTRvghA9Fwor8aj5: 10.00000000 BTC
        └── 1D71eCxQHi5hcVvcmSUb5GbMPdhzQKYpEo: 10.00000000 BTC
        └── 19cgkx6vmcJego1BMuBE8aT3uQoGmcmeKH: 10.00000000 BTC
        └── 1N8A71cPb2FAmpSyfiKKGKQXs8ALPizyVi: 10.00000000 BTC
        └── 1LyJte9bkzCVn3YmEngztV1Sxe8LLHeWwo: 10.00000000 BTC
        └── 1Lg3Lsxs4D8q2pz5wYYU6mmRfAPZkJz6mc: 10.00000000 BTC
        └── 12AHp2aF47izsx66F9n9SxVCSCDJfuychg: 10.00000000 BTC
        └── 1N6wTiPFXWXdWkbj9J6HNm5yHVETmojAkP: 10.00000000 BTC
        └── 14qJZRApNuAEd7tmXK8MWSoR99hLMX4iQg: 10.00000000 BTC
        └── 138prbgoUdzmgxskWSTRzTXUqjFBjXoMcP: 10.00000000 BTC
        └── 1JS1WWcUx65YSDnRx7sjaoHuo6gN4r2jGE: 10.00000000 BTC
        └── 1MQuyT1y7CkRHgjoj9PAYmN4KEvanwjEku: 10.00000000 BTC
        └── 1MyWJyxUcbdCFEVLuJ6UXaF26vNN49Jb2E: 10.00000000 BTC
        └── 1HLNzKeKQtzhwukp9CorbpKua8W3vJY6u9: 10.00000000 BTC
        └── 69a39eb32d93639537e6f3321fd60e608225272699a09dad5f511f38139bd6fb&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
        └── d12b522c33ca1d22d070af08ab12280e793f4134c289b834de91e79b2f0f6247&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;Transaction IDs marked with a &lt;code class=&quot;highlighter-rouge&quot;&gt;*&lt;/code&gt; are detectable through multiple paths in the tree - I only process them the first time they are encountered.&lt;/p&gt;
        &lt;h2 id=&quot;bitbills-today&quot;&gt;Bitbills Today&lt;/h2&gt;
        &lt;p&gt;With this set of addresses now available, I was able to load the entire Bitbills collection onto &lt;a href=&quot;https://collectible.money&quot; target=&quot;_BLANK&quot;&gt;collectible.money&lt;/a&gt; under &lt;a href=&quot;https://collectible.money/creator/bitbills&quot; target=&quot;_BLANK&quot;&gt;Bitbills&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;As of this post&apos;s publication, a total of 928 Bitbills were produced. Today, just 395 remain intact, with only 26 20 BTC Bitbills and 27 10 BTC Bitbills intact respectively.&lt;/p&gt;
        &lt;p&gt;1 BTC Bitbills were produced in the largest quantity, and also have the highest peel rate - nevertheless, I believe a significant portion of the 293 remaining 1 BTC Bitbills are lost to time, given the lower redemption rate than other denominations.&lt;/p&gt;
        &lt;p&gt;This also means that today, only 26 full sets of 1, 5, 10, and 20 BTC Bitbills can be assembled.&lt;/p&gt;</content><author><name></name></author><category term="bitcoin" /><category term="collectible.money" /><category term="crypto-forensics" /><category term="crypto-collectibles" /><category term="crypto-numismatics" /><summary type="html">In May 2011, an innocuous post[[bitcointalk.org/index.php?topic=7724.0::lsn]] appeared on the bitcointalk forum. Titled &quot;Introducing Bitbills!&quot;, it became the first stepping stone in what grew to be a thriving collectibles market in the Bitcoin space.</summary></entry><entry><title type="html">BTC Archeology: Where was 1.2 BTC sent in 2010?</title><link href="https://raghavsood.com//blog/2024/06/25/bitcoin-archeology-120-btc-lost/" rel="alternate" type="text/html" title="BTC Archeology: Where was 1.2 BTC sent in 2010?" /><published>2024-06-25T00:00:00+00:00</published><updated>2024-06-25T00:00:00+00:00</updated><id>https://raghavsood.com//blog/2024/06/25/bitcoin-archeology-120-btc-lost</id><content type="html" xml:base="https://raghavsood.com//blog/2024/06/25/bitcoin-archeology-120-btc-lost/">&lt;p&gt;As part of building &lt;a href=&quot;https://burned.money&quot; target=&quot;_BLANK&quot;&gt;burned.money&lt;/a&gt;, I&apos;ve been trying to track down old cases of BTC that is likely lost.&lt;/p&gt;
        &lt;p&gt;On July 14th 2010 (UTC), bitcointalk user &lt;code class=&quot;highlighter-rouge&quot;&gt;ksd5&lt;/code&gt; started a &lt;a href=&quot;https://bitcointalk.org/index.php?topic=359.0&quot; target=&quot;_BLANK&quot;&gt;thread&lt;/a&gt; talking about how they could not locate 1.2 BTC after playing around with the wallet to test double spend protection.[[Bitcoin protects against double spending using the Unspent Transaction Output model - Each transaction output is uniquely identified by it&apos;s transaction ID and index in the output list (vout). Each &lt;code class=&quot;highlighter-rouge&quot;&gt;txid:vout&lt;/code&gt; pair can only be consumed once in the entire blockchain. If a subsequent transaction claims to spend from an already consumed pair, it is invalid and any blocks containing it are invalid.::rmn]]&lt;/p&gt;
        &lt;p&gt;In summary, &lt;code class=&quot;highlighter-rouge&quot;&gt;ksd5&lt;/code&gt; says that they:&lt;/p&gt;
        &lt;ol&gt;
        &lt;li&gt;Started with a wallet containing 1.21 BTC&lt;/li&gt;
        &lt;li&gt;Made a backup of that wallet by copying &lt;code class=&quot;highlighter-rouge&quot;&gt;wallet.dat&lt;/code&gt; to a new location&lt;/li&gt;
        &lt;li&gt;With the original copy of the file loaded into the Bitcoin Client, they made a 0.1 BTC donation&lt;/li&gt;
        &lt;li&gt;They then closed the client and replaced &lt;code class=&quot;highlighter-rouge&quot;&gt;wallet.dat&lt;/code&gt; with the backup copy&lt;/li&gt;
        &lt;li&gt;Upon starting the client, they briefly saw a 1.21 BTC balance, before it became 0 and showed a 1.21 BTC outgoing transaction&lt;/li&gt;
        &lt;/ol&gt;
        &lt;p&gt;Notably, at step 4, they did not make a new backup of the in-use &lt;code class=&quot;highlighter-rouge&quot;&gt;wallet.dat&lt;/code&gt;.&lt;/p&gt;
        &lt;p&gt;Early Bitcoin wallet managed addresses using a keypool, which pre-generated 100 addresses so that a backup would only have to be performed every 100 transactions or so. However, back in July 2010, this hadn&apos;t been implemented yet.[[It was only added in &lt;a href=&quot;https://bitcointalk.org/index.php?topic=1414.0&quot; target=&quot;_BLANK&quot;&gt;October 2010&lt;/a&gt; by Satoshi Nakamoto.::lsn]]&lt;/p&gt;
        &lt;p&gt;As such, the Bitcoin Core client used by user &lt;code class=&quot;highlighter-rouge&quot;&gt;ksd5&lt;/code&gt; would generate a new, random private key for each new address, which would then be stored in the &lt;code class=&quot;highlighter-rouge&quot;&gt;wallet.dat&lt;/code&gt;.&lt;/p&gt;
        &lt;p&gt;When the first backup was made in Step 2, the wallet would have only contained the private key for the address holding the 1.21 BTC (and previously used addresses, if any).&lt;/p&gt;
        &lt;p&gt;Then, when the transaction was made in Step 3, a new private key was generated for the change address and stored in the &lt;code class=&quot;highlighter-rouge&quot;&gt;wallet.dat&lt;/code&gt;.[[A change address is an address in a Bitcoin transaction that sends any unused funds back to the sender&apos;s wallet. For improved privacy, most wallets will use a new, unused address for this.::lsn]]&lt;/p&gt;
        &lt;p&gt;However, when the user copied the original backup back and overwrote the now-updated &lt;code class=&quot;highlighter-rouge&quot;&gt;wallet.dat&lt;/code&gt;, this new key was lost. As far as the original backup was concerned, it had no knowledge of this change address, or the 1.2 BTC sent to it in the previous transaction.&lt;/p&gt;
        &lt;p&gt;Upon learning that the keys were lost, &lt;code class=&quot;highlighter-rouge&quot;&gt;ksd5&lt;/code&gt; declined to attempt recovery using any disk recovery tools as to deal with such &quot;small stuff&quot;.[[I&apos;m not gonna bother trying to recover the file. It was only 1.20 BTC and I&apos;m not gonna sweat the small stuff.&lt;br /&gt;&lt;cite&gt;—&lt;a href=&quot;https://bitcointalk.org/index.php?topic=359.msg3006#msg3006&quot; target=&quot;_BLANK&quot;&gt;ksd5, July 14 2010&lt;/a&gt;&lt;/cite&gt;::rmn]]&lt;/p&gt;
        &lt;p&gt;The &quot;small stuff&quot;, valued at ~0.012 USD in 2010, is worth ~73,000 USD today.&lt;/p&gt;
        &lt;h1 id=&quot;so-where-did-it-go&quot;&gt;So, where did it go?&lt;/h1&gt;
        &lt;p&gt;With the history lesson accounted for, let&apos;s try and track down the BTC in question.&lt;/p&gt;
        &lt;p&gt;As a rule, &lt;a href=&quot;https://burned.money&quot; target=&quot;_BLANK&quot;&gt;burned.money&lt;/a&gt; only tracks BTC where the public address is known. If I want to include this loss, I need to track down the address associated with this transaction.&lt;/p&gt;
        &lt;p&gt;The following searches were done on my local index of Bitcoin transactions, but for the purpose of this post I&apos;ll recreate them using &lt;a href=&quot;https://blockchair.com&quot; target=&quot;_BLANK&quot;&gt;Blockchair&lt;/a&gt;.&lt;/p&gt;
        &lt;h2 id=&quot;narrowing-down-the-candidates&quot;&gt;Narrowing down the candidates&lt;/h2&gt;
        &lt;p&gt;We know that the user started with 1.21 BTC. While it is technically possible that this was held in multiple addresses, given the low value of BTC at the time, we can assume that it is a single output.&lt;/p&gt;
        &lt;p&gt;We&apos;re also going to assume that it was somewhat recently created - &lt;code class=&quot;highlighter-rouge&quot;&gt;ksd5&lt;/code&gt; only signed up for bitcointalk two days prior, on July 12th 2010. Their other posts are indicative of it being early in their Bitcoin journey.&lt;/p&gt;
        &lt;p&gt;Lastly, we also know that the coins were spent - the user made an outgoing transaction for 0.1 BTC, which would result in the full 1.21 BTC being consumed (with 1.20 BTC sent to a change address, thus beginning this saga).&lt;/p&gt;
        &lt;p&gt;With these parameters, I decided to search for outputs that:&lt;/p&gt;
        &lt;ol&gt;
        &lt;li&gt;Are spent&lt;/li&gt;
        &lt;li&gt;Are exactly 1.21 BTC&lt;/li&gt;
        &lt;li&gt;Were created between 1 July 2010 and 15 July 2010&lt;/li&gt;
        &lt;/ol&gt;
        &lt;p&gt;Blockchair&apos;s handy output listing and its filters allow us to &lt;a href=&quot;https://blockchair.com/bitcoin/outputs?s=time(desc)&amp;amp;q=value(121000000),time(2010-07-01..2010-07-15),is_spent(true)&quot; target=&quot;_BLANK&quot;&gt;narrow it down to 3 outputs&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;&lt;img src=&quot;/blog/img/120-btc-lost-blockchair-1.png&quot; alt=&quot;Blockchair output search&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;
        &lt;table style=&quot;width: 100%; font-family: monospace;&quot;&gt;
        &lt;thead style=&quot;text-align: left; background-color: #cccccc;&quot;&gt;
        &lt;tr&gt;
        &lt;th&gt;Block&lt;/th&gt;
        &lt;th&gt;Block Time&lt;/th&gt;
        &lt;th&gt;Address&lt;/th&gt;
        &lt;th&gt;Value&lt;/th&gt;
        &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody style=&quot;text-align: left; background-color: #f0f0f0;&quot;&gt;
        &lt;tr&gt;
        &lt;td&gt;67758&lt;/td&gt;
        &lt;td&gt;2010-07-15 10:34:11&lt;/td&gt;
        &lt;td&gt;1Ndgetj6fyvwf7ia5XpvrUgoy6gz5U4Wf5&lt;/td&gt;
        &lt;td&gt;1.21 BTC&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
        &lt;td&gt;67434&lt;/td&gt;
        &lt;td&gt;2010-07-14 22:29:00&lt;/td&gt;
        &lt;td&gt;1HRCRTBjdGPmbUVqQhhthBVyeAsGGFqXVJ&lt;/td&gt;
        &lt;td&gt;1.21 BTC&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
        &lt;td&gt;67246&lt;/td&gt;
        &lt;td&gt;2010-07-14 14:21:18&lt;/td&gt;
        &lt;td&gt;1PVGD99UorsotcKyZYKHSyMxTHpnth1vny&lt;/td&gt;
        &lt;td&gt;1.21 BTC&lt;/td&gt;
        &lt;/tr&gt;
        &lt;/tbody&gt;
        &lt;/table&gt;
        &lt;h2 id=&quot;picking-the-winner&quot;&gt;Picking the winner&lt;/h2&gt;
        &lt;p&gt;We can disqualify the first output, as it took place after July 14th - by then, the bitcointalk post had already been made.&lt;/p&gt;
        &lt;p&gt;Between the remaining two candidates, we need to look at the actual transaction details.&lt;/p&gt;
        &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;1HRCRTBjdGPmbUVqQhhthBVyeAsGGFqXVJ&lt;/code&gt; sent 1.2 BTC to &lt;code class=&quot;highlighter-rouge&quot;&gt;16DsRFSCbv8aPMmDcbP4wYsS4FV9hf6rt2&lt;/code&gt; and 0.01 BTC to &lt;code class=&quot;highlighter-rouge&quot;&gt;15VjRaDX9zpbA8LVnbrCAFzrVzN7ixHNsC&lt;/code&gt;.&lt;/p&gt;
        &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;1PVGD99UorsotcKyZYKHSyMxTHpnth1vny&lt;/code&gt; send 1.2 BTC to &lt;code class=&quot;highlighter-rouge&quot;&gt;1BDjntPz95d9Ppv7qmWqqY8EUfjF94oQvR&lt;/code&gt; and 0.1 BTC to &lt;code class=&quot;highlighter-rouge&quot;&gt;15jJwkaxssfrq6jo82tRbHBorvfQ46GgpC&lt;/code&gt;.&lt;/p&gt;
        &lt;p&gt;At this stage, both look viable - the outgoing transactions match the bitcointalk post, and took place prior to the post being made.&lt;/p&gt;
        &lt;p&gt;However, we do have more information to filter with:&lt;/p&gt;
        &lt;ol&gt;
        &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ksd5&lt;/code&gt; mentioned that they made a donation - while it is not specified to whom this donation was, we are looking at the very early days of Bitcoin. Donations for useful services and sites was commonplace, and donation addresses tend to see a lot of activity&lt;/li&gt;
        &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ksd5&lt;/code&gt; declined to recover the coins - this means that at least the 1.2 BTC output must be unspent&lt;/li&gt;
        &lt;/ol&gt;
        &lt;p&gt;Armed with the above facts, we can look into the outputs of the two candidates and further narrow it down.&lt;/p&gt;
        &lt;h2 id=&quot;where-did-all-the-coins-go&quot;&gt;Where did all the coins go?&lt;/h2&gt;
        &lt;p&gt;First, let&apos;s look at the second transaction.&lt;/p&gt;
        &lt;p&gt;&lt;img src=&quot;/blog/img/120-btc-lost-trezor-1.png&quot; alt=&quot;1PVGD99UorsotcKyZYKHSyMxTHpnth1vny outgoing transactions&quot; width=&quot;100%&quot; /&gt;
        &lt;em&gt;Image from &lt;a href=&quot;https://btc2.trezor.io/address/1PVGD99UorsotcKyZYKHSyMxTHpnth1vny&quot; target=&quot;_BLANK&quot;&gt;Trezor&apos;s Blockbook&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
        &lt;p&gt;The 1.2 BTC output sent to &lt;code class=&quot;highlighter-rouge&quot;&gt;1BDjntPz95d9Ppv7qmWqqY8EUfjF94oQvR&lt;/code&gt; was subsequently &lt;a href=&quot;https://btc2.trezor.io/tx/f9b53a53820d659220b7493a083669c08025423968f5e524a4967900635b8062&quot; target=&quot;_BLANK&quot;&gt;spent&lt;/a&gt; on 14th July 2010. While it is possible that &lt;code class=&quot;highlighter-rouge&quot;&gt;ksd5&lt;/code&gt; managed to recover their keys after making the post[[Bitcoin Block Timestamps aren&apos;t 100% in line with real-world time, which can lead to discrepencies when comparing bitcointalk post timings against the blockchain.::lsn]] and spend the coins, it does seem unlikely for 0.012 USD.&lt;/p&gt;
        &lt;p&gt;The address involved in the 0.01 BTC output, &lt;code class=&quot;highlighter-rouge&quot;&gt;15jJwkaxssfrq6jo82tRbHBorvfQ46GgpC&lt;/code&gt;, is a little more interesting. It also &lt;a href=&quot;https://btc2.trezor.io/tx/77f6d7385e9f7c7dbafbcf9fdf10d6c98f8591cc13e2edd153bb03131f5feb2a&quot; target=&quot;_BLANK&quot;&gt;received&lt;/a&gt; 0.01 BTC in the same transaction that funded 1.21 BTC to &lt;code class=&quot;highlighter-rouge&quot;&gt;1PVGD99UorsotcKyZYKHSyMxTHpnth1vny&lt;/code&gt;, and has seen 312 transactions. This is a good candidate for a donation address.&lt;/p&gt;
        &lt;p&gt;However, all of the transactions involving that address are for 0.01 BTC, and we see intermediate consolidation transactions combining all the BTC sent to it and &lt;a href=&quot;https://btc2.trezor.io/address/1BiRpMGDef8rEDZU6RArzYmBGATQSG1zQp&quot; target=&quot;_BLANK&quot;&gt;another address&lt;/a&gt; (also receiving multiple 0.01 BTC transactions). The address was also active for only three days between 13th and 15th July 2010.&lt;/p&gt;
        &lt;p&gt;This behaviour doesn&apos;t match that of a donation address, as they tend to be long-lived and see more disparate amounts.&lt;/p&gt;
        &lt;p&gt;Based on this, I would disqualify &lt;code class=&quot;highlighter-rouge&quot;&gt;1PVGD99UorsotcKyZYKHSyMxTHpnth1vny&lt;/code&gt; as the address used by &lt;code class=&quot;highlighter-rouge&quot;&gt;ksd5&lt;/code&gt; to send 1.21 BTC.&lt;/p&gt;
        &lt;p&gt;Turning our attention to the second candidate, we see an outgoing transaction that meets our amount criteria.&lt;/p&gt;
        &lt;p&gt;&lt;img src=&quot;/blog/img/120-btc-lost-trezor-2.png&quot; alt=&quot;1HRCRTBjdGPmbUVqQhhthBVyeAsGGFqXVJ outgoing transactions&quot; width=&quot;100%&quot; /&gt;
        &lt;em&gt;Image from &lt;a href=&quot;https://btc2.trezor.io/address/1HRCRTBjdGPmbUVqQhhthBVyeAsGGFqXVJ&quot; target=&quot;_BLANK&quot;&gt;Trezor&apos;s Blockbook&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
        &lt;p&gt;Right away, this seems more promising - the 1.2 BTC output sent to &lt;code class=&quot;highlighter-rouge&quot;&gt;16DsRFSCbv8aPMmDcbP4wYsS4FV9hf6rt2&lt;/code&gt; remains unspent as of writing this post, which aligns with &lt;code class=&quot;highlighter-rouge&quot;&gt;ksd5&lt;/code&gt;&apos;s post and the keys being lost.&lt;/p&gt;
        &lt;p&gt;The second address, receiving the purpoted donation, is &lt;code class=&quot;highlighter-rouge&quot;&gt;15VjRaDX9zpbA8LVnbrCAFzrVzN7ixHNsC&lt;/code&gt;. This address has soon over 9000 transactions till date, with many varying amounts. It was first used on 11th June 2010, with the last outgoing transaction on 3rd July 2014.&lt;/p&gt;
        &lt;p&gt;With a little research on this address, we can find out that it was used by the very first Bitcoin Faucet, created by Gavin Andresen. The faucet would give out 5 BTC to anyone who asked for it, and was instrumental in the early days of Bitcoin.&lt;/p&gt;
        &lt;p&gt;A 3rd July 2010 &lt;a href=&quot;https://web.archive.org/web/20100703032414/https://freebitcoins.appspot.com/&quot; target=&quot;_BLANK&quot;&gt;snapshot from archive.org&lt;/a&gt; shows &lt;code class=&quot;highlighter-rouge&quot;&gt;15VjRaDX9zpbA8LVnbrCAFzrVzN7ixHNsC&lt;/code&gt; as the donation address for the faucet.&lt;/p&gt;
        &lt;p&gt;This lines up perfectly with the donation mentioned by &lt;code class=&quot;highlighter-rouge&quot;&gt;ksd5&lt;/code&gt;. When combined with the 1.2 BTC output being unspent, we can say with a high degree of confidence that the address with the lost key is &lt;code class=&quot;highlighter-rouge&quot;&gt;16DsRFSCbv8aPMmDcbP4wYsS4FV9hf6rt2&lt;/code&gt;.&lt;/p&gt;
        &lt;h1 id=&quot;burned-btc---where-does-it-go&quot;&gt;Burned BTC - where does it go?&lt;/h1&gt;
        &lt;p&gt;As part of the &lt;a href=&quot;https://burned.money&quot; target=&quot;_BLANK&quot;&gt;burned.money&lt;/a&gt; project, I&apos;ve been tracking down lost BTC and categorising them based on their fate. The 1.2 BTC lost by &lt;code class=&quot;highlighter-rouge&quot;&gt;ksd5&lt;/code&gt; is a prime candidate for the &quot;Lost Keys&quot; category.&lt;/p&gt;
        &lt;p&gt;&quot;Burning Money&quot; is a term that predates cryptocurrencies. Within the context of this space, it&apos;s taken on a new meaning - the act of rendering coins irrevocably lost, preferably in a provable manner. Bitcoin does support a provable burn in the form of an &lt;code class=&quot;highlighter-rouge&quot;&gt;OP_RETURN&lt;/code&gt; output. However, many burn addresses have been created over the years, either for aesthetic purposes such as &lt;span style=&quot;font-family: monospace;&quot;&gt;&lt;a href=&quot;https://burned.money/script/76a914000000000000000000000000000000000000000088ac&quot; target=&quot;_BLANK&quot;&gt;1111111111111111111114oLvT2&lt;/a&gt;&lt;/span&gt;, &lt;span style=&quot;font-family: monospace;&quot;&gt;&lt;a href=&quot;https://burned.money/script/76a914818895f3dc2c178629d3d2d8fa3ec4a3f817982188ac&quot; target=&quot;_BLANK&quot;&gt;1CounterpartyXXXXXXXXXXXXXXXUWLpVr&lt;/a&gt;&lt;/span&gt;, or &lt;span style=&quot;font-family: monospace;&quot;&gt;&lt;a href=&quot;https://burned.money/script/76a914759d6677091e973b9e9d99f19c68fbf43e3f05f988ac&quot; target=&quot;_BLANK&quot;&gt;1BitcoinEaterAddressDontSendf59kuE&lt;/a&gt;&lt;/span&gt;, or by accident, such as by losing the keys to an address.&lt;/p&gt;
        &lt;p&gt;These, combined with several other ways to destroy BTC, contribute to a permanent reduction in the circulating supply of Bitcoin.&lt;/p&gt;
        &lt;p&gt;Having concluded this archaeological dig, I&apos;ll be adding the 1.2 BTC lost by &lt;code class=&quot;highlighter-rouge&quot;&gt;ksd5&lt;/code&gt; to the &lt;a href=&quot;https://burned.money&quot; target=&quot;_BLANK&quot;&gt;burned.money&lt;/a&gt; database under &lt;a href=&quot;https://burned.money/script/76a9143947b5155f8641756a90c935fbf61814a65ec4a288ac&quot; target=&quot;_BLANK&quot;&gt;16DsRFSCbv8aPMmDcbP4wYsS4FV9hf6rt2&lt;/a&gt;.&lt;/p&gt;</content><author><name></name></author><category term="bitcoin" /><category term="burned.money" /><category term="crypto-forensics" /><summary type="html">As part of building burned.money, I&apos;ve been trying to track down old cases of BTC that is likely lost.</summary></entry><entry><title type="html">Installing NixOS on an OVH/Kimsufi/SoYouStart server</title><link href="https://raghavsood.com//blog/2024/06/21/ovh-nixos-install/" rel="alternate" type="text/html" title="Installing NixOS on an OVH/Kimsufi/SoYouStart server" /><published>2024-06-21T00:00:00+00:00</published><updated>2024-06-21T00:00:00+00:00</updated><id>https://raghavsood.com//blog/2024/06/21/ovh-nixos-install</id><content type="html" xml:base="https://raghavsood.com//blog/2024/06/21/ovh-nixos-install/">&lt;p&gt;I&apos;ve been running NixOS servers for a few years now, largely hosting them across a mix of Mini PCs, DigitalOcean, Hetzner, and more recently Contabo.&lt;/p&gt;
        &lt;p&gt;While migrating &lt;a href=&quot;https://burned.money&quot;&gt;burned.money&lt;/a&gt; off fly.io (their 500GB volume limit started to become a problem), I settled on OVH&apos;s Kimsufi offering as it offered the best price for the storage I needed, and was located in a region close to my BTC node.&lt;/p&gt;
        &lt;p&gt;Unfortunately, as it turns out, a mix of OVH weirdness and Nix flakiness (distinct from Nix flakes) made this a long and cumbersome install.&lt;/p&gt;
        &lt;p&gt;Hopefully, this post will help you save some sanity and days if you are ever in the same boat.&lt;/p&gt;
        &lt;h2 id=&quot;getting-a-server&quot;&gt;Getting a server&lt;/h2&gt;
        &lt;p&gt;This part is pretty straightforward - head over to OVH or one of their subsidiaries (Kimsufi, SoYouStart) and pick a server that suits your needs. Buy it. Wait a few minutes to a few hours for the server to be provisioned. Done.&lt;/p&gt;
        &lt;h2 id=&quot;preparing-ovh&quot;&gt;Preparing OVH&lt;/h2&gt;
        &lt;p&gt;Before we get started, let me save you some time - open up the KVM. This isn&apos;t available on all servers, but most with datacenter-level hardware (sorry, no ATOMs).&lt;/p&gt;
        &lt;p&gt;OVH offers a KVM console, accessible by downloading a &lt;code class=&quot;highlighter-rouge&quot;&gt;jnlp&lt;/code&gt; file through their web console. Unfortunately, in 2024, &lt;code class=&quot;highlighter-rouge&quot;&gt;jnlp&lt;/code&gt; files are a relic of the past. M-series Macs aren&apos;t supported by the &lt;code class=&quot;highlighter-rouge&quot;&gt;iKVM64.jar&lt;/code&gt;. Debugging this cost me a few hours of my life.&lt;/p&gt;
        &lt;p&gt;Instead, you can fallback to sane options. Using a Linux machine with Nix (or, you know, NixOS), or a VM if you&apos;re on a Mac, you can simply run:&lt;/p&gt;
        &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;nix-shell &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; adoptopenjdk-icedtea-web
        &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;javaws /path/to/your/downloaded.jnlp
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;Don&apos;t waste your time with CheerpJ or other wrappers that claim to be able to deal with this. They can&apos;t. Use &lt;a href=&quot;https://github.com/AdoptOpenJDK/IcedTea-Web&quot; target=&quot;blank&quot;&gt;IcedTea-Web&lt;/a&gt; and be done with it.&lt;/p&gt;
        &lt;p&gt;By now, you should have a KVM interface - it should be showing you the graphical output as well as piping through your keyboard. By default, you&apos;re probably looking at the rescue mode login or some other OVH banner.&lt;/p&gt;
        &lt;p&gt;To get NixOS installed, we&apos;re going to use the &lt;code class=&quot;highlighter-rouge&quot;&gt;kexec&lt;/code&gt; method to temporarily boot into a NixOS system from the rescue system, and then use that to install NixOS onto the disk.&lt;/p&gt;
        &lt;h2 id=&quot;installing-nixos&quot;&gt;Installing NixOS&lt;/h2&gt;
        &lt;p&gt;First, we&apos;re going to use the OVH console to boot into rescue mode (use a Debian systems - Windows will not help), with an SSH key added - this is important, as our kexec NixOS is going to copy existing SSH keys.&lt;/p&gt;
        &lt;p&gt;To do this, alter the Boot configuration using the OVH console and select the rescue system. Provide your SSH key and click through the confirmation prompt. Then, reboot the server from the OVH console.&lt;/p&gt;
        &lt;p&gt;A minute or so later, you should be able to SSH into the server (tip: run &lt;code class=&quot;highlighter-rouge&quot;&gt;ping &amp;lt;ip&amp;gt;&lt;/code&gt; to have an indication of when the server has finished restarting).&lt;/p&gt;
        &lt;p&gt;You should now see a prompt like this:&lt;/p&gt;
        &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;root@rescue-customer-eu &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;ns326340.ip-&amp;lt;ip&amp;gt;.eu&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; ~ &lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;The Nix community offers weekly kexec images over at &lt;a href=&quot;https://github.com/nix-community/nixos-images&quot; target=&quot;blank&quot;&gt;nixos-image&lt;/a&gt;. Unfortunately, recent images don&apos;t quite seem to work&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; - they hang during execution, rendering the server inaccessible without a new reboot into rescue.&lt;/p&gt;
        &lt;p&gt;Instead, we&apos;ll use an older image for NixOS-22.11.&lt;/p&gt;
        &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;--location&lt;/span&gt; https://github.com/nix-community/nixos-images/releases/download/nixos-22.11/nixos-kexec-installer-noninteractive-x86_64-linux.tar.gz | &lt;span class=&quot;nb&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-C&lt;/span&gt; /root &lt;span class=&quot;nt&quot;&gt;-xvzf-&lt;/span&gt;
        /root/kexec/run
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;The machine will restart after a 6 second delay. As before, you can use &lt;code class=&quot;highlighter-rouge&quot;&gt;ping&lt;/code&gt; to watch for the server to come back online. Once it&apos;s up, SSHing again gives us a lovely NixOS prompt.&lt;/p&gt;
        &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;root@nixos ~ &lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;With everything in place now, we can install and configure the actual NixOS system. To start, we need to partition the disks. OVH has a preculiar constraint requiring the boot partition to be on &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/sda&lt;/code&gt; (I&apos;m unsure if this translates over to NVME disks as well).&lt;/p&gt;
        &lt;p&gt;The rest of your disks can be partitioned and merged as needed, but this constrained means it is not possible to have a mirrored boot drive or a mdadm RAID1 boot drive.&lt;/p&gt;
        &lt;p&gt;In the case of this demo server, we only have one disk, we let&apos;s get that set up:&lt;/p&gt;
        &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# lsblk
        NAME  MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
        loop0   7:0    0 341.3M  0 loop /nix/.ro-store
        sda     8:0    0   1.8T  0 disk
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# parted /dev/sda &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; mklabel msdos
        Information: You may need to update /etc/fstab.
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# parted /dev/sda &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; mkpart primary 1MiB 512MiB
        Information: You may need to update /etc/fstab.
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# parted /dev/sda &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; mkpart primary 512MiB 100%
        Information: You may need to update /etc/fstab.
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# lsblk
        NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
        loop0    7:0    0 341.3M  0 loop /nix/.ro-store
        sda      8:0    0   1.8T  0 disk
        ├─sda1   8:1    0   511M  0 part
        └─sda2   8:2    0   1.8T  0 part
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# mkfs.ext4 &lt;span class=&quot;nt&quot;&gt;-L&lt;/span&gt; boot /dev/sda1
        mke2fs 1.46.5 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;30-Dec-2021&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        Creating filesystem with 523264 1k blocks and 130560 inodes
        Filesystem UUID: 53e7efcf-73ba-4145-b503-aab590481958
        Superblock backups stored on blocks:
        8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
        Allocating group tables: &lt;span class=&quot;k&quot;&gt;done
        &lt;/span&gt;Writing inode tables: &lt;span class=&quot;k&quot;&gt;done
        &lt;/span&gt;Creating journal &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;8192 blocks&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;: &lt;span class=&quot;k&quot;&gt;done
        &lt;/span&gt;Writing superblocks and filesystem accounting information: &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# zpool create &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-O&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;mountpoint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;none rpool /dev/sda2
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# zpool list
        NAME    SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
        rpool  1.81T   165K  1.81T        -         -     0%     0%  1.00x    ONLINE  -
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;I&apos;m using ext4 for a BIOS boot parition, and ZFS for the main partition. If multiple disks are present, the above can be tweaked to set up a mirrored ZFS pool.&lt;/p&gt;
        &lt;p&gt;Next, we&apos;re going to mount the partitions and generate the NixOS configuration.&lt;/p&gt;
        &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# zfs create &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;mountpoint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;legacy rpool/root
        zfs create &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;mountpoint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;legacy rpool/root/nixos
        zfs create &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;mountpoint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;legacy rpool/home
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# mount &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; zfs rpool/root/nixos /mnt
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# &lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; /mnt/home
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# mount &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; zfs rpool/home /mnt/home
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# &lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; /mnt/boot
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# mount /dev/sda1 /mnt/boot
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# findmnt
        TARGET                       SOURCE     FSTYPE    OPTIONS
        /                            tmpfs      tmpfs     rw,relatime,mode&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;755
        ├─/dev                       devtmpfs   devtmpfs  rw,nosuid,size&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;200432k,nr_inodes&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;455291,mode&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;755
        │ ├─/dev/pts                 devpts     devpts    rw,nosuid,noexec,relatime,gid&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;3,mode&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;620,ptmxmode&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;666
        │ ├─/dev/shm                 tmpfs      tmpfs     rw,nosuid,nodev
        │ ├─/dev/mqueue              mqueue     mqueue    rw,nosuid,nodev,noexec,relatime
        │ └─/dev/hugepages           hugetlbfs  hugetlbfs rw,relatime,pagesize&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;2M
        ├─/proc                      proc       proc      rw,nosuid,nodev,noexec,relatime
        ├─/run                       tmpfs      tmpfs     rw,nosuid,nodev,size&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1002152k,mode&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;755
        │ ├─/run/keys                ramfs      ramfs     rw,nosuid,nodev,relatime,mode&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;750
        │ ├─/run/wrappers            tmpfs      tmpfs     rw,nodev,relatime,mode&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;755
        │ ├─/run/user/1000           tmpfs      tmpfs     rw,nosuid,nodev,relatime,size&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;400860k,nr_inodes&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;100215,mode
        │ └─/run/user/0              tmpfs      tmpfs     rw,nosuid,nodev,relatime,size&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;400860k,nr_inodes&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;100215,mode
        ├─/sys                       sysfs      sysfs     rw,nosuid,nodev,noexec,relatime
        │ ├─/sys/kernel/security     securityfs securityf rw,nosuid,nodev,noexec,relatime
        │ ├─/sys/fs/cgroup           cgroup2    cgroup2   rw,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursive
        │ ├─/sys/fs/bpf              bpf        bpf       rw,nosuid,nodev,noexec,relatime,mode&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;700
        │ ├─/sys/kernel/debug        debugfs    debugfs   rw,nosuid,nodev,noexec,relatime
        │ ├─/sys/fs/fuse/connections fusectl    fusectl   rw,nosuid,nodev,noexec,relatime
        │ ├─/sys/kernel/config       configfs   configfs  rw,nosuid,nodev,noexec,relatime
        │ └─/sys/fs/pstore           pstore     pstore    rw,nosuid,nodev,noexec,relatime
        ├─/nix/.ro-store             /dev/loop0 squashfs  ro,relatime,errors&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
        ├─/nix/.rw-store             tmpfs      tmpfs     rw,relatime,mode&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;755
        ├─/nix/store                 overlay    overlay   rw,relatime,lowerdir&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/mnt-root/nix/.ro-store,upperdir&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/mnt-
        │ └─/nix/store               overlay    overlay   ro,relatime,lowerdir&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/mnt-root/nix/.ro-store,upperdir&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/mnt-
        └─/mnt                       rpool/root/nixos
        zfs       rw,relatime,xattr,noacl
        ├─/mnt/home                rpool/home zfs       rw,relatime,xattr,noacl
        └─/mnt/boot                /dev/sda1  ext4      rw,relatime
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# nixos-generate-config &lt;span class=&quot;nt&quot;&gt;--root&lt;/span&gt; /mnt
        writing /mnt/etc/nixos/hardware-configuration.nix...
        writing /mnt/etc/nixos/configuration.nix...
        For more hardware-specific settings, see https://github.com/NixOS/nixos-hardware.
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]#
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;After mounting the required ZFS datasets and bootdisk, I confirm everything looks right with &lt;code class=&quot;highlighter-rouge&quot;&gt;findmnt&lt;/code&gt;, and then generate the NixOS configuration.&lt;/p&gt;
        &lt;p&gt;We&apos;re going to make a few changes to the auto-generated configuration. Let&apos;s get &lt;code class=&quot;highlighter-rouge&quot;&gt;vim&lt;/code&gt; by entering into a nix-shell:&lt;/p&gt;
        &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# nix-shell &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; vim
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;Now, we can edit the configuration:&lt;/p&gt;
        &lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/configuration.nix b/configuration.nix
        index b476787..c926f3f 100644
        &lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/configuration.nix
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/configuration.nix
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -17,13 +17,23 @@&lt;/span&gt;
        # boot.loader.grub.efiInstallAsRemovable = true;
        # boot.loader.efi.efiSysMountPoint = &quot;/boot/efi&quot;;
        # Define on which hard drive you want to install Grub.
        &lt;span class=&quot;gd&quot;&gt;-  # boot.loader.grub.device = &quot;/dev/sda&quot;; # or &quot;nodev&quot; for efi only
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+  boot.loader.grub.device = &quot;/dev/sda&quot;; # or &quot;nodev&quot; for efi only
        &lt;/span&gt;
        -  # networking.hostName = &quot;nixos&quot;; # Define your hostname.
        &lt;span class=&quot;gi&quot;&gt;+  networking.hostName = &quot;blog-demo&quot;;
        +  networking.hostId = &quot;12345678&quot;;
        &lt;/span&gt;   # Pick only one of the below networking options.
        # networking.wireless.enable = true;  # Enables wireless support via wpa_supplicant.
        # networking.networkmanager.enable = true;  # Easiest to use and most distros use this by default.
        +  networking.usePredictableInterfaceNames = false;
        &lt;span class=&quot;gi&quot;&gt;+  networking.interfaces.eth0.ipv4.addresses = [{
        +    address = &quot;&amp;lt;ip from console&amp;gt;&quot;;
        +    prefixLength = 24;
        +  }];
        +
        +  networking.defaultGateway = &quot;&amp;lt;gateway from console&amp;gt;&quot;;
        +  networking.nameservers = [ &quot;8.8.8.8&quot; ];
        +
        &lt;/span&gt;   # Set your time zone.
        # time.timeZone = &quot;Europe/Amsterdam&quot;;
        @@ -90,7 +100,11 @@
        # List services that you want to enable:
        # Enable the OpenSSH daemon.
        &lt;span class=&quot;gd&quot;&gt;-  # services.openssh.enable = true;
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+  services.openssh.enable = true;
        +  users.users.root.openssh.authorizedKeys.keys = [
        +    &quot;key1...&quot;
        +    &quot;key2...&quot;
        +  ];
        &lt;/span&gt;
        # Open ports in the firewall.
        # networking.firewall.allowedTCPPorts = [ ... ];
        &lt;span class=&quot;p&quot;&gt;@@ -109,7 +123,7 @@&lt;/span&gt;
        # this value at the release version of the first install of this system.
        # Before changing this value read the documentation for this option
        # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
        &lt;span class=&quot;gd&quot;&gt;-  system.stateVersion = &quot;22.11&quot;; # Did you read the comment?
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+  system.stateVersion = &quot;24.05&quot;; # Did you read the comment?
        &lt;/span&gt;
        }
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;Our changes are to:&lt;/p&gt;
        &lt;ol&gt;
        &lt;li&gt;Install grub to &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/sda&lt;/code&gt;&lt;/li&gt;
        &lt;li&gt;Configure IP address, gateway, and DNS servers based on what OVH provides&lt;/li&gt;
        &lt;li&gt;Enable SSH and add keys to the root user&lt;/li&gt;
        &lt;li&gt;Set the hostname and a random 8 hex character host ID (this is required for ZFS - you can skip &lt;code class=&quot;highlighter-rouge&quot;&gt;hostId&lt;/code&gt; for non-ZFS systems)&lt;/li&gt;
        &lt;li&gt;Update the state version to the latest NixOS release - Since we&apos;re using an old image to work around &lt;code class=&quot;highlighter-rouge&quot;&gt;kexec&lt;/code&gt; issues, we will manually bump up the install to use the latest release.&lt;/li&gt;
        &lt;/ol&gt;
        &lt;p&gt;Lastly, we need to update the &lt;code class=&quot;highlighter-rouge&quot;&gt;nixos&lt;/code&gt; channel to point to the new release:&lt;/p&gt;
        &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# nix-channel &lt;span class=&quot;nt&quot;&gt;--list&lt;/span&gt;
        nixos https://nixos.org/channels/nixos-22.11
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# nix-channel &lt;span class=&quot;nt&quot;&gt;--add&lt;/span&gt; https://nixos.org/channels/nixos-24.05 nixos
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# nix-channel &lt;span class=&quot;nt&quot;&gt;--update&lt;/span&gt;
        unpacking channels...
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]#
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;And with that, we&apos;re ready to install NixOS:&lt;/p&gt;
        &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# nixos-install &lt;span class=&quot;nt&quot;&gt;--root&lt;/span&gt; /mnt
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;This will take a few minutes. Once done, we need to unmount our ZFS pool so it can be cleanly imported by the new system.&lt;/p&gt;
        &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# umount /mnt/boot
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# umount /mnt/home
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# umount /mnt
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;Now all that&apos;s left is to reboot the server and hope for the best. In the OVH console, change the boot configuration to boot from the hard disk, and then reboot the server.&lt;/p&gt;
        &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;root@nixos:~]# reboot
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;Once rebooted, the SSH host key will have changed, so you&apos;ll need to remove it from &lt;code class=&quot;highlighter-rouge&quot;&gt;~/.ssh/known_hosts&lt;/code&gt;, then accept the new key when SSHing in.&lt;/p&gt;
        &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ssh-keygen &lt;span class=&quot;nt&quot;&gt;-R&lt;/span&gt; &amp;lt;ip&amp;gt;
        &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;ssh root@&amp;lt;ip&amp;gt;
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;And that&apos;s it! You should now have a working NixOS system on your OVH server.&lt;/p&gt;
        &lt;h2 id=&quot;all-for-naught&quot;&gt;All for naught&lt;/h2&gt;
        &lt;p&gt;In the end, the OVH system didn&apos;t actually being useful for &lt;a href=&quot;https://burned.money&quot;&gt;burned.money&lt;/a&gt; - the spinning rust was just too slow, estimating ~80 days to import the SQLite backup. Nevertheless, at least I know that NixOS can be run on OVH with a bearable amount of pain.&lt;/p&gt;
        &lt;h2 id=&quot;what-didnt-work&quot;&gt;What didn&apos;t work&lt;/h2&gt;
        &lt;p&gt;Before arriving at this recipe, I tried a number of other methods that didn&apos;t work. For posterity, here they are:&lt;/p&gt;
        &lt;ol&gt;
        &lt;li&gt;Using &lt;code class=&quot;highlighter-rouge&quot;&gt;nixos-infect&lt;/code&gt;&lt;sup id=&quot;fnref:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; - This &lt;em&gt;might&lt;/em&gt; work if you first install a regular Linux system, but with the rescue system being a temporary FS without any disk partitioning, &lt;code class=&quot;highlighter-rouge&quot;&gt;nixos-infect&lt;/code&gt; couldn&apos;t seem to figure out how to install.&lt;/li&gt;
        &lt;li&gt;Using &lt;code class=&quot;highlighter-rouge&quot;&gt;nixos-anywhere&lt;/code&gt;&lt;sup id=&quot;fnref:3&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:3&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; - This relies on &lt;code class=&quot;highlighter-rouge&quot;&gt;kexec&lt;/code&gt;, and as newer &lt;code class=&quot;highlighter-rouge&quot;&gt;kexec&lt;/code&gt; images are broken, at least on OVH, it hung in much the same way as &lt;code class=&quot;highlighter-rouge&quot;&gt;kexec&lt;/code&gt;. That said, it is possible to override&lt;sup id=&quot;fnref:4&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:4&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; the &lt;code class=&quot;highlighter-rouge&quot;&gt;kexec&lt;/code&gt; image used, so it might be possible to use an older image. When trying this out, I didn&apos;t yet know that the &lt;code class=&quot;highlighter-rouge&quot;&gt;kexec&lt;/code&gt; images were unusable, so I didn&apos;t explore that.&lt;/li&gt;
        &lt;li&gt;Using &lt;code class=&quot;highlighter-rouge&quot;&gt;nixos-generators&lt;/code&gt;&lt;sup id=&quot;fnref:5&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:5&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; - In theory, it should be possible to generate an ISO containing my system config, and using OVH&apos;s Custom ISO boot option to install from it. However, it is not currently possible to generate linux ISOs from a MacOS system, and I didn&apos;t go to the effort to trying it via a VM or other server.&lt;/li&gt;
        &lt;/ol&gt;
        &lt;h1 id=&quot;notesreferences&quot;&gt;Notes/references&lt;/h1&gt;
        &lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
        &lt;ol&gt;
        &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
        &lt;p&gt;https://discourse.nixos.org/t/kexec-hangs-on-install/40969 &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li id=&quot;fn:2&quot; role=&quot;doc-endnote&quot;&gt;
        &lt;p&gt;https://github.com/elitak/nixos-infect &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li id=&quot;fn:3&quot; role=&quot;doc-endnote&quot;&gt;
        &lt;p&gt;https://github.com/nix-community/nixos-anywhere &lt;a href=&quot;#fnref:3&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li id=&quot;fn:4&quot; role=&quot;doc-endnote&quot;&gt;
        &lt;p&gt;https://github.com/nix-community/nixos-anywhere/blob/ce18c086d8ca143d43ab20b3db20ab1e3e62c519/docs/howtos/custom-kexec.md &lt;a href=&quot;#fnref:4&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li id=&quot;fn:5&quot; role=&quot;doc-endnote&quot;&gt;
        &lt;p&gt;https://github.com/nix-community/nixos-generators &lt;a href=&quot;#fnref:5&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;/ol&gt;
        &lt;/div&gt;</content><author><name></name></author><category term="nix" /><category term="nixos" /><summary type="html">I&apos;ve been running NixOS servers for a few years now, largely hosting them across a mix of Mini PCs, DigitalOcean, Hetzner, and more recently Contabo.</summary></entry><entry><title type="html">Using Nix flakes and fly.io without Docker</title><link href="https://raghavsood.com//blog/2024/06/14/nix-flakes-fly/" rel="alternate" type="text/html" title="Using Nix flakes and fly.io without Docker" /><published>2024-06-14T00:00:00+00:00</published><updated>2024-06-14T00:00:00+00:00</updated><id>https://raghavsood.com//blog/2024/06/14/nix-flakes-fly</id><content type="html" xml:base="https://raghavsood.com//blog/2024/06/14/nix-flakes-fly/">&lt;p&gt;Admittedly, the title is not entirely accurate - we still use Docker, but successfully get away with not having to install it locally.&lt;/p&gt;
        &lt;p&gt;I&apos;ve reached the point where I refuse to run Docker on my laptop. My typical workflow involves using a Nix flake for every project, usually with &lt;a href=&quot;https://devenv.sh/&quot;&gt;devenv.sh&lt;/a&gt; for some sane defaults.&lt;/p&gt;
        &lt;p&gt;This works great for development - I can easily pull in the languages and services I need, and even run postgres or redis. It&apos;s a clean way to manage different versions and dependencies without deviating far away from a simplistic Nix flake.&lt;/p&gt;
        &lt;p&gt;Recently, while building &lt;a href=&quot;https://burned.money&quot;&gt;burned.money&lt;/a&gt;, I decided to try deploying to &lt;a href=&quot;https://fly.io&quot;&gt;fly.io&lt;/a&gt;. Fly&apos;s done some great work in minimizing idle resources and still ensuring that you can respond in a timely manner when a request comes in. However, it also requires you to provide a Docker image to run on their Fly Machines - lightweight Firecracker based VMs.&lt;/p&gt;
        &lt;p&gt;Fly provides some nice supporting infrastructure around this - you can build your Docker image using Fly Builders, which are just Fly Machines used to build your Docker images. Support for this is built right into the &lt;code class=&quot;highlighter-rouge&quot;&gt;flyctl&lt;/code&gt; CLI tool, which means it is possible to deploy to Fly without having to build your Docker image locally, as long as you can tell them how to build it (generally, by including a &lt;code class=&quot;highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt; in your project).&lt;/p&gt;
        &lt;p&gt;I wanted to make this work well with my existing development workflow - Namely, I wanted to avoid having to maintain a separate build pipeline for Docker and my Nix flake.&lt;/p&gt;
        &lt;p&gt;This turned out to be relatively simple - While building the Docker image, I can use the Nix flake to provide dependencies and build the application. As Nix provides excellent support for binary closures, I can then copy the resulting binary and all of its dependencies into another, minimal layer for deployment.&lt;/p&gt;
        &lt;h2 id=&quot;the-code&quot;&gt;The Code&lt;/h2&gt;
        &lt;p&gt;You can find the sample application for this post in &lt;a href=&quot;https://github.com/RaghavSood/fly-flake-example&quot;&gt;fly-flake-example&lt;/a&gt;.&lt;/p&gt;
        &lt;h2 id=&quot;the-nix-flake&quot;&gt;The Nix flake&lt;/h2&gt;
        &lt;p&gt;To get started, I put together a minimal Nix flake giving me access to the &lt;code class=&quot;highlighter-rouge&quot;&gt;fly&lt;/code&gt; cli tool, and enabling Go as a language.&lt;/p&gt;
        &lt;div class=&quot;language-nix highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;inputs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;nixpkgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;github:NixOS/nixpkgs/nixpkgs-unstable&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;systems&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;github:nix-systems/default&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;devenv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;github:cachix/devenv/1e4701fb1f51f8e6fe3b0318fc2b80aed0761914&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;outputs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;nixpkgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;devenv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;systems&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;forEachSystem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;nixpkgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;lib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;genAttrs&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;systems&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;in&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;devShells&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;forEachSystem&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;pkgs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;nixpkgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;legacyPackages&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;in&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;devenv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;lib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;mkShell&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;inherit&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;inputs&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;pkgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;modules&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;languages&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;enable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;packages&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;pkgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;flyctl&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;enterShell&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;                    echo &quot;fly-flake-example shell activated!&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;                  &apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;With this, I can run &lt;code class=&quot;highlighter-rouge&quot;&gt;nix develop&lt;/code&gt; to drop into a development environment. Of course, this can be a flake without &lt;code class=&quot;highlighter-rouge&quot;&gt;devenv&lt;/code&gt; too - nothing about this is contingent on &lt;code class=&quot;highlighter-rouge&quot;&gt;devenv&lt;/code&gt;.&lt;/p&gt;
        &lt;h2 id=&quot;the-go-application&quot;&gt;The Go application&lt;/h2&gt;
        &lt;p&gt;With the development environment read, we can put together a very simple Go program to run a ping-pong server.&lt;/p&gt;
        &lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;net/http&quot;&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;github.com/gin-gonic/gin&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/ping&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StatusOK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;H&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;pong&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;This will serve as the stand-in for a real application.&lt;/p&gt;
        &lt;p&gt;We&apos;re using Gin instead of &lt;code class=&quot;highlighter-rouge&quot;&gt;net/http&lt;/code&gt; so that we have some actual dependencies in our project - this is important for the next step.&lt;/p&gt;
        &lt;h2 id=&quot;building-the-program-with-nix&quot;&gt;Building the program with Nix&lt;/h2&gt;
        &lt;p&gt;So far, our flake only gives us a shell - before we can build the Dockerfile, we need to be able to have Nix build the binary itself.&lt;/p&gt;
        &lt;p&gt;Flakes support &lt;code class=&quot;highlighter-rouge&quot;&gt;nix build&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;nix run&lt;/code&gt; - we&apos;re going to add some more scaffolding to our flake to allow for &lt;code class=&quot;highlighter-rouge&quot;&gt;nix build&lt;/code&gt; to work.&lt;/p&gt;
        &lt;p&gt;The resulting flake looks like this:&lt;/p&gt;
        &lt;div class=&quot;language-nix highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;inputs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;nixpkgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;github:NixOS/nixpkgs/nixpkgs-unstable&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;systems&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;github:nix-systems/default&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;devenv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;github:cachix/devenv/1e4701fb1f51f8e6fe3b0318fc2b80aed0761914&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;outputs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;nixpkgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;devenv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;systems&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;forEachSystem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;nixpkgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;lib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;genAttrs&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;systems&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;in&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;devShells&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;forEachSystem&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;pkgs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;nixpkgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;legacyPackages&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;in&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;devenv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;lib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;mkShell&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;inherit&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;inputs&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;pkgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;modules&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;languages&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;enable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;packages&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;pkgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;flyctl&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;enterShell&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;                    echo &quot;fly-flake-example shell activated!&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;                  &apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;packages&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;forEachSystem&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;pkgs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;nixpkgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;legacyPackages&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;kn&quot;&gt;in&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;pkgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;buildGoModule&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;fly-flake-example&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;src&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;./.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;vendorHash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;sha256-Ef2XLxGq8TO3WVh9EvLE30Is2CBwH4pqXxkq1tcuR0Q=&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;doCheck&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;Here, we&apos;ve defined a &lt;code class=&quot;highlighter-rouge&quot;&gt;packages&lt;/code&gt; attribute which instructs &lt;code class=&quot;highlighter-rouge&quot;&gt;nix build&lt;/code&gt; to build the Go program - the &lt;code class=&quot;highlighter-rouge&quot;&gt;vendorHash&lt;/code&gt; is defined based on the contents of our &lt;code class=&quot;highlighter-rouge&quot;&gt;go.mod&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;go.sum&lt;/code&gt; (this is why we used Gin - if we only use &lt;code class=&quot;highlighter-rouge&quot;&gt;stdlib&lt;/code&gt; packages with no downloaded dependencies, this should be set to &lt;code class=&quot;highlighter-rouge&quot;&gt;null&lt;/code&gt;)&lt;/p&gt;
        &lt;p&gt;To get the &lt;code class=&quot;highlighter-rouge&quot;&gt;vendorHash&lt;/code&gt; for the first build, or on subsequent updates if your &lt;code class=&quot;highlighter-rouge&quot;&gt;go.sum&lt;/code&gt; changes, you can replace it with an empty string &lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;&quot;&lt;/code&gt;, run &lt;code class=&quot;highlighter-rouge&quot;&gt;nix build&lt;/code&gt;, and copy the correct value from the resulting failure message.&lt;/p&gt;
        &lt;p&gt;Now, we can run &lt;code class=&quot;highlighter-rouge&quot;&gt;nix build&lt;/code&gt; to build the Go program. This produces a Nix closure and puts it in our Nix store, symlinked to the &lt;code class=&quot;highlighter-rouge&quot;&gt;result&lt;/code&gt; symlink in the project directory. We can then run our built program with &lt;code class=&quot;highlighter-rouge&quot;&gt;./result/bin/fly-flake-example&lt;/code&gt;, even without being inside the Go development environment!&lt;/p&gt;
        &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;nix build
        &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-al&lt;/span&gt; result
        lrwxr-xr-x 1 raghavsood staff 61 Jun 14 12:38 result -&amp;gt; /nix/store/ccmb3k660k2pkiq27jbnc92kx3a79cfx-fly-flake-example
        &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./result/bin/fly-flake-example
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;GIN-debug] &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;GIN-debug] &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;WARNING] Running &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;debug&quot;&lt;/span&gt; mode. Switch to &lt;span class=&quot;s2&quot;&gt;&quot;release&quot;&lt;/span&gt; mode &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;production.
        - using &lt;span class=&quot;nb&quot;&gt;env&lt;/span&gt;:	&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GIN_MODE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;release
        - using code:	gin.SetMode&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;gin.ReleaseMode&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;GIN-debug] GET    /ping                     &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; main.main.func1 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;3 handlers&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;GIN-debug] &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;WARNING] You trusted all proxies, this is NOT safe. We recommend you to &lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;a value.
        Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;details.
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;GIN-debug] Listening and serving HTTP on :8080
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;GIN] 2024/06/14 - 12:40:07 | 200 |          85µs |             ::1 | GET      &lt;span class=&quot;s2&quot;&gt;&quot;/ping&quot;&lt;/span&gt;
        ^C
        &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;which go
        go not found
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;Now, we&apos;re ready to assemble the Dockerfile and set up the fly.io project.&lt;/p&gt;
        &lt;h2 id=&quot;fly-launch&quot;&gt;fly launch&lt;/h2&gt;
        &lt;p&gt;We can let Fly go through its default launch flow by just running &lt;code class=&quot;highlighter-rouge&quot;&gt;fly launch&lt;/code&gt; - for many projects, this will auto detect various settings and provide a good starting point. I didn&apos;t modify any of the defaults here, but you may have to tweak them based on your project.&lt;/p&gt;
        &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;fly launch
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;Fly will auto detect common stacks such as Go, Rails, etc. and generate an appropriate &lt;code class=&quot;highlighter-rouge&quot;&gt;fly.toml&lt;/code&gt; - in this case, we get a fairly straightforward one.&lt;/p&gt;
        &lt;div class=&quot;language-toml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# fly.toml app configuration file generated for fly-flake-example on 2024-06-14T12:45:50+08:00&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# See https://fly.io/docs/reference/configuration/ for information about how to use this file.&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;fly-flake-example&apos;&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;primary_region&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;sin&apos;&lt;/span&gt;
        &lt;span class=&quot;nn&quot;&gt;[build]&lt;/span&gt;
        &lt;span class=&quot;nn&quot;&gt;[build.args]&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;GO_VERSION&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;1.22.3&apos;&lt;/span&gt;
        &lt;span class=&quot;nn&quot;&gt;[env]&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;PORT&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;8080&apos;&lt;/span&gt;
        &lt;span class=&quot;nn&quot;&gt;[http_service]&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;internal_port&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8080&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;force_https&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;auto_stop_machines&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;auto_start_machines&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;min_machines_running&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;processes&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;[&apos;app&apos;]&lt;/span&gt;
        &lt;span class=&quot;nn&quot;&gt;[[vm]]&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;1gb&apos;&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;cpu_kind&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;shared&apos;&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;cpus&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;This also generates a &lt;code class=&quot;highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt;, based on our project&apos;s stack and the &lt;code class=&quot;highlighter-rouge&quot;&gt;.gitignore&lt;/code&gt; contents. The auto-generated Dockerfile can be sufficient to build the project, and would look something like this:&lt;/p&gt;
        &lt;div class=&quot;language-Dockerfile highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;ARG&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; GO_VERSION=1&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; golang:${GO_VERSION}-bookworm as builder&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;WORKDIR&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; /usr/src/app&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;COPY&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; go.mod go.sum ./&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;RUN &lt;/span&gt;go mod download &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; go mod verify
        &lt;span class=&quot;k&quot;&gt;COPY&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; . .&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;RUN &lt;/span&gt;go build &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; /run-app .
        &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; debian:bookworm&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;COPY&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; --from=builder /run-app /usr/local/bin/&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;CMD&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; [&quot;run-app&quot;]&lt;/span&gt;
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;h2 id=&quot;using-nix-within-the-dockerfile&quot;&gt;Using Nix within the Dockerfile&lt;/h2&gt;
        &lt;p&gt;To keep our &lt;code class=&quot;highlighter-rouge&quot;&gt;nix build&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt; in sync, we can use the Nix flake to build the binary and then copy it into the Docker image.&lt;/p&gt;
        &lt;p&gt;We can swap out the &lt;code class=&quot;highlighter-rouge&quot;&gt;bookworm&lt;/code&gt; base image with the &lt;code class=&quot;highlighter-rouge&quot;&gt;nixos/nix&lt;/code&gt; image, and then use &lt;code class=&quot;highlighter-rouge&quot;&gt;nix build&lt;/code&gt; to build the binary, then copy the entire closure over into a smaller &lt;code class=&quot;highlighter-rouge&quot;&gt;scratch&lt;/code&gt; image.&lt;/p&gt;
        &lt;div class=&quot;language-Dockerfile highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Use the NixOS base image&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; nixos/nix as builder&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# Set up the Nix environment&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;COPY&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; . /src&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;WORKDIR&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; /src&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;RUN &lt;/span&gt;nix &lt;span class=&quot;se&quot;&gt;\
        &lt;/span&gt;    &lt;span class=&quot;nt&quot;&gt;--extra-experimental-features&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;nix-command flakes&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\
        &lt;/span&gt;    &lt;span class=&quot;nt&quot;&gt;--option&lt;/span&gt; filter-syscalls &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\
        &lt;/span&gt;    build
        &lt;span class=&quot;k&quot;&gt;RUN &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; /tmp/nix-store-closure
        &lt;span class=&quot;k&quot;&gt;RUN &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cp&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-R&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;nix-store &lt;span class=&quot;nt&quot;&gt;-qR&lt;/span&gt; result/&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt; /tmp/nix-store-closure
        &lt;span class=&quot;c&quot;&gt;# Copy the built application to the runtime container&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; scratch&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;WORKDIR&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; /app&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# Copy /nix/store&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;COPY&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; --from=builder /tmp/nix-store-closure /nix/store&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;COPY&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; --from=builder /src/result /app&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;CMD&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; [&quot;/app/bin/fly-flake-example&quot;]&lt;/span&gt;
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;The magic sauce here is the &lt;code class=&quot;highlighter-rouge&quot;&gt;nix-store -qR result/&lt;/code&gt; command, which gives us the closure of the &lt;code class=&quot;highlighter-rouge&quot;&gt;result&lt;/code&gt; symlink. We then copy this closure into a temporary directory, and then copy it into the &lt;code class=&quot;highlighter-rouge&quot;&gt;scratch&lt;/code&gt; image. This gives us all of the dependencies required to run the binary, without having to install them in the image itself.&lt;/p&gt;
        &lt;p&gt;Of course, the &lt;code class=&quot;highlighter-rouge&quot;&gt;scratch&lt;/code&gt; image may be a little too minimal. If you intend to use features like &lt;code class=&quot;highlighter-rouge&quot;&gt;fly console ssh&lt;/code&gt;, you probably want to use a slightly larger base image like &lt;code class=&quot;highlighter-rouge&quot;&gt;alpine&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;debian&lt;/code&gt;.&lt;/p&gt;
        &lt;h2 id=&quot;deploying&quot;&gt;Deploying&lt;/h2&gt;
        &lt;p&gt;With everything in place, a deployment is as simple as running:&lt;/p&gt;
        &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;fly deploy &lt;span class=&quot;nt&quot;&gt;--remote-only&lt;/span&gt;
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;This instructs fly.io to build the image using a remote builder (which is nice, since I don&apos;t have Docker installed locally), and then subsequently deploy it.&lt;/p&gt;
        &lt;p&gt;We can then make any changes to our Nix flake for additional dependencies as the project progresses (such as adding in &lt;code class=&quot;highlighter-rouge&quot;&gt;sqlite&lt;/code&gt;, or &lt;code class=&quot;highlighter-rouge&quot;&gt;tailwindcss&lt;/code&gt;, or anything else we may need), and not have to mess around with the &lt;code class=&quot;highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt; - as long as &lt;code class=&quot;highlighter-rouge&quot;&gt;nix build&lt;/code&gt; produces the binary, the Docker image will be built correctly.&lt;/p&gt;
        &lt;h2 id=&quot;using-nix-to-build-docker-images&quot;&gt;Using Nix to build Docker images&lt;/h2&gt;
        &lt;p&gt;It is, of course, possible to use Nix to build a Docker image directly, as opposed to running &lt;code class=&quot;highlighter-rouge&quot;&gt;nix build&lt;/code&gt; during the Docker build. However, given that I don&apos;t run Docker locally, this is a little less useful for me.&lt;/p&gt;
        &lt;p&gt;If this seems like a better fit for you, you may be interested in reading up on &lt;a href=&quot;https://nix.dev/tutorials/nixos/building-and-running-docker-images.html&quot; target=&quot;_blank&quot;&gt;dockerTools.buildImage&lt;/a&gt;. Note that this only builds the image, and doing anything useful with it, such as pushing it to a registry, will require you to run Docker locally and interact with it like a regular image.&lt;/p&gt;
        &lt;h3 id=&quot;notesreferences&quot;&gt;Notes/References&lt;/h3&gt;
        &lt;p&gt;A special thanks to &lt;a href=&quot;https://blog.trishtzy.com/&quot; target=&quot;_blank&quot;&gt;Tricia Tan&lt;/a&gt; for reviewing this post and providing feedback.&lt;/p&gt;</content><author><name></name></author><category term="nix" /><category term="nixpkgs" /><category term="fly.io" /><summary type="html">Admittedly, the title is not entirely accurate - we still use Docker, but successfully get away with not having to install it locally.</summary></entry><entry><title type="html">Contributing to nixpkgs - Part 1 - Basic Contributions</title><link href="https://raghavsood.com//blog/2024/05/20/contributing-to-nixpkgs-basics/" rel="alternate" type="text/html" title="Contributing to nixpkgs - Part 1 - Basic Contributions" /><published>2024-05-20T00:00:00+00:00</published><updated>2024-05-20T00:00:00+00:00</updated><id>https://raghavsood.com//blog/2024/05/20/contributing-to-nixpkgs-basics</id><content type="html" xml:base="https://raghavsood.com//blog/2024/05/20/contributing-to-nixpkgs-basics/">&lt;p&gt;For many, contributing to &lt;a href=&quot;https://github.com/NixOS/nixpkgs&quot;&gt;nixpkgs&lt;/a&gt; can be a daunting task - the repository is extremely active, with thousands of PRs going in every week. With the breadth of what&apos;s included in nixpkgs spanning everything from bootstrapping an OS install to npm packages, it can be hard to know where to start.&lt;/p&gt;
        &lt;p&gt;This is the first in a series of posts on how to effectively contribute to nixpkgs. It helps you avoid common pitfalls and approach things in a manner that are easier to review and less likely to break things.&lt;/p&gt;
        &lt;h2 id=&quot;how-is-nixpkgs-structured&quot;&gt;How is nixpkgs structured?&lt;/h2&gt;
        &lt;p&gt;Nixpkgs is a monorepo, containing all the packages and infrastructure needed to build the NixOS and nixpkgs ecosystem. It&apos;s structured in a way that makes it easy to add new packages and update existing ones.&lt;/p&gt;
        &lt;p&gt;The root of the repo contains only a handful of directories:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;tree &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-L&lt;/span&gt; 1
        &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
        ├── doc
        ├── lib
        ├── maintainers
        ├── nixos
        ├── pkgs&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;As a first-time contributor, you don&apos;t need to go too deep. Just know that:&lt;/p&gt;
        &lt;ul&gt;
        &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;doc&lt;/code&gt; contains the documenation used to generate the &lt;a href=&quot;https://nixos.org/manual/nixpkgs/stable/&quot;&gt;nixpkgs manual&lt;/a&gt;. As someone updating and adding packages, you generally don&apos;t need to change anything here.&lt;/li&gt;
        &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;lib&lt;/code&gt; contains helpful functions and utilities used to compose packages and other information about them. Once again, not a common entrypoint for first-time contributors.&lt;/li&gt;
        &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;maintainers&lt;/code&gt; contains a list of known-maintainers who look after certain package or areas of the repository, as well as helpful scripts for common maintenance tasks such as updates and listings. If you wish to add a new package, or adopt an existing one, you would need to create an entry for yourself in &lt;code class=&quot;highlighter-rouge&quot;&gt;maintainers/maintainer-list.nix&lt;/code&gt;.&lt;/li&gt;
        &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;nixos&lt;/code&gt; contains the NixOS module system, which is used to configure NixOS systems. Some packages have associated NixOS modules that may require updates when the package is updated.&lt;/li&gt;
        &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;pkgs&lt;/code&gt; is where the magic happens. This directory contains all the packages in nixpkgs, organized by category. This is where you&apos;ll be spending most of your time.&lt;/li&gt;
        &lt;/ul&gt;
        &lt;h2 id=&quot;finding-something-to-contribute&quot;&gt;Finding something to contribute&lt;/h2&gt;
        &lt;p&gt;There are a few ways to make a meaningful contribution. Most folks start out by updating a package they use, or fixing a bug they&apos;re running into.&lt;/p&gt;
        &lt;p&gt;If you already have a contribution in mind, you can skip this section. If you&apos;re looking for something to work on, here are a few ways to find something:&lt;/p&gt;
        &lt;ul&gt;
        &lt;li&gt;&lt;strong&gt;Look for issues&lt;/strong&gt;: The &lt;a href=&quot;https://github.com/NixOS/nixpkgs/issues&quot;&gt;nixpkgs issue tracker&lt;/a&gt; has frequent requests for new package additions or updates. Scrolling through this list can provide some opportunities.[[If you pick an open issue, make sure to mention &lt;code class=&quot;highlighter-rouge&quot;&gt;Closes #123&lt;/code&gt; in your PR description to automatically close the issue when the PR is merged.::lsn]]&lt;/li&gt;
        &lt;li&gt;&lt;strong&gt;Check failing builds&lt;/strong&gt;: Visit Hydra&apos;s latest build for &lt;a href=&quot;https://hydra.nixos.org/jobset/nixpkgs/trunk/evals&quot;&gt;nixpkgs#trunk&lt;/a&gt; and take a look at the &lt;code class=&quot;highlighter-rouge&quot;&gt;Newly Failing Jobs&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;Still Failing Jobs&lt;/code&gt; to see if anything looks interesting.&lt;/li&gt;
        &lt;li&gt;&lt;strong&gt;Contribute without code&lt;/strong&gt;: There are countless opportunities for things such as documenation improvements, PR review, and other general tasks. We won&apos;t touch upon these in this post, but you can filter pull requests by tags such as &lt;a href=&quot;https://github.com/NixOS/nixpkgs/pulls?q=is%3Aopen+is%3Apr+label%3A%228.has%3A+documentation%22&quot;&gt;has: documenation&lt;/a&gt; to see how others are making such contributions.&lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;Once you&apos;ve identified something to work on, it&apos;s time to get started. For this post, we&apos;ll be updating the &lt;code class=&quot;highlighter-rouge&quot;&gt;flyctl&lt;/code&gt; package to the latest version.&lt;/p&gt;
        &lt;h2 id=&quot;getting-set-up&quot;&gt;Getting set up&lt;/h2&gt;
        &lt;p&gt;&lt;em&gt;We&apos;re going to assume you already have &lt;a href=&quot;https://nix.dev/install-nix.html&quot;&gt;Nix installed&lt;/a&gt;, or are using NixOS.&lt;/em&gt;&lt;/p&gt;
        &lt;p&gt;The first step is to fork the nixpkgs repository. This is done by visiting the &lt;a href=&quot;https://github.com/NixOS/nixpkgs&quot;&gt;nixpkgs repository&lt;/a&gt; and clicking the &lt;code class=&quot;highlighter-rouge&quot;&gt;Fork&lt;/code&gt; button in the top right corner.&lt;/p&gt;
        &lt;p&gt;Forking can take a moment as it is a large repository.&lt;/p&gt;
        &lt;p&gt;Once you have your fork, you can clone it locally. We&apos;re also going to want to add the main nixpkgs repository as a remote, so we can pull in changes from upstream.&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git clone git@github.com/&amp;lt;your-username&amp;gt;/nixpkgs.git          &lt;span class=&quot;c&quot;&gt;# This can be slow since it&apos;s a multi-gigabyte repository&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;nixpkgs
        &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git remote add upstream git@github.com:NixOS/nixpkgs.git
        &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git remote &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git pull upstream master                                      &lt;span class=&quot;c&quot;&gt;# Pull in the latest changes from upstream - do this each time before you start something new&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;To ensure everything is in order, let&apos;s run a quick build command:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;nix-build &lt;span class=&quot;nt&quot;&gt;-A&lt;/span&gt; flyctl&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;This may not actually build anything for you - nixpkgs is heavily cached, and since we haven&apos;t updated the version yet this will likely just pull the existing binary from the cache.&lt;/p&gt;
        &lt;h2 id=&quot;basic-contribution-workflow&quot;&gt;Basic contribution workflow&lt;/h2&gt;
        &lt;p&gt;When contributing to a large, living repository like nixpkgs, there&apos;s a few things to watch out for:&lt;/p&gt;
        &lt;ol&gt;
        &lt;li&gt;Follow the commit and style standards - most repositories have these defined in the README or CONTRIBUTING file, or in a wiki for the project.&lt;/li&gt;
        &lt;li&gt;Every commit is one unit of work - It should be easy to revert a single change without undoing an entire PR worth of work, especially if a PR touches multiple things.&lt;/li&gt;
        &lt;li&gt;There may be tooling you can use - nixpkgs, and the broader Nix ecosystem, does have a variety of bots and other tooling that can be used to simplify or cross-check your work.&lt;/li&gt;
        &lt;li&gt;When in doubt, ask - it&apos;s always easier to show your approach and ask for feedback, than to post an open ended &quot;How do I X?&quot; question. Members will be able to give more focused and helpful answers, as well as specific feedback on why your approach wasn&apos;t the preferred option.&lt;/li&gt;
        &lt;li&gt;Read &lt;a href=&quot;https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md&quot;&gt;CONTRIBUTING.md&lt;/a&gt;, &lt;a href=&quot;https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md&quot;&gt;pkgs/README.md&lt;/a&gt;, and the respective section of the manual for whichever language/stack you&apos;re updating packages in (for example, for this post, that&apos;s the &lt;a href=&quot;https://nixos.org/manual/nixpkgs/stable/#ssec-language-go&quot;&gt;Go section&lt;/a&gt;).&lt;/li&gt;
        &lt;/ol&gt;
        &lt;h2 id=&quot;optional-becoming-a-maintainer&quot;&gt;[Optional] Becoming a maintainer&lt;/h2&gt;
        &lt;p&gt;If you plan on becoming a listed maintainer for any package, it&apos;s best to do this step first - maintainer tracking in nixpkgs is done by evaluating a Nix expression, so you must be declared in the maintainer list before being added to a package or team.[[Listed maintainers are automatically tagged for Code Review by much of the automated tooling, such as GitHub and OfBorg.::rmn]]&lt;/p&gt;
        &lt;p&gt;To do this, you need to add an entry to &lt;code class=&quot;highlighter-rouge&quot;&gt;maintainers/maintainer-list.nix&lt;/code&gt;. This file is a list of maintainers, with each maintainer having a name, email, and a contain method.&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-nix&quot; data-lang=&quot;nix&quot;&gt;&lt;span class=&quot;nv&quot;&gt;handle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Your Name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;                       &lt;span class=&quot;c&quot;&gt;# Required&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;github&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;your-github-username&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;          &lt;span class=&quot;c&quot;&gt;# Required&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;email&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;hello@example.com&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;              &lt;span class=&quot;c&quot;&gt;# At least one&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;githubId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;12345678&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;                    &lt;span class=&quot;c&quot;&gt;# At least one&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;matrixId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;@your-matrix-id:matrix.org&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# At least one&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;keys&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;                                 &lt;span class=&quot;c&quot;&gt;# Optional&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;fingerprint&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;1234 5678 9ABC DEF0 1234 5678 9ABC DEF0 1234 5678&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;You can fetch your &lt;code class=&quot;highlighter-rouge&quot;&gt;githubId&lt;/code&gt; by visiting &lt;a href=&quot;https://api.github.com/users/&amp;lt;your-github-username&amp;gt;&quot;&gt;https://api.github.com/users/&amp;lt;your-github-username&amp;gt;&lt;/a&gt;. This will return a JSON object with your user details, including your &lt;code class=&quot;highlighter-rouge&quot;&gt;id&lt;/code&gt;.&lt;/p&gt;
        &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;handle&lt;/code&gt; does not have to match your GitHub username, but conventionally it does.&lt;/p&gt;
        &lt;p&gt;The entries in the file are sorted alphabetically by the &lt;code class=&quot;highlighter-rouge&quot;&gt;handle&lt;/code&gt; field, so make sure to insert your entry in the correct place.&lt;/p&gt;
        &lt;p&gt;Once you&apos;ve added your entry, it&apos;s time to commit!&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git checkout &lt;span class=&quot;nt&quot;&gt;-b&lt;/span&gt; maintainers/add-&amp;lt;handle&amp;gt;
        &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git add maintainers/maintainer-list.nix
        &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git commit &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;maintainers: add &amp;lt;handle&amp;gt;&quot;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git push origin HEAD&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;Now you can open a PR to add yourself as a maintainer. It&apos;s also possible to do this as one commit that is part of a larger PR. However, if you take that route, ensure:&lt;/p&gt;
        &lt;ol&gt;
        &lt;li&gt;The commit adding yourself as a maintainer is the first commit in the PR.&lt;/li&gt;
        &lt;li&gt;The focus of the PR is on the package being updated or added.&lt;/li&gt;
        &lt;/ol&gt;
        &lt;p&gt;A good PR which includes maintainer updates will look something like:&lt;/p&gt;
        &lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;maintainers: add RaghavSood
        flyctl: 0.0.1 -&amp;gt; 0.0.2
        flyctl: add RaghavSood as maintainer
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
        &lt;p&gt;By splitting each change into its own, clearly delineated commit, it is easier for reviewers to evaluate. Additionally, in the event that the package update needs to be reverted, it can be done without affecting the maintainer changes.&lt;/p&gt;
        &lt;h2 id=&quot;updating-the-package&quot;&gt;Updating the package&lt;/h2&gt;
        &lt;p&gt;Within nixpkgs many wrappers and build systems exist to make it easier to package different kinds of applications. For basic packages, the &lt;code class=&quot;highlighter-rouge&quot;&gt;stdenv.mkDerivation&lt;/code&gt; function is used. Go has &lt;code class=&quot;highlighter-rouge&quot;&gt;buildGoModule&lt;/code&gt;, Python has &lt;code class=&quot;highlighter-rouge&quot;&gt;buildPythonPackage&lt;/code&gt;, and so on.&lt;/p&gt;
        &lt;p&gt;A trivial update to a package will generally follow the same recipe, regardless of the language or build system used:&lt;/p&gt;
        &lt;ol&gt;
        &lt;li&gt;Update the version or revision of the package to point to the desired version.&lt;/li&gt;
        &lt;li&gt;Update any hashes (within &lt;code class=&quot;highlighter-rouge&quot;&gt;src&lt;/code&gt;, or for build requirements like go modules or cargo crates) to match their new state.&lt;/li&gt;
        &lt;li&gt;If required, update any dependencies or inputs.&lt;/li&gt;
        &lt;li&gt;Fix any tests, build issues, or other problems that arise from the update.&lt;/li&gt;
        &lt;li&gt;If required, do some housekeeping by removing any inputs, patches, or other now-useless parts of the derivation.[[A nix derivation is a Nix program that describes how to achieve a specific task, such as building a package.::rmn]]&lt;/li&gt;
        &lt;/ol&gt;
        &lt;p&gt;In this post, we&apos;re simply going to make a trivial update that requires no fixes.&lt;/p&gt;
        &lt;p&gt;As of writing, the &lt;code class=&quot;highlighter-rouge&quot;&gt;flyctl&lt;/code&gt; package in nixpkgs is at version 0.2.52, while the latest upstream version is 0.2.55. It&apos;s a Go package, so we need to:&lt;/p&gt;
        &lt;ol&gt;
        &lt;li&gt;Update the version&lt;/li&gt;
        &lt;li&gt;Update the &lt;code class=&quot;highlighter-rouge&quot;&gt;src&lt;/code&gt; hash&lt;/li&gt;
        &lt;li&gt;Update the go module hash&lt;/li&gt;
        &lt;/ol&gt;
        &lt;p&gt;Updating the version is easy enough - we simply change the &lt;code class=&quot;highlighter-rouge&quot;&gt;version&lt;/code&gt; field in the derivation:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/pkgs/development/web/flyctl/default.nix b/pkgs/development/web/flyctl/default.nix
        index 8ca6eca5268b..24f523242cea 100644
        &lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/pkgs/development/web/flyctl/default.nix
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/pkgs/development/web/flyctl/default.nix
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -2,7 +2,7 @@&lt;/span&gt;
        buildGo122Module rec {
        pname = &quot;flyctl&quot;;
        &lt;span class=&quot;gd&quot;&gt;-  version = &quot;0.2.52&quot;;
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+  version = &quot;0.2.55&quot;;
        &lt;/span&gt;
        src = fetchFromGitHub {
        owner = &quot;superfly&quot;;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;To get the updated &lt;code class=&quot;highlighter-rouge&quot;&gt;src&lt;/code&gt; hash, we have a few options. For most derivations, including &lt;code class=&quot;highlighter-rouge&quot;&gt;flyctl&lt;/code&gt;, the source is downloaded from an archive hosted on GitHub or Gitlab or other service. These have a predictable, defined URL, which can be used to fetch the source and calculate the hash using the &lt;code class=&quot;highlighter-rouge&quot;&gt;nix-prefetch-url&lt;/code&gt; command. Since the derivation uses the unpacked code, we must ask &lt;code class=&quot;highlighter-rouge&quot;&gt;nip-prefetch-url&lt;/code&gt; to unpack the source:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;nix-prefetch-url &lt;span class=&quot;nt&quot;&gt;--unpack&lt;/span&gt; https://github.com/superfly/flyctl/archive/v0.2.55.tar.gz
        117zl6pg9flr2ffhfjfy8a8svdc2gwd4s81vdgkb0lilmlbml968&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;This gives us the hash in the old, base32 format. However, current standards[^4] require that hashes in nixpkgs follow the SRI format. We can convert the hash using the &lt;code class=&quot;highlighter-rouge&quot;&gt;nix-hash&lt;/code&gt; command:[[&lt;code class=&quot;highlighter-rouge&quot;&gt;nixpkgs&lt;/code&gt; is an incredibly large, complex intersection of thousands of contributors. Standards and styles change often, and it is common to find code in the repo that is written in an old manner. To ensure you&apos;re following the latest standards, it&apos;s best to refer to the latest PRs and commits in the repository that touch similar areas and read the description and reviews.::rmn]]&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;nix-hash &lt;span class=&quot;nt&quot;&gt;--to-sri&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--type&lt;/span&gt; sha256 117zl6pg9flr2ffhfjfy8a8svdc2gwd4s81vdgkb0lilmlbml968
        sha256-yCRaF600UrDmazsgTRp/grWtkULeSQedE5m69K6h/4Q&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;While this approach works, some people find it cumbersome - moreover, it doesn&apos;t work well if you are cloning the repository over git, or have another source type that isn&apos;t just a simple file.&lt;/p&gt;
        &lt;p&gt;A more common, albeit slightly &quot;hacky&quot; approach is to intentionally put the wrong hash in the derivation, and let &lt;code class=&quot;highlighter-rouge&quot;&gt;nix-build&lt;/code&gt; throw an error and fail. This will give you the correct hash to use. To do this, we can replace the &lt;code class=&quot;highlighter-rouge&quot;&gt;src.hash&lt;/code&gt; attribute with an empty string &lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;&quot;&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;lib.fakeHash&lt;/code&gt;:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/pkgs/development/web/flyctl/default.nix b/pkgs/development/web/flyctl/default.nix
        index 8ca6eca5268b..244802befee4 100644
        &lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/pkgs/development/web/flyctl/default.nix
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/pkgs/development/web/flyctl/default.nix
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -2,13 +2,13 @@&lt;/span&gt;
        buildGo122Module rec {
        pname = &quot;flyctl&quot;;
        &lt;span class=&quot;gd&quot;&gt;-  version = &quot;0.2.52&quot;;
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+  version = &quot;0.2.55&quot;;
        &lt;/span&gt; 
        src = fetchFromGitHub {
        owner = &quot;superfly&quot;;
        repo = &quot;flyctl&quot;;
        rev = &quot;v${version}&quot;;
        &lt;span class=&quot;gd&quot;&gt;-    hash = &quot;sha256-BCnMXyS94tuD+Un1DLqs3mdGi7XrVBoZGJ/XkpACOQI&quot;;
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+    hash = lib.fakeHash;
        &lt;/span&gt;   };&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;Now, running &lt;code class=&quot;highlighter-rouge&quot;&gt;nix-build -A flyctl&lt;/code&gt; will produce an error and provide us with the correct hash:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;nix-build &lt;span class=&quot;nt&quot;&gt;-A&lt;/span&gt; flyctl
        these 3 derivations will be built:
        /nix/store/31l3mhp8rvgphz5gn1q62x7j03ryrcpd-source.drv
        /nix/store/3ygzq80kxg7nk9fkk3lp7mq06dmg9ax7-flyctl-0.2.55-go-modules.drv
        /nix/store/x0i067rpc1h5mvhrb1qadwh1vrx3mnal-flyctl-0.2.55.drv
        building &lt;span class=&quot;s1&quot;&gt;&apos;/nix/store/31l3mhp8rvgphz5gn1q62x7j03ryrcpd-source.drv&apos;&lt;/span&gt;...
        trying https://github.com/superfly/flyctl/archive/v0.2.55.tar.gz
        % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
        Dload  Upload   Total   Spent    Left  Speed
        0     0    0     0    0     0      0      0 &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt;:--:-- &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt;:--:-- &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt;:--:--     0
        100 1662k    0 1662k    0     0   547k      0 &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt;:--:--  0:00:03 &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt;:--:--  993k
        unpacking &lt;span class=&quot;nb&quot;&gt;source &lt;/span&gt;archive /private/tmp/nix-build-source.drv-0/v0.2.55.tar.gz
        error: &lt;span class=&quot;nb&quot;&gt;hash &lt;/span&gt;mismatch &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;fixed-output derivation &lt;span class=&quot;s1&quot;&gt;&apos;/nix/store/31l3mhp8rvgphz5gn1q62x7j03ryrcpd-source.drv&apos;&lt;/span&gt;:
        specified: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
        got:    sha256-yCRaF600UrDmazsgTRp/grWtkULeSQedE5m69K6h/4Q&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;Go modules are fixed against the &lt;code class=&quot;highlighter-rouge&quot;&gt;vendorHash&lt;/code&gt; attribute in &lt;code class=&quot;highlighter-rouge&quot;&gt;buildGoModule&lt;/code&gt; derivations. Unfortunately, there is no equivalent to &lt;code class=&quot;highlighter-rouge&quot;&gt;nix-prefetch-url&lt;/code&gt; for go modules, so the easiest way to get the new hash is to set it to &lt;code class=&quot;highlighter-rouge&quot;&gt;lib.fakeHash&lt;/code&gt; and try a build.&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/pkgs/development/web/flyctl/default.nix b/pkgs/development/web/flyctl/default.nix
        index 8ca6eca5268b..03d1b79f1810 100644
        &lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/pkgs/development/web/flyctl/default.nix
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/pkgs/development/web/flyctl/default.nix
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -2,16 +2,16 @@&lt;/span&gt;
        buildGo122Module rec {
        pname = &quot;flyctl&quot;;
        &lt;span class=&quot;gd&quot;&gt;-  version = &quot;0.2.52&quot;;
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+  version = &quot;0.2.55&quot;;
        &lt;/span&gt;
        src = fetchFromGitHub {
        owner = &quot;superfly&quot;;
        repo = &quot;flyctl&quot;;
        rev = &quot;v${version}&quot;;
        &lt;span class=&quot;gd&quot;&gt;-    hash = &quot;sha256-BCnMXyS94tuD+Un1DLqs3mdGi7XrVBoZGJ/XkpACOQI&quot;;
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+    hash = &quot;sha256-yCRaF600UrDmazsgTRp/grWtkULeSQedE5m69K6h/4Q=&quot;;
        &lt;/span&gt;   };
        -  vendorHash = &quot;sha256-eTiY65VGFBgGzCOrnp/WbOo9Lbdk4PYwT7CppjsZ4WE=&quot;;
        &lt;span class=&quot;gi&quot;&gt;+  vendorHash = lib.fakeHash;
        &lt;/span&gt;
        subPackages = [ &quot;.&quot; ];&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;Once again, &lt;code class=&quot;highlighter-rouge&quot;&gt;nix-build -A flyctl&lt;/code&gt; helpfully tells us the expected hash:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;nix-build &lt;span class=&quot;nt&quot;&gt;-A&lt;/span&gt; flyctl
        &lt;span class=&quot;c&quot;&gt;# some output omitted&lt;/span&gt;
        error: &lt;span class=&quot;nb&quot;&gt;hash &lt;/span&gt;mismatch &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;fixed-output derivation &lt;span class=&quot;s1&quot;&gt;&apos;/nix/store/z6xdjn6aikaaw3z364jrixr5z9jx07zl-flyctl-0.2.55-go-modules.drv&apos;&lt;/span&gt;:
        specified: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
        got:    sha256-1hlWyr41t8J4naN5QbEtfCv3npe/kvMH5NKKaxYvLYk&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;And that&apos;s it! We now have everything we need for a updated, successful build:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/pkgs/development/web/flyctl/default.nix b/pkgs/development/web/flyctl/default.nix
        index 8ca6eca5268b..b0bf00051840 100644
        &lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/pkgs/development/web/flyctl/default.nix
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/pkgs/development/web/flyctl/default.nix
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -2,16 +2,16 @@&lt;/span&gt;
        buildGo122Module rec {
        pname = &quot;flyctl&quot;;
        &lt;span class=&quot;gd&quot;&gt;-  version = &quot;0.2.52&quot;;
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+  version = &quot;0.2.55&quot;;
        &lt;/span&gt;
        src = fetchFromGitHub {
        owner = &quot;superfly&quot;;
        repo = &quot;flyctl&quot;;
        rev = &quot;v${version}&quot;;
        &lt;span class=&quot;gd&quot;&gt;-    hash = &quot;sha256-BCnMXyS94tuD+Un1DLqs3mdGi7XrVBoZGJ/XkpACOQI&quot;;
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+    hash = &quot;sha256-yCRaF600UrDmazsgTRp/grWtkULeSQedE5m69K6h/4Q=&quot;;
        &lt;/span&gt;   };
        -  vendorHash = &quot;sha256-eTiY65VGFBgGzCOrnp/WbOo9Lbdk4PYwT7CppjsZ4WE=&quot;;
        &lt;span class=&quot;gi&quot;&gt;+  vendorHash = &quot;sha256-1hlWyr41t8J4naN5QbEtfCv3npe/kvMH5NKKaxYvLYk=&quot;;
        &lt;/span&gt;
        subPackages = [ &quot;.&quot; ];&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;… or do we?&lt;/p&gt;
        &lt;p&gt;Although this was supposed to be a trivial update, it turns out we have a failing test&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;Running phase: checkPhase
        ?       github.com/superfly/flyctl      &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;no &lt;span class=&quot;nb&quot;&gt;test &lt;/span&gt;files]
        ?       github.com/superfly/flyctl      &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;no &lt;span class=&quot;nb&quot;&gt;test &lt;/span&gt;files]
        ?       github.com/superfly/flyctl/agent        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;no &lt;span class=&quot;nb&quot;&gt;test &lt;/span&gt;files]
        ?       github.com/superfly/flyctl/agent/internal/proto &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;no &lt;span class=&quot;nb&quot;&gt;test &lt;/span&gt;files]
        ?       github.com/superfly/flyctl/agent/server &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;no &lt;span class=&quot;nb&quot;&gt;test &lt;/span&gt;files]
        ?       github.com/superfly/flyctl/cmd/audit    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;no &lt;span class=&quot;nb&quot;&gt;test &lt;/span&gt;files]
        ?       github.com/superfly/flyctl/doc  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;no &lt;span class=&quot;nb&quot;&gt;test &lt;/span&gt;files]
        ?       github.com/superfly/flyctl/flyctl       &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;no &lt;span class=&quot;nb&quot;&gt;test &lt;/span&gt;files]
        ?       github.com/superfly/flyctl/flypg        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;no &lt;span class=&quot;nb&quot;&gt;test &lt;/span&gt;files]
        ?       github.com/superfly/flyctl/gql  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;no &lt;span class=&quot;nb&quot;&gt;test &lt;/span&gt;files]
        ok      github.com/superfly/flyctl/helpers      0.393s
        &lt;span class=&quot;nt&quot;&gt;---&lt;/span&gt; FAIL: TestToTestMachineConfig &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0.00s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        panic: runtime error: invalid memory address or nil pointer dereference &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;recovered]
        panic: runtime error: invalid memory address or nil pointer dereference
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;signal SIGSEGV: segmentation violation &lt;span class=&quot;nv&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0x2 &lt;span class=&quot;nv&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0xa8 &lt;span class=&quot;nv&quot;&gt;pc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0x1034f24cc]
        goroutine 38 &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;running]:
        testing.tRunner.func1.2&lt;span class=&quot;o&quot;&gt;({&lt;/span&gt;0x1038acac0, 0x1041d6000&lt;span class=&quot;o&quot;&gt;})&lt;/span&gt;
        /nix/store/460vdyz0ghxh8n5ibq3fgc3s63is68cd-go-1.22.2/share/go/src/testing/testing.go:1631 +0x1c4
        testing.tRunner.func1&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
        /nix/store/460vdyz0ghxh8n5ibq3fgc3s63is68cd-go-1.22.2/share/go/src/testing/testing.go:1634 +0x33c
        panic&lt;span class=&quot;o&quot;&gt;({&lt;/span&gt;0x1038acac0?, 0x1041d6000?&lt;span class=&quot;o&quot;&gt;})&lt;/span&gt;
        /nix/store/460vdyz0ghxh8n5ibq3fgc3s63is68cd-go-1.22.2/share/go/src/runtime/panic.go:770 +0x124
        github.com/superfly/flyctl/internal/appconfig.&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;Config&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;.ToTestMachineConfig&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0x14000421980, 0x140003971d0, 0x0&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        /private/tmp/nix-build-flyctl-0.2.55.drv-1/source/internal/appconfig/machines.go:153 +0x59c
        github.com/superfly/flyctl/internal/appconfig.TestToTestMachineConfig&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0x14000403040&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        /private/tmp/nix-build-flyctl-0.2.55.drv-1/source/internal/appconfig/machines_test.go:210 +0x51c
        testing.tRunner&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0x14000403040, 0x1039e59a0&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        /nix/store/460vdyz0ghxh8n5ibq3fgc3s63is68cd-go-1.22.2/share/go/src/testing/testing.go:1689 +0xec
        created by testing.&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;T&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;.Run &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;goroutine 1
        /nix/store/460vdyz0ghxh8n5ibq3fgc3s63is68cd-go-1.22.2/share/go/src/testing/testing.go:1742 +0x318
        FAIL    github.com/superfly/flyctl/internal/appconfig   0.355s&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;It turns out that &lt;a href=&quot;https://github.com/superfly/flyctl/pull/3430&quot;&gt;one of&lt;/a&gt; the changes between 0.2.52 and 0.2.55 added some tests that require network access. Since we&apos;re building in a sandboxed environment.[[Derivations in &lt;code class=&quot;highlighter-rouge&quot;&gt;nixpkgs&lt;/code&gt; are built in a sandbox with no network or filesystem access. Anything required by your program, such as dependencies (NPM packages, go modules, config files, etc.) must be explicitly provided. &lt;code class=&quot;highlighter-rouge&quot;&gt;buildGoModules&lt;/code&gt; already provides a wrapper to download go moduels from the internet and pin them using &lt;code class=&quot;highlighter-rouge&quot;&gt;vendorHash&lt;/code&gt;. However, if tests or other parts of the build process require network access, they will have to be skipped or patched to avoid it.::rmn]]&lt;/p&gt;
        &lt;p&gt;We can fix this by disabling the tests. &lt;code class=&quot;highlighter-rouge&quot;&gt;buildGoModule&lt;/code&gt; helpfully provides &lt;a href=&quot;https://github.com/NixOS/nixpkgs/blob/d616253e70a3476874d86974e9ef1d20629f6ab0/doc/languages-frameworks/go.section.md?plain=1#L255C21-L255C40&quot;&gt;a few options&lt;/a&gt; to remove tests from the checkPhase.&lt;/p&gt;
        &lt;p&gt;Unfortunately, the test setup for go packages doesn&apos;t quite support the common &lt;code class=&quot;highlighter-rouge&quot;&gt;go test ./...&lt;/code&gt; pattern, so we also need to override the &lt;code class=&quot;highlighter-rouge&quot;&gt;checkPhase&lt;/code&gt; step of the build process.[[A build consists of &lt;a href=&quot;https://nixos.org/manual/nixpkgs/stable/#sec-stdenv-phases&quot;&gt;multiple phases&lt;/a&gt;.::lsn]]&lt;/p&gt;
        &lt;p&gt;By disabling all of the &lt;code class=&quot;highlighter-rouge&quot;&gt;TestToTestMachineConfig&lt;/code&gt; tests, we can get a successful build.&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/pkgs/development/web/flyctl/default.nix b/pkgs/development/web/flyctl/default.nix
        index 8ca6eca5268b..2683203a79ca 100644
        &lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/pkgs/development/web/flyctl/default.nix
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/pkgs/development/web/flyctl/default.nix
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -2,16 +2,16 @@&lt;/span&gt;
        buildGo122Module rec {
        pname = &quot;flyctl&quot;;
        &lt;span class=&quot;gd&quot;&gt;-  version = &quot;0.2.52&quot;;
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+  version = &quot;0.2.55&quot;;
        &lt;/span&gt;
        src = fetchFromGitHub {
        owner = &quot;superfly&quot;;
        repo = &quot;flyctl&quot;;
        rev = &quot;v${version}&quot;;
        &lt;span class=&quot;gd&quot;&gt;-    hash = &quot;sha256-BCnMXyS94tuD+Un1DLqs3mdGi7XrVBoZGJ/XkpACOQI&quot;;
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+    hash = &quot;sha256-yCRaF600UrDmazsgTRp/grWtkULeSQedE5m69K6h/4Q=&quot;;
        &lt;/span&gt;   };
        -  vendorHash = &quot;sha256-eTiY65VGFBgGzCOrnp/WbOo9Lbdk4PYwT7CppjsZ4WE=&quot;;
        &lt;span class=&quot;gi&quot;&gt;+  vendorHash = &quot;sha256-1hlWyr41t8J4naN5QbEtfCv3npe/kvMH5NKKaxYvLYk=&quot;;
        &lt;/span&gt;
        subPackages = [ &quot;.&quot; ];
        @@ -34,8 +34,20 @@ buildGo122Module rec {
        HOME=$(mktemp -d)
        &apos;&apos;;
        -  postCheck = &apos;&apos;
        &lt;span class=&quot;gd&quot;&gt;-    go test ./... -ldflags=&quot;-X &apos;github.com/superfly/flyctl/internal/buildinfo.buildDate=1970-01-01T00:00:00Z&apos;&quot;
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+  checkFlags = [
        +    # these tests require network
        +    &quot;-skip=TestToTestMachineConfig&quot;
        +  ];
        +
        +  # We override checkPhase to be able to test ./... while using subPackages
        +  checkPhase = &apos;&apos;
        +    runHook preCheck
        +    # We do not set trimpath for tests, in case they reference test assets
        +    export GOFLAGS=&apos;&apos;${GOFLAGS//-trimpath/}
        +
        +    buildGoDir test ./...
        +
        +    runHook postCheck
        &lt;/span&gt;   &apos;&apos;;
        postInstall = &apos;&apos;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;To see the full breakdown of why these changes are necessary, you can refer to the &lt;a href=&quot;https://github.com/NixOS/nixpkgs/pull/313157&quot;&gt;PR description&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;With the update read, it&apos;s a simple commit:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git checkout &lt;span class=&quot;nt&quot;&gt;-b&lt;/span&gt; flyctl/0.2.55
        &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git add pkgs/development/web/flyctl/default.nix
        &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git commit &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;flyctl: 0.2.52 -&amp;gt; 0.2.55&quot;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git push origin HEAD&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;h2 id=&quot;housekeeping&quot;&gt;Housekeeping&lt;/h2&gt;
        &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;flyctl&lt;/code&gt; is a package I&apos;ve found myself using more and more, so I&apos;m going to adopt it as one of the maintainers - since I already exist in &lt;code class=&quot;highlighter-rouge&quot;&gt;maintainers/maintainer-list.nix&lt;/code&gt;, it&apos;s a simple change:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/pkgs/development/web/flyctl/default.nix b/pkgs/development/web/flyctl/default.nix
        index 2683203a79ca..6ab6ad9057d2 100644
        &lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/pkgs/development/web/flyctl/default.nix
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/pkgs/development/web/flyctl/default.nix
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -69,7 +69,7 @@&lt;/span&gt; buildGo122Module rec {
        downloadPage = &quot;https://github.com/superfly/flyctl&quot;;
        homepage = &quot;https://fly.io/&quot;;
        license = lib.licenses.asl20;
        &lt;span class=&quot;gd&quot;&gt;-    maintainers = with lib.maintainers; [ adtya jsierles techknowlogick ];
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+    maintainers = with lib.maintainers; [ adtya jsierles techknowlogick RaghavSood ];
        &lt;/span&gt;     mainProgram = &quot;flyctl&quot;;
        };
        }&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;We can then commit that, ensuring we do it separately from the version update itself:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git add pkgs/development/web/flyctl/default.nix
        &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git commit &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;flyctl: add RaghavSood as maintainer&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;Lastly, I&apos;m going to define an &lt;code class=&quot;highlighter-rouge&quot;&gt;updateScript&lt;/code&gt;. A significant portion of &lt;code class=&quot;highlighter-rouge&quot;&gt;nixpkgs&lt;/code&gt; updates are automated and various tooling exists to support this. However, it doesn&apos;t work on &lt;code class=&quot;highlighter-rouge&quot;&gt;flyctl&lt;/code&gt; as the upstream repository has non-standard release tags, and no &lt;code class=&quot;highlighter-rouge&quot;&gt;updateScript&lt;/code&gt; is defined to inform the tooling on how to process these tags. We can make use of existing tooling options to define such a script:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/pkgs/development/web/flyctl/default.nix b/pkgs/development/web/flyctl/default.nix
        index 6ab6ad9057d2..12483d4ef5b3 100644
        &lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/pkgs/development/web/flyctl/default.nix
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/pkgs/development/web/flyctl/default.nix
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -1,4 +1,4 @@&lt;/span&gt;
        &lt;span class=&quot;gd&quot;&gt;-{ lib, buildGo122Module, fetchFromGitHub, testers, flyctl, installShellFiles }:
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+{ lib, buildGo122Module, fetchFromGitHub, testers, flyctl, installShellFiles, gitUpdater }:
        &lt;/span&gt;
        buildGo122Module rec {
        pname = &quot;flyctl&quot;;
        &lt;span class=&quot;p&quot;&gt;@@ -58,6 +58,14 @@&lt;/span&gt; buildGo122Module rec {
        ln -s $out/bin/flyctl $out/bin/fly
        &apos;&apos;;
        +  # Upstream tags every PR merged with release tags like
        &lt;span class=&quot;gi&quot;&gt;+  # v2024.5.20-pr3545.4. We ignore all revisions containing a &apos;-&apos;
        +  # to skip these releases.
        +  passthru.updateScript = gitUpdater {
        +    rev-prefix = &quot;v&quot;;
        +    ignoredVersions = &quot;-&quot;;
        +  };
        +
        &lt;/span&gt;   passthru.tests.version = testers.testVersion {
        package = flyctl;
        command = &quot;HOME=$(mktemp -d) flyctl version&quot;;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;Again, we want to commit this as a separate unit of work from our version update and maintainer list change:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git add pkgs/development/web/flyctl/default.nix
        &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git commit &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;flyctl: add updateScript&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;And with that, we&apos;re done!&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git log &lt;span class=&quot;nt&quot;&gt;--oneline&lt;/span&gt;
        54a85a69a597 flyctl: add updateScript
        df4c4e9183ae flyctl: add RaghavSood as maintainer
        b57260da32c6 flyctl: 0.2.52 -&amp;gt; 0.2.55&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;</content><author><name></name></author><category term="nixpkgs" /><summary type="html">For many, contributing to nixpkgs can be a daunting task - the repository is extremely active, with thousands of PRs going in every week. With the breadth of what&apos;s included in nixpkgs spanning everything from bootstrapping an OS install to npm packages, it can be hard to know where to start.</summary></entry><entry><title type="html">Find Something to Fix</title><link href="https://raghavsood.com//blog/2024/05/16/find-something-to-fix/" rel="alternate" type="text/html" title="Find Something to Fix" /><published>2024-05-16T00:00:00+00:00</published><updated>2024-05-16T00:00:00+00:00</updated><id>https://raghavsood.com//blog/2024/05/16/find-something-to-fix</id><content type="html" xml:base="https://raghavsood.com//blog/2024/05/16/find-something-to-fix/">&lt;p&gt;When I&apos;m idling, I like to just… look at things. I might scroll HN, or trace random transactions on a blockchain explorer, or poke about in trending git repositories surfaced by &lt;a href=&quot;https://github.com/explore&quot;&gt;Github&apos;s Explore&lt;/a&gt;.&lt;/p&gt;
        &lt;p&gt;I&apos;m not looking for anything in particular. I&apos;m hardly going to come back to anything I see today. But over time, just simply looking at things has helped me form a decent feel of what&apos;s out there.&lt;/p&gt;
        &lt;p&gt;This is handy in odd, unpredictable ways - Simply being aware of what else is out there is a problem-solving super power.&lt;/p&gt;
        &lt;p&gt;Sometimes, this extends to fixing something. Typically, this takes the form of trying to make &lt;a href=&quot;https://github.com/NixOS/nixpkgs&quot;&gt;nixpkgs&lt;/a&gt; just ever so slightly greener. For its various faults, nixpkgs does have good toolling. PRs are well labelled, there&apos;s a small army of people contributing, and OfBorg&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; and Hydra&lt;sup id=&quot;fnref:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; do an amazing job of CI/CD.&lt;/p&gt;
        &lt;p&gt;I do maintain some packages for nixpkgs, and generally help out with things when I can, but fixing a random package is a window into another world. Where the window leads is decided by whichever failing Hydra job&lt;sup id=&quot;fnref:3&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:3&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; or GitHub issue I chance upon, and it can be a journey.&lt;/p&gt;
        &lt;p&gt;Earlier this week, this led me to the &lt;a href=&quot;https://github.com/BIC-MNI/bicpl&quot;&gt;bicpl&lt;/a&gt; package - it was failing to build for darwin platforms&lt;sup id=&quot;fnref:4&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:4&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;, and was a dependency for 4 other packages, causing them to fail as well.&lt;/p&gt;
        &lt;p&gt;Stepping through this window revealed that bicpl is a library built by the &lt;a href=&quot;https://www.mcgill.ca/bic/&quot;&gt;McConnel Brain Imaging Centre&lt;/a&gt; at the Montreal Neurological Institute. It&apos;s a C library used to process brain imaging data, and is used by a number of other programs. Neuroimaging wasn&apos;t a field I expected to be looking at today, but nevertheless that&apos;s where I found myself.&lt;/p&gt;
        &lt;p&gt;Looking at their &lt;a href=&quot;https://github.com/BIC-MNI/bicpl&quot;&gt;code&lt;/a&gt; reveals that while the master branch gave the impression the project was abandoned, occasional fixes did crop up on other branches. In particular, the &lt;a href=&quot;https://github.com/BIC-MNI/bicpl/tree/develop-apple&quot;&gt;develop-apple&lt;/a&gt; branch did contain a fix for the darwin build issues. Bringing that into nixpkgs was simply a matter of bumping the version we were building.&lt;/p&gt;
        &lt;p&gt;Another issue surfaced after the version bump - the builder insisted that time-related functions weren&apos;t properly declared:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;/tmp/nix-build-bicpl-unstable-2023-01-19.drv-0/source/Prog_utils/random.c:80:16: error: call to undeclared &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;time&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; ISO C99 and later &lt;span class=&quot;k&quot;&gt;do &lt;/span&gt;not support implicit &lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;declarations &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Wimplicit-function-declaration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
        seed &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;NULL&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;Now, I haven&apos;t touched C in a long, long time, but fortunately this does give us enough information to go on. A quick search for &lt;code class=&quot;highlighter-rouge&quot;&gt;-Wimplicit-function-declaration&lt;/code&gt; later, and we find that &lt;a href=&quot;https://releases.llvm.org/16.0.0/tools/clang/docs/ReleaseNotes.html#potentially-breaking-changes&quot;&gt;clang16 has&lt;/a&gt; made this warning into an error. Nixpkgs, in an effort to keep things clean, safe, and stable, started defaulting to clang16 for darwin on &lt;a href=&quot;https://github.com/NixOS/nixpkgs/commit/bcbdb800cf7659d6ff36ac114121a056fe8c9656&quot;&gt;2023-06-11&lt;/a&gt;&lt;sup id=&quot;fnref:5&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:5&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;, which is also when the bicpl package started to fail.&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/Prog_utils/random.c b/Prog_utils/random.c
        index f61dbb6..f5dcb9c 100644
        &lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/Prog_utils/random.c
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/Prog_utils/random.c
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -23,6 +23,7 @@&lt;/span&gt;
        #endif
        #include &amp;lt;stdlib.h&amp;gt;
        &lt;span class=&quot;gi&quot;&gt;+#include &amp;lt;time.h&amp;gt;
        &lt;/span&gt;
        static  VIO_BOOL  initialized = FALSE;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;Armed with this, the fix was simple - we just needed to include the &lt;code class=&quot;highlighter-rouge&quot;&gt;time.h&lt;/code&gt; header file. Now, nixpkgs does have convenient ways to patch source files - I could add the patch to the repository and include it, but I elected to send &lt;a href=&quot;https://github.com/BIC-MNI/bicpl/pull/9&quot;&gt;a PR&lt;/a&gt; to the upstream repository instead. This way, the fix would be available to everyone, and not just nixpkgs users. It&apos;s an issue that would inevitably bite any users outside of nixpkgs too as clang16 adoption grows. At the same time, I opened &lt;a href=&quot;https://github.com/NixOS/nixpkgs/pull/311264&quot;&gt;a nixpkgs PR&lt;/a&gt;, pulling in the patch during the build for now. At the very least, this would fix any issues within nixpkgs and anyone downstream of it.&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/pkgs/development/libraries/science/biology/bicpl/default.nix b/pkgs/development/libraries/science/biology/bicpl/default.nix
        index 5ad45b1f8c0431..45d1b159d07471 100644
        &lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/pkgs/development/libraries/science/biology/bicpl/default.nix
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/pkgs/development/libraries/science/biology/bicpl/default.nix
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -2,6 +2,7 @@&lt;/span&gt;
        lib,
        stdenv,
        fetchFromGitHub,
        &lt;span class=&quot;gi&quot;&gt;+  fetchpatch,
        &lt;/span&gt;   cmake,
        libminc,
        netpbm,
        &lt;span class=&quot;p&quot;&gt;@@ -9,16 +10,24 @@&lt;/span&gt;
        stdenv.mkDerivation rec {
        pname = &quot;bicpl&quot;;
        &lt;span class=&quot;gd&quot;&gt;-  version = &quot;unstable-2020-10-15&quot;;
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+  version = &quot;unstable-2023-01-19&quot;;
        &lt;/span&gt;
        -  # current master is significantly ahead of most recent release, so use Git version:
        &lt;span class=&quot;gi&quot;&gt;+  # master is not actively maintained, using develop and develop-apple branches
        &lt;/span&gt;   src = fetchFromGitHub {
        owner = &quot;BIC-MNI&quot;;
        repo = pname;
        &lt;span class=&quot;gd&quot;&gt;-    rev = &quot;a58af912a71a4c62014975b89ef37a8e72de3c9d&quot;;
        -    sha256 = &quot;0iw0pmr8xrifbx5l8a0xidfqbm1v8hwzqrw0lcmimxlzdihyri0g&quot;;
        &lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+    rev = &quot;884b3ac8db945a17df51a325d29f49b825a61c3e&quot;;
        +    hash = &quot;sha256-zAA+hPwjMawQ1rJuv8W30EqKO+AI0aq9ybquBnKlzC0=&quot;;
        &lt;/span&gt;   };
        +  patches = [
        &lt;span class=&quot;gi&quot;&gt;+    # fixes build by including missing time.h header
        +    (fetchpatch {
        +      url = &quot;https://github.com/RaghavSood/bicpl/commit/3def4acd6bae61ff7a930ef8422ad920690382a6.patch&quot;;
        +      hash = &quot;sha256-VdAKuLWTZY7JriK1rexIiuj8y5ToaSEJ5Y+BbnfdYnI=&quot;;
        +    })
        +  ];
        +
        &lt;/span&gt;   nativeBuildInputs = [ cmake ];
        buildInputs = [
        libminc&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;With that done and merged, &lt;a href=&quot;https://hydra.nixos.org/eval/1806287#tabs-now-succeed&quot;&gt;bicpl and its dependents&lt;/a&gt; were building successfully again.&lt;/p&gt;
        &lt;p&gt;As a pleasant surprise, despite bicpl&apos;s repository being inactive, the upstream PR was merged within 24 hours, allowing me to &lt;a href=&quot;https://github.com/NixOS/nixpkgs/pull/311553&quot;&gt;remove the patch&lt;/a&gt; from the nixpkgs build.&lt;/p&gt;
        &lt;h2 id=&quot;but-why&quot;&gt;But why?&lt;/h2&gt;
        &lt;p&gt;By almost any definition, this was a pointless exercise - I don&apos;t use bicpl, or any of its derivates. Heck, I don&apos;t even use C enough to have to care about breaking changes in clang16. But random-walk discoveries like this are how I&apos;ve learned about countless things over the years.&lt;/p&gt;
        &lt;p&gt;Now I know bicpl exists. Just based on the brief look through the window of open-source brain imaging, I can hazard a guess that their data files contain some kind of volumetric data, expressed as geomtric shapes and coordinates. Maybe there&apos;s some type or tag associated with these values to indicate density or mass&lt;sup id=&quot;fnref:6&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:6&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;. Maybe it&apos;s computed on the fly. I know that they&apos;re active enough to notice uncalled for PRs on inactive repositories, and that they understand enough about software engineering to evaluate it quickly&lt;sup id=&quot;fnref:7&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:7&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
        &lt;p&gt;I know there&apos;s a small sliver of open source centered around dealing with brain imaging data and how to manipulate it. A sliver that&apos;s been at it since &lt;a href=&quot;https://github.com/BIC-MNI/mni-acmacros/commit/9d54abc95839c16fe8d3b63927e44f63a4dfcd76&quot;&gt;at least 2001&lt;/a&gt;&lt;sup id=&quot;fnref:8&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:8&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;. I don&apos;t know if anyone&apos;s going to use this package from nixpkgs, probably not. But having it functional means that if someone does, it&apos;s one less barrier for them to cross. If every package maintainer only mainted things they actively used, nixpkgs would be a much poorer place.&lt;/p&gt;
        &lt;p&gt;That&apos;s good enough for me.&lt;/p&gt;
        &lt;p&gt;And who knows, maybe one day I will need to know that clang16 broke implicit function declarations. I&apos;ve used more arbitrary knowledge in the past&lt;sup id=&quot;fnref:9&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:9&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;9&lt;/a&gt;&lt;/sup&gt;. Might even scan a brain someday.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;h1 id=&quot;notesreferences&quot;&gt;Notes/References&lt;/h1&gt;
        &lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
        &lt;ol&gt;
        &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
        &lt;p&gt;&lt;a href=&quot;https://github.com/NixOS/ofborg&quot;&gt;OfBorg&lt;/a&gt; is nixpkgs&apos; bot to help automatically build, label, and check PRs. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li id=&quot;fn:2&quot; role=&quot;doc-endnote&quot;&gt;
        &lt;p&gt;&lt;a href=&quot;https://nixos.org/hydra/&quot;&gt;Hydra&lt;/a&gt; is NixOS&apos; CI/CD system. Like OfBorg, it automatically builds and reports the state of the Nix ecosystem. &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li id=&quot;fn:3&quot; role=&quot;doc-endnote&quot;&gt;
        &lt;p&gt;Hydra manages the release channels, and builds the entire nixpkgs package set. It helpfully reports &lt;a href=&quot;https://hydra.nixos.org/eval/1806308#tabs-still-fail&quot;&gt;failing&lt;/a&gt; and &lt;a href=&quot;https://hydra.nixos.org/eval/1806308#tabs-now-fail&quot;&gt;newly failing&lt;/a&gt; jobs for each evaluation. &lt;a href=&quot;#fnref:3&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li id=&quot;fn:4&quot; role=&quot;doc-endnote&quot;&gt;
        &lt;p&gt;OfBorg and Hydra build packages for x86 and ARM on linux and darwin. &lt;a href=&quot;#fnref:4&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li id=&quot;fn:5&quot; role=&quot;doc-endnote&quot;&gt;
        &lt;p&gt;If you look at the associated &lt;a href=&quot;https://github.com/NixOS/nixpkgs/pull/241692&quot;&gt;pull request&lt;/a&gt;, you&apos;ll notice it&apos;s actually from July, and was merged in October. However, it was merged to &lt;code class=&quot;highlighter-rouge&quot;&gt;staging&lt;/code&gt; first, since changing the default compiler for darwin is a big deal. Due to the way nixpkgs is structured, this changes &lt;code class=&quot;highlighter-rouge&quot;&gt;stdenv&lt;/code&gt;, and essentially triggers a &quot;rebuild-the-world&quot; event, requiring nearly every darwin package to be rebuilt. By merging to staging first, Hydra can build and cache the new builds. Once this is done, merging to master results in a signficantly small rebuild set, ensuring that nixpkgs&apos; channels stay relatively up-to-date and don&apos;t wait days for a rebuild. &lt;a href=&quot;#fnref:5&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li id=&quot;fn:6&quot; role=&quot;doc-endnote&quot;&gt;
        &lt;p&gt;I can make this guess because I&apos;ve seen similar data structures in other contexts. Probably a similarly-pointless context. &lt;a href=&quot;#fnref:6&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li id=&quot;fn:7&quot; role=&quot;doc-endnote&quot;&gt;
        &lt;p&gt;Having seen many researchers&apos; code, this is not a given. &lt;a href=&quot;#fnref:7&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li id=&quot;fn:8&quot; role=&quot;doc-endnote&quot;&gt;
        &lt;p&gt;This is just their earliest git commit I could find - if the repositories are right, at some point they were using CVS, and probably hosted code elsewhere. There&apos;s a very real chance BIC-MNI&apos;s open source efforts predate me. &lt;a href=&quot;#fnref:8&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li id=&quot;fn:9&quot; role=&quot;doc-endnote&quot;&gt;
        &lt;p&gt;A story for another post. &lt;a href=&quot;#fnref:9&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;/ol&gt;
        &lt;/div&gt;</content><author><name></name></author><category term="thoughts" /><category term="perspectives" /><category term="nixpkgs" /><summary type="html">When I&apos;m idling, I like to just… look at things. I might scroll HN, or trace random transactions on a blockchain explorer, or poke about in trending git repositories surfaced by Github&apos;s Explore.</summary></entry><entry><title type="html">Bitcoin&apos;s Signature Types - SIGHASH</title><link href="https://raghavsood.com//blog/2018/06/10/bitcoin-signature-types-sighash/" rel="alternate" type="text/html" title="Bitcoin&apos;s Signature Types - SIGHASH" /><published>2018-06-10T00:00:00+00:00</published><updated>2018-06-10T00:00:00+00:00</updated><id>https://raghavsood.com//blog/2018/06/10/bitcoin-signature-types-sighash</id><content type="html" xml:base="https://raghavsood.com//blog/2018/06/10/bitcoin-signature-types-sighash/">&lt;p&gt;Using Bitcoin day to day, one takes signatures for granted. You sign a transaction when you want to spend BTC, and that&apos;s about it. It simply helps ensure that no one is spending your BTC without your permission (with said permission in the form of a digital signature).&lt;/p&gt;
        &lt;p&gt;This is all true, but somewhat of an oversimplification. Bitcoin transactions actually have a number of different ways that they can be signed, known as the &lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH&lt;/code&gt;. This is encoded into the signature portion of the transaction. Having these multiple signature types allow us to create some innovative transactions that do more than just spend Bitcoin, facilitating trustless sales, and multi-party contributions. This post aims to shed some light on these options, and how they can be used.&lt;/p&gt;
        &lt;p&gt;Let&apos;s take a look at a simple, one input and one output Pay-to-pubkey-hash (P2PKH) transaction from a recent block at the time of writing: &lt;a href=&quot;https://blockchain.info/tx/e251decc598148363669ae64cf0ec56f6049a0adc1eb42ac850f949aff0e6e55&quot; target=&quot;_blank&quot;&gt;e251decc598148363669ae64cf0ec56f6049a0adc1eb42ac850f949aff0e6e55&lt;/a&gt;&lt;/p&gt;
        &lt;p&gt;The signature data in this transaction is a total of 106 bytes (including the push opcodes). You can easily pull this information out using the &lt;code class=&quot;highlighter-rouge&quot;&gt;decoderawtransaction&lt;/code&gt; method in bitcoind, under the &lt;code class=&quot;highlighter-rouge&quot;&gt;vin&amp;gt;scriptSig&lt;/code&gt; key.&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;PUSH&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0x47&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# 71 bytes&lt;/span&gt;
        304402203ff7162d6635246dbf59b7fa9e72e3023e959a73b1fbc51edbaaa5a8dbc6d2f
        70220776e2fa5740df01cc0ac47bda713e87fc59044960122ba45abb11c949655c58401
        PUSH&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;0x21&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# 33 bytes&lt;/span&gt;
        03bc3c9134f5a5e3f08287d175d7e43368f72cb93a2e6cbb801b5e90d1ed628e60&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;The first push here is the actual signature, while the second push is the public key for address &lt;code class=&quot;highlighter-rouge&quot;&gt;18w59Xd5ZXPsnx9A7buNgqmAvUNqn3cmUJ&lt;/code&gt;, the sender in this transaction.&lt;/p&gt;
        &lt;p&gt;Bitcoin uses &lt;a href=&quot;https://en.wikipedia.org/wiki/X.690#DER_encoding&quot; target=&quot;_blank&quot;&gt;DER encoded&lt;/a&gt; signatures, so let&apos;s break it up into it&apos;s components as well:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;30 &lt;span class=&quot;c&quot;&gt;# DER Sequence tag&lt;/span&gt;
        44 &lt;span class=&quot;c&quot;&gt;# Sequence length 0x44 (68) bytes&lt;/span&gt;
        02 &lt;span class=&quot;c&quot;&gt;# Integer element&lt;/span&gt;
        20 &lt;span class=&quot;c&quot;&gt;# Element length 0x20 (32) bytes&lt;/span&gt;
        3ff7162d6635246dbf59b7fa9e72e3023e959a73b1fbc51edbaaa5a8dbc6d2f7 &lt;span class=&quot;c&quot;&gt;# ECDSA r value&lt;/span&gt;
        02 &lt;span class=&quot;c&quot;&gt;# Integer element&lt;/span&gt;
        20 &lt;span class=&quot;c&quot;&gt;# Element length 0x20 (32) bytes&lt;/span&gt;
        776e2fa5740df01cc0ac47bda713e87fc59044960122ba45abb11c949655c584 &lt;span class=&quot;c&quot;&gt;# ECDSA s value&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# DER encoding completed&lt;/span&gt;
        01&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;That one byte left over after the DER encoding (but still part of the actual signature push) is the &lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH&lt;/code&gt; flag.&lt;/p&gt;
        &lt;p&gt;The values for this flag are found in &lt;a href=&quot;https://github.com/bitcoin/bitcoin/blob/56f69360dc98bd68704f19646a84d045788d199e/src/script/interpreter.h#L21&quot; target=&quot;_blank&quot;&gt;interpreter.h&lt;/a&gt;:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;cm&quot;&gt;/** Signature hash types/flags */&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;enum&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;SIGHASH_ALL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;SIGHASH_NONE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;SIGHASH_SINGLE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;SIGHASH_ANYONECANPAY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;Although only four values are defined, &lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_ANYONECANPAY&lt;/code&gt; is combined with the previous three via a bitwise &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;amp;&lt;/code&gt; (effectively addition in this case), for a total of six possible values.&lt;/p&gt;
        &lt;ul&gt;
        &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_ALL&lt;/code&gt; (&lt;code class=&quot;highlighter-rouge&quot;&gt;0x01&lt;/code&gt;) - This is the default in every consumer-facing wallet that I am aware of. It signs every input and output, and any change to the transaction will render the signature invalid. This essentially says &quot;I only agree to move my BTC with this exact combination of inputs and outputs&quot;.&lt;/li&gt;
        &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_NONE&lt;/code&gt; (&lt;code class=&quot;highlighter-rouge&quot;&gt;0x02&lt;/code&gt;) - This signs all the inputs to the transaction, but none of the outputs. Effectively, it creates an authorizing saying &quot;Hey, I&apos;m okay with participating in this transaction, but I don&apos;t particularly care where it goes&quot;. This might seem insecure, and should never be used in single-input transactions. We&apos;ll cover why it exists soon, though.&lt;/li&gt;
        &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_SINGLE&lt;/code&gt; (&lt;code class=&quot;highlighter-rouge&quot;&gt;0x03&lt;/code&gt;) - This type of signature signs all inputs, and exactly one corresponding output. The corresponding output is the one with the same index as your signature (i.e., if your input is at vin 0, then the output you want to sign must be vout 0). This essentially says &quot;I agree to participate in this tx with all these inputs, as long as this much goes to this one address&quot;.&lt;/li&gt;
        &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_ALL | SIGHASH_ANYONECANPAY&lt;/code&gt; (&lt;code class=&quot;highlighter-rouge&quot;&gt;0x81&lt;/code&gt;) - This is similar to &lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_ALL&lt;/code&gt;, and signs all outputs. However, it only signs the one input it is part of. It&apos;s essentially saying &quot;I agree to participate in this tx, as long as the following recipients receive these amounts. I don&apos;t care about any additional inputs to this transaction.&quot;&lt;/li&gt;
        &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_NONE | SIGHASH_ANYONECANPAY&lt;/code&gt; (&lt;code class=&quot;highlighter-rouge&quot;&gt;0x82&lt;/code&gt;) - This is similar to &lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_NONE&lt;/code&gt;, but only signs the one input it is in. This is essentially like saying &quot;Hey, I&apos;m okay with sending this BTC. In fact, I don&apos;t even care if it is sent in this transaction. Here&apos;s a signed note saying that any transaction including this can spend this BTC&quot;.&lt;/li&gt;
        &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_SINGLE | SIGHASH_ANYONECANPAY&lt;/code&gt; (&lt;code class=&quot;highlighter-rouge&quot;&gt;0x83&lt;/code&gt;) - This is similar to &lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_SINGLE&lt;/code&gt;, except it only signs the input that contains it, and the corresponding output. This says &quot;I definitely want to move this much BTC to this output, but I don&apos;t care about any other inputs and outputs in this transaction&quot;.&lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;Now, one might wonder why multiple signature types are needed at all, so let&apos;s look at some quick example of how they might be used:&lt;/p&gt;
        &lt;ul&gt;
        &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_ALL&lt;/code&gt; - This one is pretty straightforward, it&apos;s what we use every day. Spending specific inputs to create specific outputs.&lt;/li&gt;
        &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_NONE&lt;/code&gt; - This one is a bit more confusing. On the face of it, it seems like you&apos;re burning money by not signing any outputs. Indeed, if you create a tx with just a single input and sign it with &lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_NONE&lt;/code&gt;, the miner would be able to simply change the output to one that they control. This is mostly designed to be used in scenarios where more than one party is contributing inputs. At that point, such a signature essentially means &quot;I agree to spend my money, provided all these other people spend their&apos;s too&quot;. It is expected that one of the other signers will then use &lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_ALL&lt;/code&gt; to secure all the outputs of the transaction, and send the money to a mutually agreed output set.&lt;/li&gt;
        &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_SINGLE&lt;/code&gt; - This can be used to send BTC in scenarios where you only want to make the transfer provided some other parties are making a transfer too. Essentially, you agree to move a certain amount of BTC to a certain output, but only if the other input parties to the transaction also move their BTC. This can be used to create a transaction where you and a friend need to pay someone 1.5 BTC, and you are contributing 1 BTC. However, your friend only has a 1 BTC output. Thus, you can use &lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_SINGLE&lt;/code&gt; to create a transaction with both the 1 BTC inputs, and a 1.5 BTC output to whoever needs to be paid. Your friend can then add an output for their change address, and use &lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_ALL&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_SINGLE&lt;/code&gt; (if their change address is at the same index as their input) and complete the transaction.&lt;/li&gt;
        &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_ALL | SIGHASH_ANYONECANPAY&lt;/code&gt; - This is again somewhat straightforward. You essentially agree to contribute to a transaction, but only if a list of recipients receives a certain amount of BTC. This is a situation like our &lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_SINGLE&lt;/code&gt; example, but the rest of the inputs are arbitrary, and the ouputs are fixed.&lt;/li&gt;
        &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_NONE | SIGHASH_ANYONECANPAY&lt;/code&gt; - This one essentially boils down to &quot;Here&apos;s some BTC&quot;. It offers no guarantees at all, and can be used as a proof of burn. Such a transaction allows anyone to define an input, and include the input in any other transaction, with arbitrary outputs. By making such a signature, you are fully committing to spending the BTC without any control whatsoever. &lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_NONE&lt;/code&gt; at least enforces the condition is that everyone else with inputs on the transaction must also move their BTC.&lt;/li&gt;
        &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_SINGLE | SIGHASH_ANYONECANPAY&lt;/code&gt; - This is a rather interesting combination, and allows for on-chain sales of assets (or coloured coins, in Bitcoin&apos;s case). I don&apos;t think I could come up with a better example than &lt;a href=&quot;https://groups.google.com/forum/#!msg/bitcoinx/pON4XCIBeV4/IvzwkU8Vch0J&quot; target=&quot;_blank&quot;&gt;this one by Alex Mzrahi&lt;/a&gt;. Essentially, this allows Alice, who holds 100 COIN to sign an input authorizing the movement of 100 COIN, and an output to an address she controls with a value of 1 BTC. She then publishes this incomplete and invalid transaction (since there are no inputs for 1 BTC). Anyone who wishes to purchase 100 COIN for 1 BTC can then add an input &amp;gt;= 1 BTC, an output claiming the 100 COIN (remember, Alice&apos;s output only claims the BTC), and any change outputs if required. This then makes a complete tx, which can be broadcast to execute the sale trustlessly.&lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;This completes a brief look at the various signature types allowed on Bitcoin. Just one last note. Interestingly, there is a bug in the implementation for &lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHASH_SINGLE&lt;/code&gt;, first &lt;a href=&quot;https://www.mail-archive.com/bitcoin-development@lists.sourceforge.net/msg01408.html&quot; target=&quot;_blank&quot;&gt;reported in 2012&lt;/a&gt;. If the input has a vin that exceeds the number of outputs, it produces a signature that is valid, but not tied to any inputs. Essentially, you end up with a signature that can be used to spend not only the input you were signing, but also any past or future outputs to that address! A pull request (&lt;a href=&quot;https://github.com/bitcoin/bitcoin/pull/13360&quot; target=&quot;_blank&quot;&gt;bitcoin#13360&lt;/a&gt;) was opened to make such transactions non-standard was opened just a few days ago, and is what prompted me to look into how all this actually works.&lt;/p&gt;</content><author><name></name></author><category term="bitcoin" /><category term="sighash" /><summary type="html">Using Bitcoin day to day, one takes signatures for granted. You sign a transaction when you want to spend BTC, and that&apos;s about it. It simply helps ensure that no one is spending your BTC without your permission (with said permission in the form of a digital signature).</summary></entry><entry><title type="html">Demystifying Bitcoin&apos;s peers.dat</title><link href="https://raghavsood.com//blog/2018/05/20/demystifying-peers-dat/" rel="alternate" type="text/html" title="Demystifying Bitcoin&apos;s peers.dat" /><published>2018-05-20T00:00:00+00:00</published><updated>2018-05-20T00:00:00+00:00</updated><id>https://raghavsood.com//blog/2018/05/20/demystifying-peers-dat</id><content type="html" xml:base="https://raghavsood.com//blog/2018/05/20/demystifying-peers-dat/">&lt;p&gt;Bitcoin uses a custom format to store peer information. Although the inbuilt JSON-RPC provides a helpful &lt;code class=&quot;highlighter-rouge&quot;&gt;getpeerinfo&lt;/code&gt; method to list your active connections, it offers no method to query, dump, or otherwise access the information in peers.dat, which contains far more than just your active connections. Having access to the information in this file can be helpful for a number of reasons, such as finding out information about the network and finding more nodes than just your connections to broadcast transactions to.&lt;/p&gt;
        &lt;p&gt;My interest in this was piqued by &lt;a href=&quot;https://bitcoin.stackexchange.com/q/75324/7272&quot; target=&quot;_blank&quot;&gt;this&lt;/a&gt; post on the &lt;a href=&quot;https://bitcoin.stackexchange.com/&quot; target=&quot;_blank&quot;&gt;Bitcoin StackExchange&lt;/a&gt;. This blog post is an attempt to answer that question (and cover some gaps in my personal crypto tools) by building a utility that can read and query peers.dat. The post will go step by step, as I am writing this while building the utility.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;h2 id=&quot;research&quot;&gt;Research&lt;/h2&gt;
        &lt;p&gt;To work with a minimal example, I deleted my existing peers.dat and ran &lt;code class=&quot;highlighter-rouge&quot;&gt;bitcoind&lt;/code&gt; again. This gives me a much lighter file (11 KB), instead of a 4MB+ one that contained peer info over many months. I then open up the peers.dat file in sublime. This gives us a bunch of hex, no surprises there. When dealing with hex, &lt;code class=&quot;highlighter-rouge&quot;&gt;hexdump&lt;/code&gt; is step 1, so let&apos;s see what we get:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;hexdump &lt;span class=&quot;nt&quot;&gt;-C&lt;/span&gt; peers.dat | &lt;span class=&quot;nb&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; 17
        00000000  f9 be b4 d9 01 20 91 41  99 be 39 46 d6 2c 9f b3  |..... .A..9F.,..|
        00000010  e6 80 ef db 3c 1d 64 52  7c 18 c4 3e 0b eb 23 9b  |....&amp;lt;.dR|..&amp;gt;..#.|
        00000020  59 46 e3 79 40 f8 6b 00  00 00 01 00 00 00 00 04  |YF.y@.k.........|
        00000030  00 40 34 &lt;span class=&quot;nb&quot;&gt;fc &lt;/span&gt;01 00 85 55  f7 5a 09 00 00 00 00 00  |.@4....U.Z......|
        00000040  00 00 00 00 00 00 00 00  00 00 00 00 ff ff 05 09  |................|
        00000050  8b 05 20 8d 00 00 00 00  00 00 00 00 00 00 ff ff  |.. .............|
        00000060  2d 20 82 13 00 00 00 00  00 00 00 00 00 00 00 00  |- ..............|
        00000070  34 &lt;span class=&quot;nb&quot;&gt;fc &lt;/span&gt;01 00 08 c2 f9 5a  09 00 00 00 00 00 00 00  |4......Z........|
        00000080  00 00 00 00 00 00 00 00  00 00 ff ff 31 49 ae 91  |............1I..|
        00000090  20 8d 00 00 00 00 00 00  00 00 00 00 ff ff 2d 20  | .............- |
        000000a0  82 13 00 00 00 00 00 00  00 00 00 00 00 00 34 &lt;span class=&quot;nb&quot;&gt;fc&lt;/span&gt;  |..............4.|
        000000b0  01 00 24 34 f8 5a 09 00  00 00 00 00 00 00 00 00  |..&lt;span class=&quot;nv&quot;&gt;$4&lt;/span&gt;.Z..........|
        000000c0  00 00 00 00 00 00 00 00  ff ff 25 23 b7 0a 20 8d  |..........%#.. .|
        000000d0  00 00 00 00 00 00 00 00  00 00 ff ff 2d 20 82 13  |............- ..|
        000000e0  00 00 00 00 00 00 00 00  00 00 00 00 34 &lt;span class=&quot;nb&quot;&gt;fc &lt;/span&gt;01 00  |............4...|
        000000f0  b7 84 fa 5a 09 00 00 00  00 00 00 00 00 00 00 00  |...Z............|
        00000100  00 00 00 00 00 00 ff ff  b4 6b 56 4d 20 8d 00 00  |.........kVM ...|&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;This is a truncated output, as the file continues much the same way.&lt;/p&gt;
        &lt;p&gt;The hex immediately gives us some clues. The first four bytes (&lt;code class=&quot;highlighter-rouge&quot;&gt;f9 be b4 d9&lt;/code&gt;) stand out as the &lt;a href=&quot;https://github.com/bitcoin/bitcoin/blob/21f56805531c4b2954d0aaffa34c83f37ed8f9c0/src/chainparams.cpp#L115&quot; target=&quot;_blank&quot;&gt;message start string&lt;/a&gt;, which is something you see very often when working with bitcoin&apos;s network level implementations. Based on some past projects with Bitcoin, these bytes are ingrained into my head and stood out immediately.&lt;/p&gt;
        &lt;p&gt;The next set of bytes after the message start doesn&apos;t offer any immediate insight, so let&apos;s skip ahead for the moment. The next thing that does stand out is a repeated pattern of &lt;code class=&quot;highlighter-rouge&quot;&gt;ff ff&lt;/code&gt;,  followed by four bytes, followed by &lt;code class=&quot;highlighter-rouge&quot;&gt;20 8d&lt;/code&gt;. The first two don&apos;t seem to give out any information (&lt;code class=&quot;highlighter-rouge&quot;&gt;ff ff&lt;/code&gt; would be an unlikely candidate for magic bytes, so is unlikely to be a marker in the file). However, the next two (&lt;code class=&quot;highlighter-rouge&quot;&gt;20 8d&lt;/code&gt;) do give us some useful information. When &lt;a href=&quot;http://www.hexadecimaldictionary.com/hexadecimal/0x208D/&quot; target=&quot;_blank&quot;&gt;converted to decimal&lt;/a&gt;, we get &lt;code class=&quot;highlighter-rouge&quot;&gt;8333&lt;/code&gt;, which is the default port number for bitcoin.&lt;/p&gt;
        &lt;p&gt;This new piece of information updates our previous pattern to &lt;code class=&quot;highlighter-rouge&quot;&gt;ff ff&lt;/code&gt; + four bytes + port number (&lt;code class=&quot;highlighter-rouge&quot;&gt;8333&lt;/code&gt;). IPv4 addresses use a 32-bit address space, which is four bytes. It stands to reason that the four bytes before the port number are an IP address, considering this file is meant to hold peer info.&lt;/p&gt;
        &lt;p&gt;This is easily verified by taking the first instance of this pattern&apos;s middle four bytes (&lt;code class=&quot;highlighter-rouge&quot;&gt;05 09 8b 05&lt;/code&gt;) and converting them to an IP address. I wrote a quick &lt;a href=&quot;https://play.golang.org/p/MMOucH-oP6P&quot; target=&quot;_blank&quot;&gt;Go script&lt;/a&gt; for this, as it is an operation I will likely be doing in the utility as well. The script gives us &lt;code class=&quot;highlighter-rouge&quot;&gt;5.9.139.5&lt;/code&gt;, which seems like a plausible IP address. Running the script with a few other bytes from other patterns also produces valid IPs, so I&apos;m pretty sure at this point this is the correct interpretation.&lt;/p&gt;
        &lt;p&gt;This seems like all the information I&apos;m going to get just by looking at the hex above, so the next step is to look at the hexdump for the bottom of the file:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;hexdump &lt;span class=&quot;nt&quot;&gt;-C&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; peers.dat | &lt;span class=&quot;nb&quot;&gt;tail&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; 17
        00002b30  00 00 4f 00 00 00 00 00  00 00 00 00 00 00 00 00  |..O.............|
        00002b40  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
        00002b50  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
        00002b60  00 00 00 00 00 00 02 00  00 00 53 00 00 00 61 00  |..........S...a.|
        00002b70  00 00 00 00 00 00 00 00  00 00 01 00 00 00 21 00  |..............!.|
        00002b80  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
        00002b90  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
        00002ba0  00 00 00 00 00 00 01 00  00 00 69 00 00 00 00 00  |..........i.....|
        00002bb0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
        00002bc0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
        00002bd0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
        00002be0  00 00 00 00 00 00 01 00  00 00 2c 00 00 00 00 00  |..........,.....|
        00002bf0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
        00002c00  00 00 00 00 00 00 86 be  3d 3b b8 &lt;span class=&quot;nb&quot;&gt;dd &lt;/span&gt;01 93 f1 79  |........&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;.....y|
        00002c10  f9 c9 d1 ff f5 d4 cb 38  4d ab 56 25 62 d0 c8 d7  |.......8M.V%b...|
        00002c20  d8 82 c1 4c c1 2c                                 |...L.,|&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;Nothing really sticks out except the last few bytes. Counting these shows that there is 32 bytes of continous non-zero data. This is very likely a hash, and being at the very end of the file, it&apos;s almost certainly a checksum&lt;/p&gt;
        &lt;p&gt;With the initial hex analysis not providing enough information to completely decode the file, it&apos;s time to head to the Bitcoin source code. Some quick searches on GitHub reveal that peers.dat is managed by &lt;a href=&quot;https://github.com/bitcoin/bitcoin/blob/8b4081a889b35cac3ccafa4f7109c72ccb087518/src/addrdb.cpp&quot; target=&quot;_blank&quot;&gt;addrdb.cpp&lt;/a&gt;&lt;/p&gt;
        &lt;p&gt;Browsing through addrdb.cpp shows that the initial assumptions about the message start and checksum hash were correct:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SerializeDB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Stream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;CHashWriter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hasher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SER_DISK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CLIENT_VERSION&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MessageStart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;hasher&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MessageStart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hasher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;This snippet shows that the checksum algorithm is the same as the regular Bitcoin hashing algorithm (since it relies on &lt;a href=&quot;https://github.com/bitcoin/bitcoin/blob/172f5fa738d419efda99542e2ad2a0f4db5be580/src/hash.h&quot; target=&quot;_blank&quot;&gt;hash.h&lt;/a&gt;), which is a double-sha256. We can verify this quickly with bash and openssl:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-32&lt;/span&gt; peers.dat | openssl dgst &lt;span class=&quot;nt&quot;&gt;-sha256&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-binary&lt;/span&gt; | openssl dgst &lt;span class=&quot;nt&quot;&gt;-sha256&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;stdin&lt;span class=&quot;o&quot;&gt;)=&lt;/span&gt; 86be3d3bb8dd0193f179f9c9d1fff5d4cb384dab562562d0c8d7d882c14cc12c&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;We strip the last 32 bytes from the file (which contain the checksum), and pass the rest to openssl for hashing twice. Do note that this requires a GNU version of &lt;code class=&quot;highlighter-rouge&quot;&gt;head&lt;/code&gt;, as OS X will complain about a negative byte number. We can see that the result matches what we see in the hexdump, so that&apos;s definitely the checksum.&lt;/p&gt;
        &lt;p&gt;Now all that&apos;s needed is to determine the data format, and the rest of the header following the message start bytes. Switching from addrdb.cpp to &lt;a href=&quot;https://github.com/bitcoin/bitcoin/blob/e1d6e2af6d89935f6edf027e5d4ea1d2ec6c7f41/src/addrman.h&quot; target=&quot;_blank&quot;&gt;addrdb.h&lt;/a&gt; leads us to a &lt;a href=&quot;https://github.com/bitcoin/bitcoin/blob/e1d6e2af6d89935f6edf027e5d4ea1d2ec6c7f41/src/addrman.h#L287&quot; target=&quot;_blank&quot;&gt;helpful comment&lt;/a&gt; that lays out the serialized header format for us.&lt;/p&gt;
        &lt;p&gt;Lastly, some more GitHub search magic leads to &lt;a href=&quot;https://github.com/bitcoin/bitcoin/blob/108af52ef75a466be71d04bb973b794eca17e212/src/chainparamsseeds.h&quot; target=&quot;_blank&quot;&gt;chainparamsseeds.h&lt;/a&gt;. This states that:&lt;/p&gt;
        &lt;blockquote&gt;
        &lt;p&gt;Each line contains a 16-byte IPv6 address and a port.&lt;br /&gt;
        IPv4 as well as onion addresses are wrapped inside an IPv6 address accordingly.&lt;/p&gt;
        &lt;/blockquote&gt;
        &lt;p&gt;This explains the whole lot of &lt;code class=&quot;highlighter-rouge&quot;&gt;00&lt;/code&gt; in the hexdump preceding the IP, as well as the &lt;code class=&quot;highlighter-rouge&quot;&gt;ff ff&lt;/code&gt;. Since the majority of connections still default to IPv4, what we are seeing is IPv4 addresses encoded as IPv6 addresses, which &lt;a href=&quot;https://en.wikipedia.org/wiki/IPv6#IPv4-mapped_IPv6_addresses&quot; target=&quot;_blank&quot;&gt;follows the format&lt;/a&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;::ffff:IPv4-address&lt;/code&gt;, which is where the &lt;code class=&quot;highlighter-rouge&quot;&gt;ff ff&lt;/code&gt; comes from.&lt;/p&gt;
        &lt;h2 id=&quot;file-structure&quot;&gt;File Structure&lt;/h2&gt;
        &lt;p&gt;Based on the above research, a flow of how peers.dat is generated and structured can be put together.&lt;/p&gt;
        &lt;p&gt;The snippet from &lt;code class=&quot;highlighter-rouge&quot;&gt;addrdb.cpp&lt;/code&gt; shared above is the starting point for the creation of &lt;code class=&quot;highlighter-rouge&quot;&gt;peers.dat&lt;/code&gt;. This snippet gave us the base structure as&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;peers.dat
        ├── header
        ├── data
        └── checksum&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;The file header consists of:&lt;/p&gt;
        &lt;ul&gt;
        &lt;li&gt;A 4-byte magic value which is the message start defined in chainparams.cpp.&lt;/li&gt;
        &lt;li&gt;1 version byte, always &lt;code class=&quot;highlighter-rouge&quot;&gt;0x01&lt;/code&gt;&lt;/li&gt;
        &lt;li&gt;1-byte defining the key length for nkey, always &lt;code class=&quot;highlighter-rouge&quot;&gt;0x20&lt;/code&gt; (32 in decimal)&lt;/li&gt;
        &lt;li&gt;Key length number of bytes that specify the nkey, &lt;code class=&quot;highlighter-rouge&quot;&gt;0x20&lt;/code&gt; from above&lt;/li&gt;
        &lt;li&gt;4 bytes specifying how many new addresses there are&lt;/li&gt;
        &lt;li&gt;4 bytes specifying how many tried addresses there are&lt;/li&gt;
        &lt;li&gt;4 bytes specifying how many buckets there are (XOR&apos;d against &lt;code class=&quot;highlighter-rouge&quot;&gt;2**30&lt;/code&gt;)&lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;In all, this gives us a 50-byte header for peers.dat, which can be encapsulated in the following Go struct:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-go&quot; data-lang=&quot;go&quot;&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PeersDB&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;         &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;MessageBytes&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// 0  : 4&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Version&lt;/span&gt;      &lt;span class=&quot;kt&quot;&gt;uint8&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;// 4  : 4&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;KeySize&lt;/span&gt;      &lt;span class=&quot;kt&quot;&gt;uint8&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;// 5  : 5&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;NKey&lt;/span&gt;         &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// 37 : 32&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;NNew&lt;/span&gt;         &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// 41 : 4&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;NTried&lt;/span&gt;       &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// 45 : 4&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;NewBuckets&lt;/span&gt;   &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// 49 : 4&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;This expands our structure to:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;peers.dat
        └── header
        ├── MessageBytes
        ├── Version
        ├── KeySize
        ├── NKey
        ├── NNew
        ├── NTried
        └── NewBuckets
        ├── data
        ├── checksum&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;The data part of the file is simply the peer info structure repeated &lt;code class=&quot;highlighter-rouge&quot;&gt;NNew + NTried&lt;/code&gt; times (i.e. once per peer). The structure of this can be pieced together from three files. &lt;code class=&quot;highlighter-rouge&quot;&gt;CAddrInfo&lt;/code&gt; from &lt;a href=&quot;https://github.com/bitcoin/bitcoin/blob/0a8054e7cd5c76d01e4ac7234e3883d05f6f5fdd/src/addrman.h#L61&quot; target=&quot;_blank&quot;&gt;addrman.h&lt;/a&gt; encapsulates the information regarding a single peer as follows:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;kr&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SerializationOp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Stream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Operation&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ser_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;READWRITEAS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;READWRITE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;READWRITE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nLastSuccess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;READWRITE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nAttempts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;We will try to keep our Go code in sync with Bitcoin Core&apos;s code to allow for easier updates in the event of changes.&lt;/p&gt;
        &lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;PeersDB&lt;/code&gt; struct is updated to include &lt;code class=&quot;highlighter-rouge&quot;&gt;CAddrInfo&lt;/code&gt; slices for New and Tried peers, becoming:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-go&quot; data-lang=&quot;go&quot;&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PeersDB&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;          &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;MessageBytes&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// 0  : 4&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Version&lt;/span&gt;       &lt;span class=&quot;kt&quot;&gt;uint8&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;// 4  : 4&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;KeySize&lt;/span&gt;       &lt;span class=&quot;kt&quot;&gt;uint8&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;// 5  : 5&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;NKey&lt;/span&gt;          &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// 37 : 32&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;NNew&lt;/span&gt;          &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// 41 : 4&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;NTried&lt;/span&gt;        &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// 45 : 4&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;NewBuckets&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// 49 : 4&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;NewAddrInfo&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CAddrInfo&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;TriedAddrInfo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CAddrInfo&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;CAddrInfo&lt;/code&gt; struct simply mimics the data serlialized in it:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-go&quot; data-lang=&quot;go&quot;&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CAddrInfo&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt;     &lt;span class=&quot;n&quot;&gt;CAddress&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Source&lt;/span&gt;      &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;LastSuccess&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint64&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Attempts&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;Looking into the code for &lt;code class=&quot;highlighter-rouge&quot;&gt;CAddress&lt;/code&gt; in &lt;a href=&quot;https://github.com/bitcoin/bitcoin/blob/5c2aff8d95a932f82a9472975b1d183da6c99e5f/src/protocol.h#L339&quot; target=&quot;_blank&quot;&gt;protocol.h&lt;/a&gt;, we can assemble a &lt;code class=&quot;highlighter-rouge&quot;&gt;CAddress&lt;/code&gt; struct as follows:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-go&quot; data-lang=&quot;go&quot;&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CAddress&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;SerializationVersion&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Time&lt;/span&gt;                 &lt;span class=&quot;kt&quot;&gt;uint32&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ServiceFlags&lt;/span&gt;         &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;PeerAddress&lt;/span&gt;          &lt;span class=&quot;n&quot;&gt;CService&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;Finally, &lt;code class=&quot;highlighter-rouge&quot;&gt;CService&lt;/code&gt; is found in &lt;a href=&quot;https://github.com/bitcoin/bitcoin/blob/c19986940869034cb15e684f014f48fe00e75778/src/netaddress.h#L169&quot; target=&quot;_blank&quot;&gt;netaddress.h&lt;/a&gt;, and converts to a very simple struct:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-go&quot; data-lang=&quot;go&quot;&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CService&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;IPAddress&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Port&lt;/span&gt;      &lt;span class=&quot;kt&quot;&gt;uint16&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// This is serialized as BigEndian&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;These simple structs, chained together, give us an overall structure for &lt;code class=&quot;highlighter-rouge&quot;&gt;peers.dat&lt;/code&gt;. In a comprehensive tree, it looks something like:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;peers.dat
        └── header
           ├── MessageBytes
           ├── Version
           ├── KeySize
           ├── NKey
           ├── NNew
           ├── NTried
           └── NewBuckets
        └── data
        └── repeated
        └── CAddrInfo
        ├── CAddress
           ├── SerializationVersion
           ├── Time
           ├── ServiceFlags
        ├── CService
               ├── IPAddress
               └── Port
        ├── Source
        ├── LastSuccess
        └── Attempts
        └── checksum&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;With the structure of the file all figured out, we can move on to writing the utility to parse it. At this point, the utility itself is quite simple - simply start from the beginning, read the header, loop until &lt;code class=&quot;highlighter-rouge&quot;&gt;NNew + NTried&lt;/code&gt; entries of &lt;code class=&quot;highlighter-rouge&quot;&gt;CAddrInfo&lt;/code&gt; have been read, and then dump the output in the format requested. Instead of putting the boring code in this post, I invite you to visit the &lt;a href=&quot;https://github.com/RaghavSood/bitpeers&quot; target=&quot;_blank&quot;&gt;bitpeers&lt;/a&gt; repo.&lt;/p&gt;
        &lt;p&gt;That said, there is still a chunk of the file after the last tried address before the checksum that is not decoded. As far as I can tell, it does not contain any peer information. Instead, I suspect it is some kind of per-peer/per-bucket integrity check, preventing an attacker from changing all the peers to a set they control. I may work on decoding that in the future, and will update this post if I do.&lt;/p&gt;
        &lt;h2 id=&quot;using-bitpeers&quot;&gt;Using bitpeers&lt;/h2&gt;
        &lt;p&gt;Installing &lt;code class=&quot;highlighter-rouge&quot;&gt;bitpeers&lt;/code&gt; is quite simple, provided you have go installed, and your &lt;code class=&quot;highlighter-rouge&quot;&gt;GOPATH&lt;/code&gt; set up. If not, go has a &lt;a href=&quot;https://golang.org/doc/install&quot; target=&quot;_blank&quot;&gt;handy getting started guide&lt;/a&gt; which you can use to fix that.&lt;/p&gt;
        &lt;p&gt;Once go is set up, simply run&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;go get &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; github.com/RaghavSood/bitpeers/cmd/bitpeers&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;If your go environment is set up properly, you should now have a &lt;code class=&quot;highlighter-rouge&quot;&gt;bitpeers&lt;/code&gt; command available. If not, try finding your &lt;code class=&quot;highlighter-rouge&quot;&gt;GOBIN&lt;/code&gt; (&lt;code class=&quot;highlighter-rouge&quot;&gt;GOPATH/bin&lt;/code&gt;) and adding it to your &lt;code class=&quot;highlighter-rouge&quot;&gt;PATH&lt;/code&gt;.&lt;/p&gt;
        &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;bitpeers&lt;/code&gt; allows you to easily dump &lt;code class=&quot;highlighter-rouge&quot;&gt;peers.dat&lt;/code&gt; addresses as either human-readable plaintext or JSON. It accepts three flags:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;Usage of bitpeers:
        &lt;span class=&quot;nt&quot;&gt;--addressonly&lt;/span&gt;       outputs only addresses &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;specified
        &lt;span class=&quot;nt&quot;&gt;--filepath&lt;/span&gt; string   the path to peers.dat
        &lt;span class=&quot;nt&quot;&gt;--format&lt;/span&gt; string     the output format &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;json|text&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;default &lt;span class=&quot;s2&quot;&gt;&quot;json&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;Running &lt;code class=&quot;highlighter-rouge&quot;&gt;bitpeers --filepath /mnt/doge/.dogecoin/peers.dat --addressonly&lt;/code&gt; will produce a JSON array of all the IPs and ports in &lt;code class=&quot;highlighter-rouge&quot;&gt;peers.dat&lt;/code&gt;. You can also pass the &lt;code class=&quot;highlighter-rouge&quot;&gt;--format text&lt;/code&gt; option to produce a list of all IPs and ports, one IP:port per line.&lt;/p&gt;
        &lt;p&gt;Running without the &lt;code class=&quot;highlighter-rouge&quot;&gt;--addressonly&lt;/code&gt; option will produce the full JSON/text output, which contains the following:&lt;/p&gt;
        &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;bitpeers &lt;span class=&quot;nt&quot;&gt;--filepath&lt;/span&gt; ./peers.dat &lt;span class=&quot;nt&quot;&gt;--format&lt;/span&gt; text
        SerializationVersion: 34fc0100
        Time: 1526192792
        ServiceFlags: 0x000000000000000d
        IP: 42.5.143.180:8333
        Source: 8.8.8.8
        LastSuccess: 1526746622
        Attempts: 0&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
        &lt;p&gt;If you happen to find any inconsistencies or issues with the parser or output, please open an issue on the &lt;a href=&quot;https://github.com/RaghavSood/bitpeers&quot; target=&quot;_blank&quot;&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;</content><author><name></name></author><category term="bitcoin" /><category term="bitcoin-core" /><category term="golang" /><summary type="html">Bitcoin uses a custom format to store peer information. Although the inbuilt JSON-RPC provides a helpful getpeerinfo method to list your active connections, it offers no method to query, dump, or otherwise access the information in peers.dat, which contains far more than just your active connections. Having access to the information in this file can be helpful for a number of reasons, such as finding out information about the network and finding more nodes than just your connections to broadcast transactions to.</summary></entry><entry><title type="html">Why Bitcoin Changed The Game</title><link href="https://raghavsood.com//blog/2018/03/24/why-bitcoin/" rel="alternate" type="text/html" title="Why Bitcoin Changed The Game" /><published>2018-03-24T00:00:00+00:00</published><updated>2018-03-24T00:00:00+00:00</updated><id>https://raghavsood.com//blog/2018/03/24/why-bitcoin</id><content type="html" xml:base="https://raghavsood.com//blog/2018/03/24/why-bitcoin/">&lt;p&gt;Bitcoin did not spawn out of nothing. The fundamental building blocks of Bitcoin were not new, but instead combined in a novel way to fix shortcomings in the individual components. This post aims to shed a little light on where the basics of Bitcoin originated, and why Bitcoin was able to succeed in creating a peer-to-peer electronic cash system where others before it failed.&lt;/p&gt;
        &lt;p&gt;The properties that we are interested in are defined in the introduction of the Bitcoin whitepaper as&lt;/p&gt;
        &lt;blockquote&gt;
        &lt;p&gt;… an electronic payment system based on cryptographic proof instead of trust, allowing any two willing parties to transact directly with each other without the need for a trusted third party. Transactions that are computationally impractical to reverse would protect sellers from fraud, and routine escrow mechanisms could easily be implemented to protect buyers. In this paper, we propose a solution to the double-spending problem using a peer-to-peer distributed timestamp server to generate computational proof of the chronological order of transactions. The system is secure as long as honest nodes collectively control more CPU power than any cooperating group of attacker nodes.&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
        &lt;/blockquote&gt;
        &lt;p&gt;This introduction contains the essence of what Bitcoin is, and also conveniently lists the properties that we are interested in:&lt;/p&gt;
        &lt;ol&gt;
        &lt;li&gt;Cryptographic proof of trust (digital signatures)&lt;/li&gt;
        &lt;li&gt;No trusted party (peer to peer)&lt;/li&gt;
        &lt;li&gt;Transactions are irreversible (proof of work)&lt;/li&gt;
        &lt;li&gt;Chronological ordering of transactions based on computational proof (timestamping proof of work)&lt;/li&gt;
        &lt;/ol&gt;
        &lt;h2 id=&quot;prior-art&quot;&gt;Prior Art&lt;/h2&gt;
        &lt;h3 id=&quot;digital-signatures&quot;&gt;Digital Signatures&lt;/h3&gt;
        &lt;p&gt;Digital signatures predate Bitcoin by far, and this post does not aim to delve into cryptography. Instead, we will focus on their applications to digital cash. Prior to Bitcoin, there were numerous attempts at digital cash, some of them even seeing brief real-world use, such as &lt;a href=&quot;https://en.wikipedia.org/wiki/DigiCash&quot;&gt;DigiCash&lt;/a&gt;. However, these system had shortcomings. For one, they relied on a centralized service. If this service was to go down, all digital transactions would be halted. Additionally, they were unable to cleanly solve the double spending problem. Regardless, the base for digital signatures used for digital cash was established long before Bitcoin.&lt;/p&gt;
        &lt;h4 id=&quot;double-spending&quot;&gt;Double Spending&lt;/h4&gt;
        &lt;p&gt;Understanding what double spending is is essential to understanding why Bitcoin succeeds. By solving it in a decentralized manner, it has fulfilled one of the major gaps in prior digital cash systems (and even real cash systems).&lt;/p&gt;
        &lt;p&gt;In early digital cash system proposals, &quot;cash&quot; was simply a value with a digital signature. This led to the problem that the signed value could easily be duplicated and sent multiple times. In order to prevent this, the notion of unique identifiers was introduced, where cash not only had a value, but also a unique identifier. This value+identifier combination was then signed as one unit. This, in turn, led to another problem - before accepting a payment, the recipient would have to contact whoever issued that cash and ask them if the cash with a given identifier had already been spent. This works well if the issuer is contactable. If it has not been spent, the recipient accepts it and the issuer marks it as spent. If it has been spent, the recipient rejects it. However, if the issuer is uncontactable, the validity of the cash cannot be verified, and no transaction can safely take place. Additionally, after collecting cash, the recipient must now go back to the issuer and have the received cash&apos;s value reissued with a new unique identifier to be able to spend it further.&lt;/p&gt;
        &lt;p&gt;Bitcoin utilized the same digital signatures as proof of ownership, but combines them with a distributed ledger maintained via a proof of work algorithm that prevents double spending. I will go into details on this in the proof of work section below.&lt;/p&gt;
        &lt;h3 id=&quot;peer-to-peer&quot;&gt;Peer to peer&lt;/h3&gt;
        &lt;p&gt;Once again, peer-to-peer (or p2p) systems were nothing new when Bitcoin was announced. In fact, Bitcoin&apos;s implementation of it has next to no notable features. It is simply used as a carrier layer for the blocks and transactions. Numerous p2p systems existed before, such as &lt;a href=&quot;https://en.wikipedia.org/wiki/ARPANET&quot;&gt;ARPANET&lt;/a&gt;, &lt;a href=&quot;https://en.wikipedia.org/wiki/Usenet&quot;&gt;Usenet&lt;/a&gt;, &lt;a href=&quot;https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol&quot;&gt;SMTP&lt;/a&gt;, etc.&lt;/p&gt;
        &lt;h3 id=&quot;proof-of-work&quot;&gt;Proof of Work&lt;/h3&gt;
        &lt;p&gt;This is where half the magic of Bitcoin happens. Proof of work (or PoW) was first proposed in a 1993 article&lt;sup id=&quot;fnref:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; by Cynthia Dwork and Moni Naor. It&apos;s most well-known use prior to Bitcoin is perhaps in Hashcash&lt;sup id=&quot;fnref:3&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:3&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;, a email spam combatting system designed by Adam Back. It is also likely from where Satoshi got the idea, as it is credited in the Bitcoin whitepaper.&lt;/p&gt;
        &lt;p&gt;Proof of work is essentially a problem-solving game. In the simplest form, you must repeatedly solve a mathematical puzzle with different inputs until the output matches certain validation criteria. This validation criteria is changed to increase or reduce the difficulty of finding the solution. Moreover, each attempt must have an equal probability of being the solution for a given set of validation criteria. Lastly, proof of work should be hard to find, but easy to verify. This is usually done by employing a relatively inexpensive hash function as the PoW algorithm, which is easy to compute for a single value. Thus, one needs to compute several values to find a valid hash, but only needs to verify input to the valid solution.&lt;/p&gt;
        &lt;p&gt;Both Bitcoin and Hashcash rely on a very similar proof of work model, where some data (the block header, in the case of Bitcoin) is hashed along with a nonce value repeatedly until the answer falls below a given difficulty level. By including the block header as an input to the puzzle, Bitcoin prevents past work from being reusable for new blocks, thus ensuring that everyone must do new work each time they wish to mine a block.&lt;/p&gt;
        &lt;p&gt;The primary issues with proof of work in systems such as hashcash came about in usability. Hashcash was designed as an email spam combating measure, where each email had a proof of work attached to it, with the amount of work needed scaling up as CPUs became more powerful. This was done with the thought that for normal users sending only a few emails, it would pose no limitation. However, for spammers sending thousands or millions of emails, the cost of computation would quickly exceed what was feasible economically or practically.&lt;/p&gt;
        &lt;p&gt;Unfortunately, most spammers utilized botnets, and would thus be able to rapidly send emails anyways (although Hashcash would certainly slow them down a bit). Moreover, as CPU power increased across average computers, users with older models would fall behind and find it extremely slow to send emails as the hashcash computation requirements went up, forcing otherwise unnecessary upgrades.&lt;/p&gt;
        &lt;h3 id=&quot;timestamping&quot;&gt;Timestamping&lt;/h3&gt;
        &lt;p&gt;In any financial system, maintaining a chronological order of transactions is essential. Without this order, things quickly breakdown as people are spending money they haven&apos;t received, or receiving money from people who have none.&lt;/p&gt;
        &lt;p&gt;Like everything else so far, timestamping is not a new concept. Timestamping was proposed all the way back in 1990 by Haber and Stornetta&lt;sup id=&quot;fnref:4&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:4&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;. They proposed a central service to which an end user may send documents. This central service would then affix a digital signature over the document and the current timestamp, along with a point or link to a previous version of the document. A later paper improved upon this design by batching documents into blocks and signing and linking the blocks instead&lt;sup id=&quot;fnref:5&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:5&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; (sound familiar yet?).&lt;/p&gt;
        &lt;p&gt;However, once again, this service depended on the availability and honest of a centralized timestamping system.&lt;/p&gt;
        &lt;h2 id=&quot;bitcoin&quot;&gt;Bitcoin&lt;/h2&gt;
        &lt;p&gt;The above prior art is only a short look at what existed before Bitcoin. There is much more to this history than what is covered above, and further information can be found in the Further Reading section below. Now, let&apos;s get on to why Bitcoin is so exceptional.&lt;/p&gt;
        &lt;p&gt;To see why Bitcoin is able to achieve something new, we should look at it being built layer by layer.&lt;/p&gt;
        &lt;p&gt;The very first layer is that it is peer-to-peer. This removes reliance on a central authority, as each peer independently stores and validates transactions and blocks. Any peer can start mining the proof of work algorithm and submit new blocks to the network.&lt;/p&gt;
        &lt;p&gt;Within this peer to peer system, there are transactions. Transactions have inputs and outputs (much like DigiCash). Each input is must correspond to a previous output in the blockchain, and each output can only be used in a single input further along in the chain. This rule is enforced by each peer in the network, and transactions attempting to use an output that has already been used in another transaction again are rejected. Finally, each input must be accompanied by an appropriate digital signature from the address it resides in (this is an oversimplification, but suffices for the essence of this post). This solves the double spending problem by allowing each input to be used only once, and enforcing it via a peer to peer system of validation.&lt;/p&gt;
        &lt;p&gt;Miners are able to batch these transactions into blocks by solving the mining puzzle. To solve the puzzle, they must make a list of transactions they wish to include in their block, link them all into a &lt;a href=&quot;https://en.wikipedia.org/wiki/Merkle_tree&quot;&gt;merkle tree&lt;/a&gt;, and use the block hash of the previous block, the root of the merkle tree, and a few other metadata fields to build a block header. This block header is unique to each block, authoritatively defines which transactions are in a block via the merkle root, and links it to the previous block in the chain. This block header is hashed in combination with random nonce values until the result of the hash satisfies the current difficulty requirement of the network. The difficulty requirement is adjusted every 2016 blocks (or every two weeks) in a manner that there is, on average, one solution every ten minutes, and thus one block every ten minutes. As more miners join and perform more computation, blocks are found faster than every 10 minutes. When the next difficulty adjustment happens (every 2016 blocks) the difficulty will be increased so that the same computational power produces a solution every 10 minutes again. Any block submitted that does not meet the difficulty requirement is rejected by the network. As a reward for finding a valid block, miners are allowed to credit a certain amount of new Bitcoin (that decreases with time) to themselves, along with any transaction fees for the transactions included in their block.&lt;/p&gt;
        &lt;p&gt;By using proof of work to limit the creation speed of blocks, Bitcoin creates its own timestamping system. As each block contains transactions, and each block appears after another block, each transaction is timestamped into the blockchain in a specific, verifiable order, without relying on a central timestamping system.&lt;/p&gt;
        &lt;p&gt;When all of these layers are combined, you have a peer-to-peer electronic cash system.&lt;/p&gt;
        &lt;h2 id=&quot;further-reading&quot;&gt;Further Reading&lt;/h2&gt;
        &lt;p&gt;Bitcoin is a vast and complex system, with many nuances. It&apos;s impossible to cover it in a blog post. For further information, I suggest reading &lt;a href=&quot;https://bitcoinbook.info/&quot;&gt;Mastering Bitcoin&lt;/a&gt;, &lt;a href=&quot;http://bitcoinbook.cs.princeton.edu/&quot;&gt;Bitcoin and Cryptocurrency Technologies&lt;/a&gt;, and, of course, the &lt;a href=&quot;https://bitcoin.org/bitcoin.pdf&quot;&gt;Bitcoin Whitepaper&lt;/a&gt;.&lt;/p&gt;
        &lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
        &lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
        &lt;ol&gt;
        &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
        &lt;p&gt;Nakamoto, S. (2008). &lt;em&gt;Bitcoin: A peer-to-peer electronic cash system&lt;/em&gt;. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li id=&quot;fn:2&quot; role=&quot;doc-endnote&quot;&gt;
        &lt;p&gt;Dwork, C., &amp;amp; Naor, M. (1992, August). &lt;em&gt;Pricing via processing or combatting junk mail&lt;/em&gt;. In Annual International Cryptology Conference (pp. 139-147). Springer, Berlin, Heidelberg. &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li id=&quot;fn:3&quot; role=&quot;doc-endnote&quot;&gt;
        &lt;p&gt;Back, A. (2002). &lt;em&gt;Hashcash-a denial of service counter-measure&lt;/em&gt;. &lt;a href=&quot;#fnref:3&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li id=&quot;fn:4&quot; role=&quot;doc-endnote&quot;&gt;
        &lt;p&gt;Haber, S., &amp;amp; Stornetta, W. S. (1990, August). &lt;em&gt;How to time-stamp a digital document&lt;/em&gt;. In Conference on the Theory and Application of Cryptography (pp. 437-455). Springer, Berlin, Heidelberg. &lt;a href=&quot;#fnref:4&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;li id=&quot;fn:5&quot; role=&quot;doc-endnote&quot;&gt;
        &lt;p&gt;Bayer, D., Haber, S., &amp;amp; Stornetta, W. S. (1993). &lt;em&gt;Improving the efficiency and reliability of digital time-stamping&lt;/em&gt;. In Sequences II (pp. 329-334). Springer, New York, NY. &lt;a href=&quot;#fnref:5&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
        &lt;/li&gt;
        &lt;/ol&gt;
        &lt;/div&gt;</content><author><name></name></author><category term="bitcoin" /><category term="blockchain" /><summary type="html">Bitcoin did not spawn out of nothing. The fundamental building blocks of Bitcoin were not new, but instead combined in a novel way to fix shortcomings in the individual components. This post aims to shed a little light on where the basics of Bitcoin originated, and why Bitcoin was able to succeed in creating a peer-to-peer electronic cash system where others before it failed.</summary></entry></feed>