<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Andreas Tzionis</title>
    <description>The latest articles on DEV Community by Andreas Tzionis (@liveduo).</description>
    <link>https://dev.to/liveduo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F993417%2F4677707f-7fe6-4443-adcf-a2dc0ab657a8.jpeg</url>
      <title>DEV Community: Andreas Tzionis</title>
      <link>https://dev.to/liveduo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/liveduo"/>
    <language>en</language>
    <item>
      <title>How to create Web Apps in pure Rust</title>
      <dc:creator>Andreas Tzionis</dc:creator>
      <pubDate>Thu, 24 Apr 2025 11:21:34 +0000</pubDate>
      <link>https://dev.to/liveduo/how-to-create-web-apps-in-pure-rust-4p7a</link>
      <guid>https://dev.to/liveduo/how-to-create-web-apps-in-pure-rust-4p7a</guid>
      <description>&lt;p&gt;TinyWeb enables client-side applications to be built in pure Rust, similar to backend applications, leveraging the language strict type system and great built-in tooling.&lt;/p&gt;

&lt;p&gt;It has a tiny footprint with less than 800 lines of code, has no build step and no external dependencies. Yet, it support full-featured webapps!&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 1. Use the starter project
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Fork the &lt;a href="https://github.com/LiveDuo/tinyweb-starter" rel="noopener noreferrer"&gt;tinyweb-starter&lt;/a&gt; project
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/LiveDuo/tinyweb-starter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Option 2. Create a new project
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Create a Rust project
&lt;/h3&gt;

&lt;p&gt;Create a new Rust project with &lt;code&gt;cargo new tinyweb-example --lib&lt;/code&gt;. Add &lt;code&gt;crate-type =["cdylib"]&lt;/code&gt; in &lt;code&gt;Cargo.toml&lt;/code&gt; and install the crate with &lt;code&gt;cargo add tinyweb --git https://github.com/LiveDuo/tinyweb&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Add sample code
&lt;/h3&gt;

&lt;p&gt;Update the &lt;code&gt;src/lib.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;tinyweb&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;element&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;El&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;tinyweb&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;component&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;El&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;El&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"div"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.child&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;El&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"print"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"click"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"alert('hello browser')"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[]);&lt;/span&gt;
        &lt;span class="p"&gt;}))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[no_mangle]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Js&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"return document.querySelector('body')"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;&lt;span class="nf"&gt;.to_ref&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;component&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Load wasm in HTML
&lt;/h3&gt;

&lt;p&gt;Create an &lt;code&gt;index.html&lt;/code&gt; in a new &lt;code&gt;public&lt;/code&gt; folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/gh/LiveDuo/tinyweb/src/js/main.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"application/wasm"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"client.wasm"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Build the wasm
&lt;/h3&gt;

