<?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>Forem: Loading Blocks</title>
    <description>The latest articles on Forem by Loading Blocks (@loading_blocks).</description>
    <link>https://forem.com/loading_blocks</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%2F3397221%2Faef68b9d-ce26-47bc-ab30-9c354c966d94.jpeg</url>
      <title>Forem: Loading Blocks</title>
      <link>https://forem.com/loading_blocks</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/loading_blocks"/>
    <language>en</language>
    <item>
      <title>Build Own Blockchain - 2 episode</title>
      <dc:creator>Loading Blocks</dc:creator>
      <pubDate>Mon, 03 Nov 2025 14:23:42 +0000</pubDate>
      <link>https://forem.com/loading_blocks/build-own-blockchain-2-episode-41pm</link>
      <guid>https://forem.com/loading_blocks/build-own-blockchain-2-episode-41pm</guid>
      <description>&lt;p&gt;We usually think of a crypto wallet as just a digital account, like a fancy version of online banking. But when you actually &lt;em&gt;build one from scratch&lt;/em&gt;, you discover that the system under the hood is way more elegant — and way more mathematical — than it looks on the surface. The process really opened my eyes to how cryptography, math, and trust all fit together in the blockchain world.&lt;/p&gt;

&lt;p&gt;Here are &lt;strong&gt;five things&lt;/strong&gt; that really surprised me when I was developing my own wallet.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. Your Public “Key” Isn’t Really a Key — It’s a Point on a Curve
&lt;/h3&gt;

&lt;p&gt;When you first see a public key, it looks like a random string of text. But that string actually represents a &lt;em&gt;point&lt;/em&gt; on something called an &lt;strong&gt;elliptic curve&lt;/strong&gt;. In most cases, that’s the P-256 curve (some blockchains use slightly different ones).&lt;/p&gt;

&lt;p&gt;The public key has two parts — X and Y coordinates — and the long hex string we see is basically just those two numbers stuck together. I remember seeing in the code something like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“take hex of x, hex of y, and concatenate the two strings.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It blew my mind that a crypto “key” isn’t just a password—it’s geometry! It’s a literal point on a mathematical curve that can be verified with pure math. That’s the backbone of ownership and verification in blockchain.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Your Wallet Address Is Just a Fingerprint of Your Public Key
&lt;/h3&gt;

&lt;p&gt;People often mix up &lt;em&gt;wallet addresses&lt;/em&gt; and &lt;em&gt;public keys&lt;/em&gt;, but they’re not the same. The wallet address is actually a &lt;strong&gt;hash&lt;/strong&gt; of your public key — basically a short, one-way fingerprint. In my project, we used &lt;code&gt;SHA-256&lt;/code&gt; to do this.&lt;/p&gt;

&lt;p&gt;Hashing is a one-way process. You can get from a public key to an address easily, but you can’t go backward. That adds a nice privacy layer — your public key isn’t exposed until you spend funds.&lt;/p&gt;

&lt;p&gt;And every blockchain has its own little twist. As one dev in the project said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“address is just some hash of public key... different blockchain has different way of creating the address.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some chains even add custom prefixes (like “evo” for Evo chain). But in the end, the address is just a friendly alias. The real secret sauce lives one step before that…&lt;/p&gt;




&lt;h3&gt;
  
  
  3. The Private Key Is the Only Thing That Really Matters
&lt;/h3&gt;

&lt;p&gt;If you remember &lt;em&gt;one&lt;/em&gt; thing from this article, make it this:&lt;br&gt;
&lt;strong&gt;The private key is everything.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your public key and address can both be regenerated from it. But not the other way around. We built a feature in the wallet that could take a single hex string — the private key — and rebuild the entire wallet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the D value (the integer form of the private key)&lt;/li&gt;
&lt;li&gt;the X/Y coordinates of the public key&lt;/li&gt;
&lt;li&gt;the wallet address&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All perfectly derived from one piece of data. That’s why security warnings are so strict:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Do not share your private key or recovery phrase with anyone.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If someone gets your private key, it’s game over. They basically &lt;em&gt;are&lt;/em&gt; you, financially speaking.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. You Don’t Sign a Transaction — You Sign Its Hash
&lt;/h3&gt;

&lt;p&gt;This part really surprised me. When you “sign” a transaction, you’re not encrypting all the transaction data. You’re just signing its &lt;strong&gt;hash&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here’s roughly how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Bundle the transaction data (sender, receiver, amount, etc.)&lt;/li&gt;
&lt;li&gt;Hash that data with SHA-256&lt;/li&gt;
&lt;li&gt;Use your private key to sign &lt;em&gt;the hash&lt;/em&gt;, not the data itself&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is brilliant for two reasons: it’s super fast, and it’s tamper-proof. If even one comma changes in the transaction, the hash will be totally different — and the signature won’t verify anymore. It’s like a cryptographic checksum that can’t be faked.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Verifying a Signature Means Pretending It Isn’t There
&lt;/h3&gt;

&lt;p&gt;This part feels like a magic trick. To verify a transaction, a blockchain node doesn’t just check the signature directly. It &lt;em&gt;recreates&lt;/em&gt; the signing process — but without the signature itself.&lt;/p&gt;

&lt;p&gt;Here’s the simplified logic:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The node receives the transaction (with signature + public key).&lt;/li&gt;
&lt;li&gt;It sets those two fields aside.&lt;/li&gt;
&lt;li&gt;It re-hashes the transaction from scratch (without the signature).&lt;/li&gt;
&lt;li&gt;Then it uses the public key to check if the signature matches that freshly computed hash.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I saw this in the source:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“we are first storing the signature and public key... then we make them empty, marshal the transaction, hash it again, and finally verify the signature.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That means every node independently proves — mathematically — that the sender had the private key and didn’t tamper with the data. No trust, no middleman, just math.&lt;/p&gt;




&lt;h3&gt;
  
  
  code：
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/ecdsa"&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/elliptic"&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/rand"&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/sha256"&lt;/span&gt;
    &lt;span class="s"&gt;"encoding/hex"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"math/big"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// Transaction structure / 交易结构体（核心字段）&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Transaction&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;From&lt;/span&gt;      &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="c"&gt;// sender address / 发送方地址&lt;/span&gt;
    &lt;span class="n"&gt;To&lt;/span&gt;        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="c"&gt;// receiver address / 接收方地址&lt;/span&gt;
    &lt;span class="n"&gt;Amount&lt;/span&gt;    &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="c"&gt;// transfer amount / 转账金额&lt;/span&gt;
    &lt;span class="n"&gt;Signature&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="c"&gt;// signature (r|s) / 签名&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Hash the transaction data to get a unique fingerprint&lt;/span&gt;
&lt;span class="c"&gt;// 对交易数据进行哈希，得到唯一指纹&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;hashTransaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tx&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Transaction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%s:%s:%d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;From&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;To&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sum256&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// 1️⃣ Generate elliptic curve key pair (P-256)&lt;/span&gt;
    &lt;span class="c"&gt;// 生成椭圆曲线密钥对（P-256）&lt;/span&gt;
    &lt;span class="n"&gt;privKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ecdsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GenerateKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elliptic&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;P256&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Reader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pubKey&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;privKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;privKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// 2️⃣ Generate wallet address by hashing public key&lt;/span&gt;
    &lt;span class="c"&gt;// 通过公钥哈希生成钱包地址&lt;/span&gt;
    &lt;span class="n"&gt;addrHash&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sum256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pubKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;hex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EncodeToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addrHash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Wallet Address / 钱包地址:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// 3️⃣ Create a simple transaction&lt;/span&gt;
    &lt;span class="c"&gt;// 构造简单交易&lt;/span&gt;
    &lt;span class="n"&gt;tx&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Transaction&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;From&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;To&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"receiver_wallet_123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Amount&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// 4️⃣ Hash the transaction (for signing)&lt;/span&gt;
    &lt;span class="c"&gt;// 对交易进行哈希（签名目标）&lt;/span&gt;
    &lt;span class="n"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;hashTransaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// 5️⃣ Sign the transaction hash with private key&lt;/span&gt;
    &lt;span class="c"&gt;// 使用私钥对交易哈希签名（得到 r 和 s）&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ecdsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Reader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;privKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Signature (r|s hex) / 签名:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EncodeToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Signature&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c"&gt;// 6️⃣ Verify the signature using public key&lt;/span&gt;
    &lt;span class="c"&gt;// 使用公钥验证签名&lt;/span&gt;
    &lt;span class="n"&gt;sigLen&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Signature&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;rCheck&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Signature&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;sigLen&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;sCheck&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Signature&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sigLen&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;valid&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ecdsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Verify&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;privKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rCheck&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sCheck&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Signature Verified / 签名验证结果:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;valid&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;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Building a crypto wallet from the ground up taught me that blockchain security isn’t built on complexity — it’s built on &lt;em&gt;clarity&lt;/em&gt;. A handful of elegant cryptographic rules form the foundation of everything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the public key is a point on a curve&lt;/li&gt;
&lt;li&gt;the address is its fingerprint&lt;/li&gt;
&lt;li&gt;and the private key is the single root of trust&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Transactions aren’t trusted — they’re &lt;em&gt;verified&lt;/em&gt;. Every step is grounded in reproducible math.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
    </item>
    <item>
      <title>Build Own Blockchain - 1 episode</title>
      <dc:creator>Loading Blocks</dc:creator>
      <pubDate>Sun, 02 Nov 2025 11:38:45 +0000</pubDate>
      <link>https://forem.com/loading_blocks/build-own-blockchain-1-episode-3l5d</link>
      <guid>https://forem.com/loading_blocks/build-own-blockchain-1-episode-3l5d</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction: From Buzzword to Building Blocks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The word blockchain gets thrown around everywhere — usually surrounded by hype, buzzwords, and way too much mystery. I used to think it was some alien-level technology. But I found the best way to really understand it wasn’t by reading definitions — it was by building one myself.&lt;/p&gt;

&lt;p&gt;So I decided to make a simple blockchain from scratch in Go. The process completely changed how I saw it. Under all the complexity, blockchain is built on a few clean, almost obvious ideas. Here are the five biggest “aha!” moments I had — the ones that turned the concept from something abstract into something I could actually reason about and code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. A Blockchain Is Just a Linked List with Rules&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first big surprise: a blockchain’s core structure isn’t exotic at all. It’s basically a glorified linked list with some cryptographic glue holding it together.&lt;/p&gt;

&lt;p&gt;The basic components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transaction — holds from_address, to_address, and value&lt;/li&gt;
&lt;li&gt;Block — contains a list of transactions, a timestamp, and a field called PreviousHash&lt;/li&gt;
&lt;li&gt;Blockchain — just a slice (blocks []*Block) that stores all the blocks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each block saves the hash of the previous one. That single rule — every block pointing back via hash — is what makes it tamper-evident. The magic isn’t in some fancy data structure, it’s in applying simple cryptography to something familiar.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. “Mining” Is Literally Just Guessing Until You Get Lucky&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I always imagined mining as some super-complicated math problem. Turns out, it’s just brute-force guessing. Proof of Work is basically a loop that keeps changing a number (called nonce) until the resulting hash starts with enough zeros.&lt;/p&gt;

&lt;p&gt;In my code, it goes like this:&lt;/p&gt;

&lt;p&gt;Set nonce = 0&lt;/p&gt;

&lt;p&gt;Combine transactions, previous hash, and nonce into a block&lt;/p&gt;

&lt;p&gt;Hash the whole thing&lt;/p&gt;

&lt;p&gt;Check if the hash starts with the required number of leading zeros (mining_difficulty)&lt;/p&gt;

&lt;p&gt;If not, increment nonce and repeat&lt;/p&gt;

&lt;p&gt;That’s it. Pure trial and error. When I increased difficulty from 4 to 5, and then to 6, the mining time shot up — instantly showing how difficulty scales with computation. Mining isn’t complex, it’s just hard on purpose.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. New Coins Come Out of Thin Air (a “Digital Faucet”)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One thing that confused me early: if every transaction just moves coins around, where do new coins come from? The answer is surprisingly simple — they’re created from nothing as a mining reward.&lt;/p&gt;

&lt;p&gt;When a miner finds a valid block, the program creates a reward transaction. Its from_address is something like "Evo chain faucet". That faucet isn’t a real wallet, so it doesn’t have a private key. Because it can’t sign anything, the transaction has to be added manually to the block — it’s not verified like normal ones.&lt;/p&gt;

&lt;p&gt;That’s literally how new currency enters the system: the code itself mints it as a reward for doing the computational work. In my setup, it was 1200 EVO per block. Kind of wild to see “money” just appear because a loop found a hash with enough zeros.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. The Whole Chain Gets Saved Every Time Something Changes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Persistence was another thing that surprised me. Without a database, the blockchain only lives in memory and disappears when the app stops.&lt;/p&gt;

&lt;p&gt;I used LevelDB as a simple key-value store. The persistence logic was super direct:&lt;/p&gt;

&lt;p&gt;Serialize the whole blockchain struct as a JSON string&lt;/p&gt;

&lt;p&gt;Save it in the DB under one key, "blockchain_key"&lt;/p&gt;

&lt;p&gt;And every time anything changes — new transaction, new block — the entire chain gets serialized and written again. It’s definitely not efficient for a big system, but it’s dead simple and reliable for a prototype. No state gets lost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Wallet Balances Aren’t Stored — They’re Rebuilt from History&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This one blew my mind: there’s no “balance” field stored anywhere. To get your wallet balance, the program recalculates it every time by replaying every transaction in history.&lt;/p&gt;

&lt;p&gt;My first version only added incoming funds, which gave wrong results. The correct approach:&lt;/p&gt;

&lt;p&gt;Start from zero&lt;/p&gt;

&lt;p&gt;Loop through every block&lt;/p&gt;

&lt;p&gt;Loop through every transaction inside it&lt;/p&gt;

&lt;p&gt;If to_address == target, add value&lt;/p&gt;

&lt;p&gt;If from_address == target, subtract value&lt;/p&gt;

&lt;p&gt;At the end, the sum is your balance. Nothing is stored — the balance emerges from the chain’s full transaction history. In this world, history is the state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Building a blockchain by hand stripped away the hype. What’s left is something surprisingly elegant:&lt;/p&gt;

&lt;p&gt;A linked list with cryptographic links&lt;/p&gt;

&lt;p&gt;A brute-force guessing loop for consensus&lt;/p&gt;

&lt;p&gt;A code-driven faucet that mints new coins&lt;/p&gt;