&lt;p&gt;Build the project with &lt;code&gt;cargo build --target wasm32-unknown-unknown -r&lt;/code&gt;. Then &lt;code&gt;cp target/wasm32-unknown-unknown/release/*.wasm public/client.wasm&lt;/code&gt; to get the &lt;code&gt;.wasm&lt;/code&gt; in the right place and serve the &lt;code&gt;public&lt;/code&gt; folder with any static http server.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>rust</category>
      <category>frontend</category>
      <category>html</category>
    </item>
    <item>
      <title>Crypto's anti-network effect</title>
      <dc:creator>Andreas Tzionis</dc:creator>
      <pubDate>Sun, 21 May 2023 21:00:00 +0000</pubDate>
      <link>https://dev.to/liveduo/cryptos-anti-network-effect-18jb</link>
      <guid>https://dev.to/liveduo/cryptos-anti-network-effect-18jb</guid>
      <description>&lt;h3&gt;
  
  
  Network effects
&lt;/h3&gt;

&lt;p&gt;Much of this millenia's history has been marked by a single observation. Networks grow exponentially ie. Metcalfe's law. Not every industry benefits from network effects, but those who do enjoy unique economics and an extreme upside potential.&lt;/p&gt;

&lt;h3&gt;
  
  
  Crypto networks
&lt;/h3&gt;

&lt;p&gt;Every crypto project is becoming a network in multiple ways. A blockchain natively needs an asset exchange, a naming system for human-friendly addresses and at least a bunch of protocols to support the ecosystem like liquid staking, lending platforms, NFT marketplaces, stablecoins and aggregators.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adoption drawbacks
&lt;/h3&gt;

&lt;p&gt;There's also a secondary effect where people joining an ecosystem early are disproportionally interested in its success. Yet, in general the bigger the ecosystem the more tokens are listed in exchanges, the more NFTs are listed in marketplaces and the more the people (in terms of addresses) you can interact with. That effect is arguably dominant in comparison to the early adopter effect mentioned before.&lt;/p&gt;

&lt;p&gt;In short, one could expect "the bigger a network, the bigger it will become", even in crypto. But that's not the case.&lt;/p&gt;

&lt;p&gt;Read more on:&lt;br&gt;
&lt;a href="https://www.tzionis.com/crypto-anti-network-effect"&gt;https://www.tzionis.com/crypto-anti-network-effect&lt;/a&gt;&lt;/p&gt;

</description>
      <category>bitcoin</category>
      <category>distributedsystems</category>
      <category>discuss</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Classifying blockchain tech</title>
      <dc:creator>Andreas Tzionis</dc:creator>
      <pubDate>Sun, 14 May 2023 21:00:00 +0000</pubDate>
      <link>https://dev.to/liveduo/classifying-blockchain-tech-kbb</link>
      <guid>https://dev.to/liveduo/classifying-blockchain-tech-kbb</guid>
      <description>&lt;p&gt;Discussions in crypto, when civilized, are around scalability (ie. tx fees) and security. Hidden behind these high level properties are some fundamental underlying properties that are so central they can be found in any blockchain.&lt;/p&gt;

&lt;p&gt;This properties are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Data availability guarantees&lt;/li&gt;
&lt;li&gt;Compute or execution guarantees&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k-X9LlMy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nznrwhkd0bopewq6hdve.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k-X9LlMy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nznrwhkd0bopewq6hdve.png" alt="Image description" width="686" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Classifications
&lt;/h2&gt;

&lt;h4&gt;
  
  
  1. Part of consensus
&lt;/h4&gt;

&lt;p&gt;When Bitcoin was release data availability was not a topic of discussion. That's because data can be expected to be stored for nodes that are part of consensus. If nodes omit any blockchain data then they might not being able to compute the blockchain state and risk losing their consensis rewards.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s6k9SA3L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0qbxyz4q7iz26ro440kq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s6k9SA3L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0qbxyz4q7iz26ro440kq.png" alt="Image description" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Storage deals
&lt;/h4&gt;

&lt;p&gt;A completely different approach is Filecoin deals. To be clear that is different from Filecoin consensus which follows a conventional pBFT leader-based consensus. Filecoin deals are essentially a marketplace with storage providers, each provider has a reputation based on their history and data is usually stored in multiple operators for better resilience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xB-ZFkXf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k74je76m8uywpqqljgoa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xB-ZFkXf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k74je76m8uywpqqljgoa.png" alt="Image description" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Slashable DAS
&lt;/h4&gt;

&lt;p&gt;If there's agreement on the blockchain data you can run a node to provide an execution environment. That means that data can be safeguard with "cheaper" methods but still have the same security guarantees.&lt;/p&gt;

&lt;p&gt;One such method is data availability sampling (DAS) where a blockchain stores data and does not care about execution. The data are guarantee to be available by random sampling or in other words by continuously requesting random pieces so nodes cannot omit any to not lose rewards.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5a-wEGs1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/goc6ohggc77wyjisyyoh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5a-wEGs1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/goc6ohggc77wyjisyyoh.png" alt="Image description" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Optimistic DAS
&lt;/h4&gt;

&lt;p&gt;A similar method is optimistic data availability sampling. This method still employs succinct proofs to ensure node's store the data but does not enforce slashing for nodes that do not provide the proofs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---pddeRHF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vsnm7vjj4ytutnu3wjz6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---pddeRHF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vsnm7vjj4ytutnu3wjz6.png" alt="Image description" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  More options
&lt;/h2&gt;

&lt;h4&gt;
  
  
  1. Sharding
&lt;/h4&gt;

&lt;p&gt;Data sharding is a method to split data or execution in "committees" that only process part of the blockchain. Near protocol is focusing on sharding its mainnet that is expected to split the network in 4 and hence improve its scalability by 4x.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--G3Xu6gMt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tw33354a10ijd6uragoi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--G3Xu6gMt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tw33354a10ijd6uragoi.png" alt="Image description" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Expiry
&lt;/h2&gt;

&lt;p&gt;State expiry is way to store non-permanent data in a blockchain. Storing data temporarily means that the blockchain size grows in a slower pace and hence nodes will eventually be able to store more data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D8e4vKga--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/opeoee7pby3ceuxdv8qr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D8e4vKga--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/opeoee7pby3ceuxdv8qr.png" alt="Image description" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Read more on:&lt;br&gt;
&lt;a href="https://www.tzionis.com/classifying-blockchain-tech"&gt;https://www.tzionis.com/classifying-blockchain-tech&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How BitTorrent (really) works:</title>
      <dc:creator>Andreas Tzionis</dc:creator>
      <pubDate>Sun, 07 May 2023 23:24:48 +0000</pubDate>
      <link>https://dev.to/liveduo/how-bittorrent-really-works-5hla</link>
      <guid>https://dev.to/liveduo/how-bittorrent-really-works-5hla</guid>
      <description>&lt;h3&gt;
  
  
  1. Discovering nodes
&lt;/h3&gt;

&lt;p&gt;BitTorrent node ip addresses (for a given torrent) are discovered from a DHT network, called Kademlia.&lt;/p&gt;

&lt;p&gt;Kademlia assigns random ids to nodes similar to the data ids (ie. the torrent hash) so nodes know about torrents with ids close to their own.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MNc9u34j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6menqy0wtrfuiixq1bq2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MNc9u34j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6menqy0wtrfuiixq1bq2.png" alt="Image description" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Kademlia messages are sent over UDP and contain a payload and some metadata (type and length).&lt;/p&gt;

&lt;p&gt;The "get_peers" message returns nodes that are closer to a given id (eg. torrent hash).&lt;/p&gt;

&lt;p&gt;Script: &lt;a href="https://github.com/liveduo/bittorrent-scripts/blob/main/1-connect-dht.js"&gt;https://github.com/liveduo/bittorrent-scripts/blob/main/1-connect-dht.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*82 lines of code (depends on &lt;code&gt;bencode&lt;/code&gt; npm package)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o4_f9xtg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/htkj40pen5chsubm3akl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o4_f9xtg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/htkj40pen5chsubm3akl.png" alt="Image description" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To get the nodes that own a given id (ie. torrent hash)  "get_peers" messages are sent recursively to get nodes that closer and closer to the torrent.&lt;/p&gt;

&lt;p&gt;Script: &lt;a href="https://github.com/LiveDuo/bittorrent-scripts/blob/main/2-discover-nodes.js"&gt;https://github.com/LiveDuo/bittorrent-scripts/blob/main/2-discover-nodes.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*130 lines of code (depends on &lt;code&gt;bencode&lt;/code&gt; npm package)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nENLCbct--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/idt6pf32ned2icb1lzpe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nENLCbct--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/idt6pf32ned2icb1lzpe.png" alt="Image description" width="659" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Connecting to a node
&lt;/h3&gt;

&lt;p&gt;Initially (before 2008), BitTorrent needed trackers, centralised servers that contained the torrent metadata.&lt;/p&gt;

&lt;p&gt;This metadata can be size, torrent files, piece hashes for checksums and others.&lt;/p&gt;

&lt;p&gt;Now metadata can be downloaded from nodes in the DHT without centralised parties.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uy_63ZO4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t5i1lbd6sj8tmesbgn2t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uy_63ZO4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t5i1lbd6sj8tmesbgn2t.png" alt="Image description" width="726" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bittorrent messages are sent over TCP and contain a payload and some metadata.&lt;/p&gt;

&lt;p&gt;The "handshake", "interested" and "unchoke" messages establish a connection and interest for a torrent.&lt;/p&gt;

&lt;p&gt;The "bitfield" message shows which pieces a node has and "piece" is used to transfer data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FFn0vb4p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/35ksz1iwxh6g14myldsi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FFn0vb4p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/35ksz1iwxh6g14myldsi.png" alt="Image description" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To connect to a node we first send a "handshake" message. &lt;/p&gt;

&lt;p&gt;We should receive "handshake" and "unchoke" messages if the node is ready for "piece" requests (ie. requests for data).&lt;/p&gt;

&lt;p&gt;Script: &lt;a href="https://github.com/LiveDuo/bittorrent-scripts/blob/main/3-connect-node.js"&gt;https://github.com/LiveDuo/bittorrent-scripts/blob/main/3-connect-node.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*69 lines of code (depends on &lt;code&gt;bencode&lt;/code&gt; npm package)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A4z26Vet--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fx2dqjqch1gtw8ky41sd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A4z26Vet--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fx2dqjqch1gtw8ky41sd.png" alt="Image description" width="659" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Downloading data
&lt;/h3&gt;

&lt;p&gt;Files are transferred in pieces from multiple nodes in parallel.&lt;/p&gt;

&lt;p&gt;When all pieces are received the torrent files can be reconstructed.&lt;/p&gt;

&lt;p&gt;Script: &lt;a href="https://github.com/LiveDuo/bittorrent-scripts/blob/main/4-download-data.js"&gt;https://github.com/LiveDuo/bittorrent-scripts/blob/main/4-download-data.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*165 lines of code (depends on &lt;code&gt;bencode&lt;/code&gt; npm package)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z34VCPqP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wuhv4fnx1n1vl6u9tj1k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z34VCPqP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wuhv4fnx1n1vl6u9tj1k.png" alt="Image description" width="726" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;More details on:&lt;br&gt;
&lt;a href="https://www.tzionis.com/bittorrent-protocol-in-25-minutes"&gt;https://www.tzionis.com/bittorrent-protocol-in-25-minutes&lt;/a&gt;&lt;/p&gt;

</description>
      <category>bittorrent</category>
      <category>distributedsystems</category>
      <category>node</category>
      <category>p2p</category>
    </item>
    <item>
      <title>How Bitcoin (really) works?</title>
      <dc:creator>Andreas Tzionis</dc:creator>
      <pubDate>Tue, 20 Dec 2022 10:19:05 +0000</pubDate>
      <link>https://dev.to/liveduo/how-bitcoin-really-works-44g</link>
      <guid>https://dev.to/liveduo/how-bitcoin-really-works-44g</guid>
      <description>&lt;h3&gt;
  
  
  1. Discovering seed nodes
&lt;/h3&gt;

&lt;p&gt;Bitcoin nodes discover other nodes from a few hardcoded DNS servers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r77VHFYq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bzjsjdac1rek4fei3kss.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r77VHFYq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bzjsjdac1rek4fei3kss.png" alt="discover seed nodes" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Script: &lt;a href="https://github.com/liveduo/bitcoin-scripts/blob/main/1-discover-nodes.js*"&gt;https://github.com/liveduo/bitcoin-scripts/blob/main/1-discover-nodes.js*&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*33 lines of code (no npm dependencies)&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Connecting to a node
&lt;/h3&gt;

&lt;p&gt;Bitcoin messages are sent over TCP and contain a payload and some metadata (type, length and checksum).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--w3aJNlEa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8xx08bs1jp8ldz7ui3g8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--w3aJNlEa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8xx08bs1jp8ldz7ui3g8.png" alt="connect to node" width="880" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first messages sent are "version" and "verack" messages are used to establish a connection. Then, "ping" / "pong" messages are sent periodically to signal the connection is still active.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PQSkoS9X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u50pwc5ypx4xgz0ho4oq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PQSkoS9X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u50pwc5ypx4xgz0ho4oq.png" alt="establishing a connection" width="880" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Script: &lt;a href="https://github.com/liveduo/bitcoin-scripts/blob/main/2-connect-node.js*"&gt;https://github.com/liveduo/bitcoin-scripts/blob/main/2-connect-node.js*&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;*90 lines of code (no npm dependencies)&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Creating an address
&lt;/h3&gt;

&lt;p&gt;Bitcoin addresses are derived from private keys (or seed phrases). Mainnet and testnet addresses have different formats (for most address types).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0X1gJzzX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ocvexraxtfj36ulyioyh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0X1gJzzX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ocvexraxtfj36ulyioyh.png" alt="create a bitcoin address" width="880" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Script: &lt;a href="https://github.com/liveduo/bitcoin-scripts/blob/main/3-create-address.js*"&gt;https://github.com/liveduo/bitcoin-scripts/blob/main/3-create-address.js*&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*67 lines of code (depends on &lt;code&gt;bs58&lt;/code&gt; and &lt;code&gt;secp256k1&lt;/code&gt; npm packages)&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Creating a transaction
&lt;/h3&gt;

&lt;p&gt;Transactions contain inputs and outputs. Inputs validate the owner of the transaction and outputs indicate where the coins should go.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l_-Gs5xo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u8cdod0hqd33tt4mhr99.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l_-Gs5xo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u8cdod0hqd33tt4mhr99.png" alt="create a bitcoin tx" width="880" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Script: &lt;a href="https://github.com/liveduo/bitcoin-scripts/blob/main/4-create-tx.js*"&gt;https://github.com/liveduo/bitcoin-scripts/blob/main/4-create-tx.js*&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*65 lines of code (no npm dependencies)&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Broadcasting a transaction
&lt;/h3&gt;

&lt;p&gt;Node advertise block and tx hashes with "inv" messages. Interested nodes ask for the data with "getdata" messages and receive them as "tx" or "block" messages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HOLD51SH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ufndrhv4cd2cvu1sys6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HOLD51SH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ufndrhv4cd2cvu1sys6.png" alt="broadcast bitcoin tx" width="880" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Script: &lt;a href="https://github.com/liveduo/bitcoin-scripts/blob/main/5-broadcast-tx.js*"&gt;https://github.com/liveduo/bitcoin-scripts/blob/main/5-broadcast-tx.js*&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*163 lines of code (no npm dependencies)&lt;/p&gt;

&lt;h3&gt;
  
  
  What's next
&lt;/h3&gt;

&lt;p&gt;Find more details on:&lt;br&gt;
&lt;a href="https://www.tzionis.com/bitcoin-protocol-in-45-minutes"&gt;https://www.tzionis.com/bitcoin-protocol-in-45-minutes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PS: There are embedded Repl.it scripts that you can run right within the blog post so you don't have to setting up anything locally&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