&lt;p&gt;A state that’s just the sum of its entire past&lt;/p&gt;

&lt;p&gt;Once you see it that way, blockchain stops feeling like black magic — and starts looking like one of the simplest, smartest systems you could ever build.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://notebooklm.google.com/notebook/36852097-780c-4f13-b692-633edf05c7de?artifactId=473af00e-8ad6-42d8-94b6-e500d89daa79" rel="noopener noreferrer"&gt;video explain&lt;/a&gt;&lt;/p&gt;

</description>
      <category>web3</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Web3 Development Toolchain</title>
      <dc:creator>Loading Blocks</dc:creator>
      <pubDate>Thu, 02 Oct 2025 08:58:14 +0000</pubDate>
      <link>https://forem.com/loading_blocks/web3-development-toolchain-2d8</link>
      <guid>https://forem.com/loading_blocks/web3-development-toolchain-2d8</guid>
      <description>&lt;p&gt;These artical serve as a practical, step-by-step guide to the essential tools in the modern Web3 development stack. It provides a structured overview of setting up a local development environment with VS Code, managing professional projects with Hard Hat, and establishing scalable blockchain connectivity with Alchemy. Together, these components form a complete workflow for building, testing, and deploying decentralized applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. VS Code + Remix Extension
&lt;/h2&gt;

&lt;p&gt;Purpose: Use VS Code as a professional IDE with Remix features integrated (compile, deploy, debug smart contracts).&lt;/p&gt;

&lt;p&gt;Essential Extensions:&lt;/p&gt;

&lt;p&gt;Ethereum Remix → Compile/deploy/debug from VS Code&lt;/p&gt;

&lt;p&gt;Prettier → Code formatting for consistency&lt;/p&gt;

&lt;p&gt;Solidity → Syntax highlighting and snippets&lt;/p&gt;

&lt;p&gt;Workflow:&lt;/p&gt;

&lt;p&gt;Start remixd client in VS Code&lt;/p&gt;

&lt;p&gt;Open Remix IDE in browser → connect to localhost&lt;/p&gt;

&lt;p&gt;VS Code acts as a proxy, allowing compilation/deployment directly&lt;/p&gt;

&lt;p&gt;Debugger:&lt;/p&gt;

&lt;p&gt;Step Into / Step Over / Step Back / Step Over Back&lt;/p&gt;

&lt;p&gt;Breakpoints for transaction trace navigation&lt;/p&gt;

&lt;p&gt;Limitation: Great for single contracts, but lacks dependency management, automation, and test frameworks → solved by Hard Hat.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Hard Hat — Professional Development Framework
&lt;/h2&gt;

&lt;p&gt;Purpose: Manage the entire contract lifecycle with testing, local blockchain, deployment automation.&lt;/p&gt;

&lt;p&gt;Project Structure:&lt;/p&gt;

&lt;p&gt;contracts/ → Solidity contracts&lt;/p&gt;

&lt;p&gt;scripts/ → Deployment scripts&lt;/p&gt;

&lt;p&gt;test/ → Automated tests (Mocha + Chai)&lt;/p&gt;

&lt;p&gt;hardhat.config.js → Compiler &amp;amp; network config&lt;/p&gt;

&lt;p&gt;Core Commands:&lt;/p&gt;

&lt;p&gt;npx hardhat compile → Compile contracts&lt;/p&gt;

&lt;p&gt;npx hardhat test → Run tests&lt;/p&gt;

&lt;p&gt;npx hardhat node → Launch local in-memory blockchain (20 accounts, each with 10k ETH)&lt;/p&gt;

&lt;p&gt;npx hardhat run script.js --network rinkeby → Execute scripts on chosen network&lt;/p&gt;

&lt;p&gt;Local Network:&lt;/p&gt;

&lt;p&gt;Fast, zero gas cost, pre-funded accounts&lt;/p&gt;

&lt;p&gt;Non-persistent (resets after restart) → perfect for clean test runs&lt;/p&gt;

&lt;p&gt;Key Value: Moves from single-contract debugging to project-level management.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Alchemy — Scalable Node Infrastructure
&lt;/h2&gt;

&lt;p&gt;Purpose: Provide reliable, scalable blockchain node services for production dApps.&lt;/p&gt;

&lt;p&gt;Usage with ethers.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const provider = new ethers.providers.AlchemyProvider("homestead", process.env.ALCHEMY_API_KEY);
const blockNumber = await provider.getBlockNumber();
console.log("Block:", blockNumber);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚠️ Always load API keys from .env, never hardcode.&lt;/p&gt;

&lt;p&gt;Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Global distributed nodes → handle high traffic with low latency&lt;/li&gt;
&lt;li&gt;Analytics dashboard → track requests, response times, most-called RPC methods&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use Cases:&lt;/p&gt;

&lt;p&gt;Large platforms (e.g., OpenSea, Shopify) use Alchemy for scalable, stable blockchain queries&lt;/p&gt;

&lt;h2&gt;
  
  
  Truffle Suite
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Truffle Suite: One of the earliest and Web3 toolchains.&lt;/p&gt;

&lt;p&gt;Positioning: Comparable to Hardhat. Both solve:&lt;/p&gt;

&lt;p&gt;Smart contract compilation, testing, deployment&lt;/p&gt;

&lt;p&gt;Local blockchain simulation&lt;/p&gt;

&lt;p&gt;Key Value: Integrated, end-to-end workflow covering the entire lifecycle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Components
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Truffle (Core Framework)
&lt;/h4&gt;

&lt;p&gt;Provides project structure &amp;amp; CLI.&lt;/p&gt;

&lt;p&gt;Features:&lt;/p&gt;

&lt;p&gt;Automated contract testing (built-in framework)&lt;/p&gt;

&lt;p&gt;Deployment scripting across networks&lt;/p&gt;

&lt;p&gt;Integration with local blockchain (via Ganache)&lt;/p&gt;

&lt;h4&gt;
  
  
  Ganache (Personal Blockchain)
&lt;/h4&gt;

&lt;p&gt;Local Ethereum simulator with instant mining &amp;amp; zero gas costs.&lt;/p&gt;

&lt;p&gt;Advantages:&lt;/p&gt;

&lt;p&gt;GUI for accounts, balances, transactions, contract states&lt;/p&gt;

&lt;p&gt;Same purpose as Hardhat Node, but with visualization&lt;/p&gt;

&lt;p&gt;Easily connects with wallets like MetaMask&lt;/p&gt;

&lt;h4&gt;
  
  
  Drizzle (Front-End Integration Layer)
&lt;/h4&gt;

&lt;p&gt;Simplifies DApp UI ↔ blockchain state sync.&lt;/p&gt;

&lt;p&gt;Features:&lt;/p&gt;

&lt;p&gt;Redux-based core for predictable state management&lt;/p&gt;

&lt;p&gt;Prebuilt React UI components (forms, buttons)&lt;/p&gt;

&lt;p&gt;Automates event listening, transaction tracking&lt;/p&gt;

&lt;p&gt;Trade-off: More dependencies; better for complex DApps, overhead for small projects.&lt;/p&gt;

&lt;h4&gt;
  
  
  Waffle (Testing Framework)
&lt;/h4&gt;

&lt;p&gt;Adds blockchain-aware assertions to tests.&lt;/p&gt;

&lt;p&gt;Benefits:&lt;/p&gt;

&lt;p&gt;expect(...).to.be.reverted → clean revert check&lt;/p&gt;

&lt;p&gt;expect(...).to.emit(...) → declarative event check&lt;/p&gt;

&lt;p&gt;More expressive than vanilla Mocha/Chai.&lt;/p&gt;

&lt;h4&gt;
  
  
  Integrated Workflow
&lt;/h4&gt;

&lt;p&gt;Truffle → Structure, compile, deploy contracts&lt;/p&gt;

&lt;p&gt;Ganache → Local blockchain simulation&lt;/p&gt;

&lt;p&gt;Waffle → Enhanced testing with blockchain matchers&lt;/p&gt;

&lt;p&gt;Drizzle → Keep front-end in sync with contract state&lt;/p&gt;

&lt;p&gt;Result: Full-stack, closed-loop DApp development workflow.&lt;/p&gt;

&lt;h4&gt;
  
  
  Truffle vs. Hardhat – Which One to Choose?
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Truffle&lt;/th&gt;
&lt;th&gt;Hardhat&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Learning Curve&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Beginner-friendly (Ganache GUI, Drizzle support)&lt;/td&gt;
&lt;td&gt;Developer-focused, requires more coding/config comfort&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ecosystem&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Integrated end-to-end suite (compile → test → UI)&lt;/td&gt;
&lt;td&gt;Modular, plugin-rich (Ethers.js, TypeChain, Foundry, etc.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Testing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Works with built-in tests + Waffle&lt;/td&gt;
&lt;td&gt;Flexible, Chai + custom matchers, strong debugging utilities&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Frontend Integration&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Drizzle (Redux-based sync between UI &amp;amp; blockchain)&lt;/td&gt;
&lt;td&gt;No native frontend layer, rely on ethers.js/web3.js&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Community &amp;amp; Adoption&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Earlier tool, smaller community today&lt;/td&gt;
&lt;td&gt;Actively maintained, widely adopted in 2024–2025&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Use Case Fit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Prototypes, educational projects, full-stack DApps needing built-in frontend sync&lt;/td&gt;
&lt;td&gt;Production-grade apps, teams needing scalability, debugging, plugins&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;👉 Rule of thumb:&lt;/p&gt;

&lt;p&gt;Truffle = good for learning, prototypes, integrated frontend.&lt;/p&gt;

&lt;p&gt;Hardhat = better for modern production workflows, plugins, debugging.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
    </item>
    <item>
      <title>Ethers.js Developer Guide – Practical</title>
      <dc:creator>Loading Blocks</dc:creator>
      <pubDate>Sat, 27 Sep 2025 15:50:53 +0000</pubDate>
      <link>https://forem.com/loading_blocks/ethersjs-developer-guide-practical-ocd</link>
      <guid>https://forem.com/loading_blocks/ethersjs-developer-guide-practical-ocd</guid>
      <description>&lt;h2&gt;
  
  
  1. Introduction
&lt;/h2&gt;

&lt;p&gt;Ethers.js is a &lt;strong&gt;lightweight JavaScript library&lt;/strong&gt; for interacting with the Ethereum blockchain. It provides:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A unified way to connect to Ethereum nodes.
&lt;/li&gt;
&lt;li&gt;Tools for creating and managing wallets.
&lt;/li&gt;
&lt;li&gt;A simple API for calling smart contracts.
&lt;/li&gt;
&lt;li&gt;Built-in utilities for handling blockchain-specific data formats (e.g., &lt;code&gt;BigNumber&lt;/code&gt;, hex strings, hashes).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compared to alternatives like &lt;strong&gt;web3.js&lt;/strong&gt;, Ethers.js is designed to be:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Smaller&lt;/strong&gt; (tree-shakeable, modular).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safer&lt;/strong&gt; (immutability, strict typing).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer-friendly&lt;/strong&gt; (clean API surface).
&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;Install via npm (or yarn/pnpm):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;ethers

import &lt;span class="o"&gt;{&lt;/span&gt; ethers &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s2"&gt;"ethers"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

const &lt;span class="o"&gt;{&lt;/span&gt; ethers &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; require&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"ethers"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

async &lt;span class="k"&gt;function &lt;/span&gt;main&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  const provider &lt;span class="o"&gt;=&lt;/span&gt; ethers.getDefaultProvider&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  const blockNumber &lt;span class="o"&gt;=&lt;/span&gt; await provider.getBlockNumber&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Latest block:"&lt;/span&gt;, blockNumber&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

main&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Providers – Connecting to Ethereum&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A Provider is your connection to the Ethereum network. Think of it as a “read-only API”.&lt;/p&gt;

&lt;p&gt;JSON-RPC Provider&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const provider = new ethers.JsonRpcProvider("http://localhost:8545");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Infura&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const provider = new ethers.InfuraProvider("mainnet", process.env.INFURA_API_KEY);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alchemy&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const provider = new ethers.AlchemyProvider("sepolia", process.env.ALCHEMY_API_KEY);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Etherscan (read-only)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const provider = new ethers.EtherscanProvider("mainnet", process.env.ETHERSCAN_API_KEY);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Browser Provider (MetaMask)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const provider = new ethers.BrowserProvider(window.ethereum);
await provider.send("eth_requestAccounts", []);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recap:&lt;/p&gt;

&lt;p&gt;Provider = blockchain connection.&lt;/p&gt;

&lt;p&gt;Use RPC for local, Infura/Alchemy for production, MetaMask for browser.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Wallets – Managing Keys&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A Wallet represents an Ethereum account (private key + address).&lt;/p&gt;

&lt;p&gt;Create a Random Wallet&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const wallet = ethers.Wallet.createRandom();
console.log("Address:", wallet.address);
console.log("Mnemonic:", wallet.mnemonic.phrase);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Import from Private Key&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const wallet = new ethers.Wallet(process.env.PRIVATE_KEY);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Import from Mnemonic&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const wallet = ethers.Wallet.fromPhrase("test test test ...");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Connect Wallet to Provider&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const provider = new ethers.JsonRpcProvider("https://rpc.sepolia.org");
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sign a Message&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const signature = await wallet.signMessage("Hello Ethereum");
console.log("Signature:", signature);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Send a Transaction&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const tx = await wallet.sendTransaction({
  to: "0xabc123...def",
  value: ethers.parseEther("0.01")
});
console.log("Transaction hash:", tx.hash);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚡ Recap:&lt;/p&gt;

&lt;p&gt;Wallet = identity + signer.&lt;/p&gt;

&lt;p&gt;Always connect wallet → provider before sending transactions.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Contracts – Interacting with Smart Contracts&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A Contract object allows you to call functions defined in a smart contract.&lt;/p&gt;

&lt;p&gt;Define a Contract&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const abi = [
  "function balanceOf(address) view returns (uint)",
  "function transfer(address, uint) returns (bool)"
];
const tokenAddress = "0xYourTokenAddress";
const contract = new ethers.Contract(tokenAddress, abi, provider);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read Data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const balance = await contract.balanceOf("0xabc123...");
console.log("Balance:", ethers.formatUnits(balance, 18));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Write Data (with Signer)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
const contractWithSigner = contract.connect(signer);

const tx = await contractWithSigner.transfer("0xdef456...", ethers.parseUnits("1", 18));
await tx.wait();
console.log("Transfer confirmed:", tx.hash);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Listen to Events&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract.on("Transfer", (from, to, value) =&amp;gt; {
  console.log(`Transfer: ${value} tokens from ${from} to ${to}`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recap:&lt;/p&gt;

&lt;p&gt;Contract = interface + ABI + address.&lt;/p&gt;

&lt;p&gt;Use provider for read calls, wallet signer for transactions.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Utilities – Everyday Helpers&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Unit Conversion&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const value = ethers.parseEther("1.0");
console.log(value.toString());
console.log(ethers.formatEther(value));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;BigNumber Math&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const a = ethers.parseUnits("1000", 18);
const b = ethers.parseUnits("250", 18);
console.log(a.add(b).toString());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hashing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const hash = ethers.keccak256(ethers.toUtf8Bytes("hello"));
console.log("Hash:", hash);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Address Helpers&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(ethers.isAddress("0xabc123...")); 
console.log(ethers.getAddress("0xabc123..."));

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚡ Recap: Utilities handle ETH units, big numbers, hashes, addresses.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Advanced Topics&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Gas Estimation &amp;amp; Overrides&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const gas = await contract.estimateGas.transfer("0xdef...", ethers.parseUnits("1", 18));
const tx = await contractWithSigner.transfer("0xdef...", ethers.parseUnits("1", 18), {
  gasLimit: gas * 2n
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Event Filters&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const filter = contract.filters.Transfer(null, "0xdef...");
const events = await contract.queryFilter(filter, -1000, "latest");
console.log(events);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Security Tips&lt;/p&gt;

&lt;p&gt;Never hardcode private keys.&lt;/p&gt;

&lt;p&gt;Use BrowserProvider for frontend dApps.&lt;/p&gt;

&lt;p&gt;Validate user inputs.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Quick Recap (Cheat Sheet)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Provider = connect (JsonRpcProvider, InfuraProvider, BrowserProvider).&lt;/p&gt;

&lt;p&gt;Wallet = manage keys + sign transactions.&lt;/p&gt;

&lt;p&gt;Contract = interact with ABI.&lt;/p&gt;

&lt;p&gt;Utilities = conversions, hashes, addresses.&lt;/p&gt;

&lt;p&gt;Advanced = gas, filters, security.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
      <category>solidity</category>
    </item>
    <item>
      <title>Connecting to the Ethereum Blockchain</title>
      <dc:creator>Loading Blocks</dc:creator>
      <pubDate>Sat, 27 Sep 2025 14:55:54 +0000</pubDate>
      <link>https://forem.com/loading_blocks/connecting-to-the-ethereum-blockchain-3cl0</link>
      <guid>https://forem.com/loading_blocks/connecting-to-the-ethereum-blockchain-3cl0</guid>
      <description>&lt;h1&gt;
  
  
  Ethers.js: MetaMask Client-Side Connection Guide
&lt;/h1&gt;

&lt;p&gt;Ethers.js is a foundational JavaScript library for interacting with the Ethereum blockchain and its ecosystem. It provides a concise yet powerful interface for connecting to Ethereum nodes through providers like JSON-RPC, Infura, Etherscan, Alchemy, Cloudflare, or MetaMask.  &lt;/p&gt;

&lt;p&gt;This guide focuses on client-side dApp integration with &lt;strong&gt;MetaMask&lt;/strong&gt;, targeting experienced front-end developers who want to wire up wallet connectivity and blockchain queries without unnecessary boilerplate.&lt;/p&gt;




&lt;h2&gt;
  
  
  MetaMask Connection Flow
&lt;/h2&gt;

&lt;p&gt;MetaMask injects the &lt;code&gt;window.ethereum&lt;/code&gt; object into the browser context. Your dApp interacts with this object through &lt;strong&gt;Ethers.js&lt;/strong&gt; by wrapping it in a &lt;code&gt;Web3Provider&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Minimal HTML Setup
&lt;/h2&gt;

&lt;p&gt;MetaMask requires a browser context; direct file execution (&lt;code&gt;file:///...&lt;/code&gt;) won’t work. You’ll need to serve your page (e.g., with VS Code &lt;strong&gt;Live Server&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ether.html&lt;/strong&gt;&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&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&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;title&amp;gt;&lt;/span&gt;Ethers.js + MetaMask&lt;span class="nt"&gt;&amp;lt;/title&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;&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/npm/ethers@5.7.2/dist/ethers.min.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&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ethereum&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MetaMask not detected&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="c1"&gt;// 1. Provider from injected Ethereum object&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Web3Provider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ethereum&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="c1"&gt;// 2. Request account access (triggers MetaMask prompt)&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eth_requestAccounts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

      &lt;span class="c1"&gt;// 3. Differentiate: provider vs signer&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;signer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSigner&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="c1"&gt;// 4. Example: fetch data&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blockNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBlockNumber&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Current block:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;blockNumber&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="c1"&gt;// 5. Example: active account&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;signer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAddress&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Connected account:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;})();&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&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;h2&gt;
  
  
  Key Concepts
&lt;/h2&gt;

&lt;p&gt;Provider → read-only blockchain access (e.g., block number, balance, contract state).&lt;/p&gt;

&lt;p&gt;Signer → account-specific, signs transactions/messages, required for state-changing ops.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;Serve with Live Server (VS Code) or any HTTP server.&lt;/p&gt;

&lt;p&gt;Load the page in a MetaMask-enabled browser.&lt;/p&gt;

&lt;p&gt;Approve the connection prompt.&lt;/p&gt;

&lt;p&gt;Inspect the console for current block number and connected address.&lt;/p&gt;

</description>
      <category>solidity</category>
      <category>web3</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Saving Real Money: Rethinking Solidity Gas Optimization</title>
      <dc:creator>Loading Blocks</dc:creator>
      <pubDate>Mon, 22 Sep 2025 15:39:50 +0000</pubDate>
      <link>https://forem.com/loading_blocks/saving-real-money-rethinking-solidity-gas-optimization-2b9d</link>
      <guid>https://forem.com/loading_blocks/saving-real-money-rethinking-solidity-gas-optimization-2b9d</guid>
      <description>&lt;h2&gt;
  
  
  Introduction: Saving Gas from Unexpected Places
&lt;/h2&gt;

&lt;p&gt;In Ethereum development, Gas fees are a very real financial burden. Every deployment, transaction, and state change costs actual money. While most developers look for ways to cut Gas usage, many of the most effective optimization tricks are actually counterintuitive.&lt;/p&gt;

&lt;p&gt;The key to real Gas savings lies in understanding two fundamental principles of the EVM (Ethereum Virtual Machine):&lt;/p&gt;

&lt;p&gt;Storage operations are extremely expensive.&lt;/p&gt;

&lt;p&gt;The EVM is built around a 256-bit (32-byte) word size.&lt;/p&gt;

&lt;p&gt;With these principles in mind, let’s dive into five surprising optimization techniques.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Variable Order Determines Cost — The Magic of Variable Packing
&lt;/h2&gt;

&lt;p&gt;Solidity stores state variables in 32-byte storage slots.&lt;/p&gt;

&lt;p&gt;Multiple smaller variables can be packed into a single slot, but only if declared consecutively.&lt;/p&gt;

&lt;p&gt;Each new slot written requires an expensive STORE operation.&lt;/p&gt;

&lt;p&gt;By rearranging variable declarations, you can reduce the number of slots used.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;Unoptimized: variables consume 3 slots.&lt;/p&gt;

&lt;p&gt;Optimized: variables consume 2 slots by grouping uint8, uint8, and uint128 together.&lt;/p&gt;

&lt;p&gt;👉 Key insight: Put small variables next to each other to maximize packing and minimize storage costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Smaller Variables Are Always Cheaper? Not Really.
&lt;/h2&gt;

&lt;p&gt;A common misconception: using uint8 instead of uint256 always saves Gas.&lt;/p&gt;

&lt;p&gt;In reality, the EVM natively operates on 256-bit words.&lt;/p&gt;

&lt;p&gt;If a small type is not packed, the EVM has to extend it to 256 bits before performing arithmetic, costing extra Gas.&lt;/p&gt;

&lt;p&gt;Rule: Use smaller types only if they can be packed. Otherwise, stick with uint256.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Delete Variables for a Gas Refund
&lt;/h2&gt;

&lt;p&gt;The delete keyword resets a variable to its default value and signals the EVM that storage is being freed.&lt;/p&gt;

&lt;p&gt;As a result, the transaction receives a Gas refund.&lt;/p&gt;

&lt;p&gt;In contrast, x = 0 just performs an STORE with no refund.&lt;/p&gt;

&lt;p&gt;Refunds are capped at about 50% of the transaction Gas used to prevent abuse.&lt;/p&gt;

&lt;p&gt;👉 Key insight: Always use delete instead of manual reset when clearing storage.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Loop Trap: Cache Storage Variables
&lt;/h2&gt;

&lt;p&gt;Reading (SLOAD) or writing (STORE) inside a loop is extremely costly.&lt;/p&gt;

&lt;p&gt;Naïve approach: Every iteration accesses storage directly → 100 costly reads/writes.&lt;/p&gt;

&lt;p&gt;Optimized approach: Cache the value into a local memory variable before the loop, then write back only once.&lt;/p&gt;

&lt;p&gt;This transforms 100 storage operations into just 1, saving massive Gas.&lt;/p&gt;

&lt;p&gt;👉 Key insight: Always cache storage variables in memory when used repeatedly inside loops.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. calldata vs memory — No Free Lunch? Actually, Yes.
&lt;/h2&gt;

&lt;p&gt;calldata: Acts like a read-only “window” into the transaction input. No copying, extremely cheap.&lt;/p&gt;

&lt;p&gt;memory: Requires copying data from calldata into a new memory allocation. More expensive, but allows modifications.&lt;/p&gt;

&lt;p&gt;For external functions where parameters don’t need modification, calldata is always the cheaper and safer choice.&lt;/p&gt;

&lt;p&gt;👉 Key insight: Use calldata for read-only parameters (arrays, strings, structs) in external functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion:
&lt;/h2&gt;

&lt;p&gt;True optimization is not about memorizing rules, but about understanding the EVM’s cost model:&lt;/p&gt;

&lt;p&gt;Storage is expensive.&lt;/p&gt;

&lt;p&gt;Memory is cheap.&lt;/p&gt;

&lt;p&gt;calldata is almost free.&lt;/p&gt;

&lt;p&gt;Computation is cheap, but state changes are not&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
    </item>
    <item>
      <title>Solidity Libraries</title>
      <dc:creator>Loading Blocks</dc:creator>
      <pubDate>Mon, 22 Sep 2025 14:59:54 +0000</pubDate>
      <link>https://forem.com/loading_blocks/solidity-libraries-4ceo</link>
      <guid>https://forem.com/loading_blocks/solidity-libraries-4ceo</guid>
      <description>&lt;h2&gt;
  
  
  1. Five Core Restrictions
&lt;/h2&gt;

&lt;p&gt;Libraries are powerful because of strict rules:&lt;/p&gt;

&lt;p&gt;Stateless: no state variables allowed.&lt;/p&gt;

&lt;p&gt;No inheritance: cannot inherit or be inherited.&lt;/p&gt;

&lt;p&gt;Indestructible: no selfdestruct.&lt;/p&gt;

&lt;p&gt;No payable/fallback: can’t hold ETH.&lt;/p&gt;

&lt;p&gt;No abstract functions: all must be fully implemented.&lt;/p&gt;

&lt;p&gt;These restrictions ensure predictability, safety, and trustworthiness.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The Magic of using for — Extending Data Types
&lt;/h2&gt;

&lt;p&gt;Normal call: Math.max(numbers)&lt;/p&gt;

&lt;p&gt;With using for:&lt;/p&gt;

&lt;p&gt;using Math for int[];&lt;br&gt;
numbers.max();&lt;/p&gt;

&lt;p&gt;Compiler automatically passes the variable (numbers) as the first argument.&lt;/p&gt;

&lt;p&gt;Convention: call this parameter self (like this in OOP).&lt;/p&gt;

&lt;p&gt;This makes Solidity code feel more object-oriented.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Solidity libraries are much more than a toolbox:&lt;/p&gt;

&lt;p&gt;Strict safety rules keep them pure and reliable.&lt;/p&gt;

&lt;p&gt;using for adds elegance and OOP-like syntax.&lt;/p&gt;

&lt;p&gt;Off-chain calls may be free, but on-chain execution still costs Gas.&lt;/p&gt;

&lt;p&gt;Deployable as shared infrastructure → true on-chain microservices.&lt;/p&gt;

&lt;p&gt;They’re not just helpers — they’re a core design pattern for secure, efficient, and modular smart contracts.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
      <category>solidity</category>
    </item>
    <item>
      <title>Abstract Contracts in Solidity</title>
      <dc:creator>Loading Blocks</dc:creator>
      <pubDate>Mon, 22 Sep 2025 14:13:52 +0000</pubDate>
      <link>https://forem.com/loading_blocks/abstract-contracts-in-solidity-287</link>
      <guid>https://forem.com/loading_blocks/abstract-contracts-in-solidity-287</guid>
      <description>&lt;p&gt;In Solidity development, when we talk about contract inheritance or reusable templates, we often think of abstract contracts. &lt;/p&gt;

&lt;p&gt;Many developers see them simply as an interface or an unfinished blueprint. In reality, abstract contracts are much more subtle and powerful. This article reveals four surprising truths about abstract contracts in Solidity that might change the way you design your contracts.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Not Just Empty Shells
&lt;/h2&gt;

&lt;p&gt;Abstract contracts are not just collections of unimplemented functions. They are a &lt;strong&gt;hybrid construct&lt;/strong&gt;—capable of holding both implemented (concrete) functions and unimplemented (abstract) functions.  &lt;/p&gt;

&lt;p&gt;Take the following &lt;code&gt;abstractMath&lt;/code&gt; example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;abstract contract abstractMath {
    // A concrete, implemented function
    function addFive() public view returns (uint) {
        return getValue() + 5; // depends on an unimplemented function
    }

    // An abstract, unimplemented function
    function getValue() public virtual view returns (uint);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;addFive is fully implemented.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;But it relies on getValue, which is not defined here.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Solidity compiler enforces a key rule: any unimplemented function in an abstract contract must be marked as virtual, making it clear that the function is intended to be overridden.&lt;/p&gt;

&lt;p&gt;This pattern is powerful because:&lt;/p&gt;

&lt;p&gt;The base contract (abstractMath) defines core reusable behavior (addFive).&lt;/p&gt;

&lt;p&gt;All child contracts must implement the missing parts (getValue).&lt;/p&gt;

&lt;p&gt;Thus, abstract contracts combine reusability with enforced design constraints.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. “Deployment Failure” Is the Point: Abstract Contracts Cannot Be Instantiated
&lt;/h2&gt;

&lt;p&gt;One fundamental rule: you cannot deploy an abstract contract directly.&lt;/p&gt;

&lt;p&gt;If you try to deploy abstractMath, the compiler will throw an error. This isn’t a bug — it’s by design.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Abstract contracts exist solely to act as parent contracts.&lt;/p&gt;

&lt;p&gt;They define structure and (optionally) partial logic, but they cannot function alone.&lt;/p&gt;

&lt;p&gt;Blocking deployment prevents incomplete or non-functional contracts from being published on-chain. It ensures only fully implemented child contracts reach deployment, avoiding dangerous “half-built” states.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: Beyond Interfaces, Toward Enforceable Design
&lt;/h2&gt;

&lt;p&gt;Abstract contracts in Solidity are far more than unfinished templates. They:&lt;/p&gt;

&lt;p&gt;Can mix reusable logic with abstract requirements.&lt;/p&gt;

&lt;p&gt;Cannot be deployed directly, by design.&lt;/p&gt;

&lt;p&gt;Are strictly enforced by the compiler to guarantee completeness.&lt;/p&gt;

&lt;p&gt;Can be abstract without abstract functions, thanks to internal constructors.&lt;/p&gt;

&lt;p&gt;Together, these rules turn abstract contracts into a powerful design pattern—not just defining structure, but enforcing architecture, ensuring correctness, and making your smart contracts safer and more maintainable.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
      <category>solidity</category>
    </item>
    <item>
      <title>Enums in Solidity</title>
      <dc:creator>Loading Blocks</dc:creator>
      <pubDate>Sun, 21 Sep 2025 15:21:36 +0000</pubDate>
      <link>https://forem.com/loading_blocks/enums-in-solidity-3167</link>
      <guid>https://forem.com/loading_blocks/enums-in-solidity-3167</guid>
      <description>&lt;p&gt;The most intuitive solutions—like using strings or plain numbers—may seem simple at first, but in the world of smart contracts, they hide huge pitfalls. These approaches can either waste gas or hurt code readability and maintainability.&lt;/p&gt;

&lt;p&gt;Fortunately, Solidity provides an elegant and efficient solution: &lt;strong&gt;enums&lt;/strong&gt;. This article uncovers three key insights about enums that will help you write clearer and more efficient smart contracts.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The Simple Trap
&lt;/h2&gt;

&lt;p&gt;When choosing how to represent states, developers often fall into two common traps: using strings or “magic numbers.” Let’s see why both are bad choices in Solidity.&lt;/p&gt;

&lt;h3&gt;
  
  
  The String Problem
&lt;/h3&gt;

&lt;p&gt;Using strings like &lt;code&gt;"pending"&lt;/code&gt; feels natural, but it has major downsides:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;String operations are &lt;strong&gt;expensive&lt;/strong&gt; in Solidity.
&lt;/li&gt;
&lt;li&gt;Comparisons are &lt;strong&gt;inefficient&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Storing and managing them &lt;strong&gt;burns gas unnecessarily&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Magic Number Problem
&lt;/h3&gt;

&lt;p&gt;Another approach is to use integers to represent states:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;1&lt;/code&gt; → pending
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2&lt;/code&gt; → shipped
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;3&lt;/code&gt; → delivered
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While this is more gas-efficient, it destroys readability:   &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In short:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Strings → costly for users (gas).
&lt;/li&gt;
&lt;li&gt;Numbers → costly for developers (maintainability).
Both are unacceptable in smart contract design.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. The Best of Both Worlds: Enum’s Readability and Efficiency
&lt;/h2&gt;

&lt;p&gt;Enums solve both of these problems at once, providing &lt;strong&gt;clarity for developers&lt;/strong&gt; and &lt;strong&gt;efficiency for the EVM&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Concept
&lt;/h3&gt;

&lt;p&gt;An enum lets you define a custom type with a fixed set of named values. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enum Status {
    Pending,
    Shipped,
    Delivered
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Dual Advantages&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;For developers: Enums make code self-explanatory.&lt;br&gt;
&lt;code&gt;if (status == Status.Delivered) { ... }&lt;/code&gt;&lt;br&gt;
is infinitely clearer than status == 2.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For the EVM: Under the hood, enums are just unsigned integers.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Pending = 0&lt;/p&gt;

&lt;p&gt;Shipped = 1&lt;/p&gt;

&lt;p&gt;Delivered = 2&lt;/p&gt;

&lt;p&gt;Enums combine human readability with machine efficiency, making them the go-to tool for state management.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Enums are far more than syntactic sugar—they’re a fundamental building block for writing clear, safe, and efficient Solidity code.&lt;/p&gt;

&lt;p&gt;If you’re writing smart contracts, mastering enums is not optional—it’s essential.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
    </item>
    <item>
      <title>5 Advanced Solidity Modifier Tricks</title>
      <dc:creator>Loading Blocks</dc:creator>
      <pubDate>Sun, 21 Sep 2025 14:42:42 +0000</pubDate>
      <link>https://forem.com/loading_blocks/5-advanced-solidity-modifier-tricks-lbg</link>
      <guid>https://forem.com/loading_blocks/5-advanced-solidity-modifier-tricks-lbg</guid>
      <description>&lt;h2&gt;
  
  
  1. Modifiers Can Change State
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Usual role: run &lt;code&gt;require&lt;/code&gt; checks before function execution.
&lt;/li&gt;
&lt;li&gt;Hidden power: &lt;strong&gt;modifiers can update state variables&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;address public owner;
uint public modifierCount;

modifier onlyOwner {
    require(msg.sender == owner);
    modifierCount++;  // state change inside modifier
    _;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result: modifierCount increases every time onlyOwner is triggered.&lt;/p&gt;

&lt;p&gt;Takeaway: modifiers can serve as pre-processors (logging, state prep, counters).&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Evolution: Dynamic Modifiers With Parameters
&lt;/h2&gt;

&lt;p&gt;(a) Literal Parameters&lt;/p&gt;

&lt;p&gt;Instead of writing many modifiers, pass values directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;modifier cost(uint value) {
    require(msg.value &amp;gt;= value, "Insufficient fee");
    _;
}

function setX() public payable cost(1 ether) { ... }
function setY() public payable cost(2 ether) { ... }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Flexible: one generic modifier → multiple use cases.&lt;/p&gt;

&lt;p&gt;(b) Function Parameters&lt;/p&gt;

&lt;p&gt;Modifiers can also take function arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;modifier greaterThan(uint val, uint min) {
    require(val &amp;gt; min, "Input value is too low");
    _;
}

function setX(uint num) public greaterThan(num, 10) {
    // executes only if num &amp;gt; 10
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Execution Order of Multiple Modifiers
&lt;/h2&gt;

&lt;p&gt;Multiple modifiers run in the listed order.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function setX(uint num) 
    public 
    payable 
    cost(1 ether) 
    greaterThan(num, 10) 
{
    // ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;cost runs first.&lt;/li&gt;
&lt;li&gt;Then greaterThan.&lt;/li&gt;
&lt;li&gt;Only then the function body.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Mechanism: each _ means “execute the next step in the chain”.&lt;/p&gt;

&lt;p&gt;Function body is just the last step in the chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Multiple _ → Multiple Executions
&lt;/h2&gt;

&lt;p&gt;You can place multiple _ in one modifier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;uint public count;

modifier tripleExecute(uint val) {
    require(val &amp;gt; 10, "Too low");
    _;
    _;
    _;
}

function setX(uint num) public tripleExecute(num) {
    count++;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;setX increments count three times per call.&lt;/p&gt;

&lt;p&gt;Rarely practical, but illustrates that _ = “insert function body here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Modifiers can:&lt;/p&gt;

&lt;p&gt;Update state directly.&lt;/p&gt;

&lt;p&gt;Accept dynamic parameters (literals + function inputs).&lt;/p&gt;

&lt;p&gt;Chain together in controlled execution order.&lt;/p&gt;

&lt;p&gt;Execute functions multiple times with multiple _.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
      <category>solidity</category>
    </item>
    <item>
      <title>Solidity Structs</title>
      <dc:creator>Loading Blocks</dc:creator>
      <pubDate>Sun, 21 Sep 2025 14:12:10 +0000</pubDate>
      <link>https://forem.com/loading_blocks/solidity-structs-1pk7</link>
      <guid>https://forem.com/loading_blocks/solidity-structs-1pk7</guid>
      <description>&lt;h2&gt;
  
  
  1. Beyond Simple Data Organization
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Challenge: managing related but different types of data (e.g., &lt;code&gt;string name&lt;/code&gt;, &lt;code&gt;address wallet&lt;/code&gt;, &lt;code&gt;uint balance&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Naive approach: multiple mappings or arrays → messy and hard to maintain.&lt;br&gt;&lt;br&gt;
Solution: &lt;strong&gt;structs&lt;/strong&gt; = custom types that combine multiple fields into one logical unit.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Structs are not just containers, but powerful &lt;strong&gt;data modeling tools&lt;/strong&gt;.    &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Trick 1
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;When accessing a &lt;strong&gt;mapping with struct values&lt;/strong&gt;, if the key was never set:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Solidity does &lt;strong&gt;not&lt;/strong&gt; throw an error.
&lt;/li&gt;
&lt;li&gt;Instead, it returns a &lt;strong&gt;default-initialized struct&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Default values:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;string&lt;/code&gt; → empty string &lt;code&gt;""&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;address&lt;/code&gt; → &lt;code&gt;0x0...0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;uint&lt;/code&gt; → &lt;code&gt;0&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;This allows an &lt;strong&gt;upsert pattern&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No need for &lt;code&gt;if (exists)&lt;/code&gt; checks.
&lt;/li&gt;
&lt;li&gt;Directly assign values whether it’s the first time or an update.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Benefit: simplifies logic, merges &lt;strong&gt;create + update&lt;/strong&gt; into one unified operation.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Trick 2
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Structs can include:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;basic types (&lt;code&gt;string&lt;/code&gt;, &lt;code&gt;uint&lt;/code&gt;),
&lt;/li&gt;
&lt;li&gt;other structs,
&lt;/li&gt;
&lt;li&gt;dynamic arrays&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Example:&lt;br&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct Person {
    string name;
    address addr;
    uint balance;
    Person[] friends;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can push another Person into the friends array.&lt;/p&gt;

&lt;p&gt;Enables building on-chain relationship graphs, e.g., social networks.&lt;/p&gt;

&lt;p&gt;Core insight: struct composition makes advanced modeling possible (nested structs, graphs, linked data).&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Trick 3
&lt;/h2&gt;

&lt;p&gt;In functions, struct variables must specify data location (memory or storage).&lt;/p&gt;

&lt;p&gt;Omit it → compilation error.&lt;/p&gt;

&lt;p&gt;Two initialization methods:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Positional Initialization (compact but order-dependent):&lt;br&gt;
&lt;code&gt;&lt;br&gt;
Person memory p = Person("Tim", msg.sender, msg.value);&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Key-Value Initialization (verbose but flexible):&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Person memory p = Person({
    name: _name,
    addr: msg.sender,
    balance: msg.value
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rules:&lt;/p&gt;

&lt;p&gt;All fields must be provided.&lt;/p&gt;

&lt;p&gt;Both methods enforce complete initialization → prevents partially defined structs.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Conclusion
&lt;/h2&gt;

&lt;p&gt;Structs in Solidity go far beyond simple aggregation&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key powers:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Default struct behavior enables elegant upsert patterns.&lt;/p&gt;

&lt;p&gt;Self-referencing arrays allow building complex graph structures.&lt;/p&gt;

&lt;p&gt;Strict but flexible initialization rules balance readability and safety.&lt;/p&gt;

&lt;p&gt;Together, these form the foundation of clear, rigorous, and powerful on-chain data architectures.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>solidity</category>
    </item>
    <item>
      <title>Time Handling</title>
      <dc:creator>Loading Blocks</dc:creator>
      <pubDate>Sun, 21 Sep 2025 13:32:29 +0000</pubDate>
      <link>https://forem.com/loading_blocks/time-handling-1oof</link>
      <guid>https://forem.com/loading_blocks/time-handling-1oof</guid>
      <description>&lt;h2&gt;
  
  
  1. Block Time, Not Real Time
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;In Solidity, &lt;code&gt;block.timestamp&lt;/code&gt; gives the timestamp of the block that included your transaction, ** not the exact submission time**&lt;/li&gt;
&lt;li&gt;All transactions in the same block share the same &lt;code&gt;block.timestamp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;This means "first come, first served" logic cannot rely on precise timestamps.&lt;/li&gt;
&lt;li&gt;The old keyword &lt;code&gt;now&lt;/code&gt; was just an alias for &lt;code&gt;block.timestamp&lt;/code&gt;, but it's deprecated now. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Get Seconds Since 1970
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;block.timestamp&lt;/code&gt; returns a Unix timestamp, i.e., the number of seconds since &lt;strong&gt;January 1, 1970(Uinx epoch)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;It's a standard across computer science, not unique to Solidity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Solidity Makes Time Arithmetic Simple
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Solidity provides time units: &lt;code&gt;seconds&lt;/code&gt;,&lt;code&gt;minutes&lt;/code&gt;, &lt;code&gt;hours&lt;/code&gt;, &lt;code&gt;days&lt;/code&gt;, &lt;code&gt;weeks&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;These can be used directly in expressions:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;block.timestamp + 1 days&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;block.timestamp - 7 days&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;This improves readablity and prevents errors from using "magic numbers".&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Building Contracts With Lifecycles
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You can implement expiry logic by setting a deadline in the constructor:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
uint public expiry;

constructor() {
    expiry = block.timestamp + 1 minutes;
}

function addOne() public {
    require(block.timestamp &amp;lt; expiry, "Contract has expired");
    count++;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern enables time-based features like token vesting, limited auctions, or timed voting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Correct time handling = safer and more predictable smart contracts.&lt;/li&gt;
&lt;li&gt;Four pillars:&lt;/li&gt;
&lt;li&gt;Block time consensus model.&lt;/li&gt;
&lt;li&gt;Unix timestamp standard.&lt;/li&gt;
&lt;li&gt;Readable time units in Solidity&lt;/li&gt;
&lt;li&gt;Lifecycle enforcement via expiry checks.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
    </item>
  </channel>
</rss>
