<?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: Gopichand</title>
    <description>The latest articles on DEV Community by Gopichand (@gopichand_dev).</description>
    <link>https://dev.to/gopichand_dev</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3882708%2F5d2325f7-46e0-4bd0-a0a5-2d36935df10a.jpg</url>
      <title>DEV Community: Gopichand</title>
      <link>https://dev.to/gopichand_dev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gopichand_dev"/>
    <language>en</language>
    <item>
      <title>Three Token-2022 Mints in One Week: Fees, Yield, and Soul-Bound</title>
      <dc:creator>Gopichand</dc:creator>
      <pubDate>Fri, 12 Jun 2026 09:10:31 +0000</pubDate>
      <link>https://dev.to/gopichand_dev/three-token-2022-mints-in-one-week-fees-yield-and-soul-bound-2b5k</link>
      <guid>https://dev.to/gopichand_dev/three-token-2022-mints-in-one-week-fees-yield-and-soul-bound-2b5k</guid>
      <description>&lt;p&gt;If you have built middleware in Web2, you already understand Token-2022 extensions.&lt;br&gt;
The old SPL token program is like a plain Express router. Token-2022 is the same&lt;br&gt;
router with a plugin system baked in. You opt a single mint into behaviors — fees,&lt;br&gt;
interest, transfer locks — at creation time, and the protocol enforces them forever.&lt;br&gt;
No forking, no custom Rust, no deploying your own program. Just flags.&lt;/p&gt;

&lt;p&gt;I spent Days 50–54 of my #100DaysOfSolana challenge shipping three mints that each&lt;br&gt;
demonstrate one of those behaviors. Here is what I built, the exact commands I ran,&lt;br&gt;
and when you would actually reach for each extension.&lt;/p&gt;


&lt;h2&gt;
  
  
  Mint 1 — Transfer Fee (Days 50 &amp;amp; 51)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mint:&lt;/strong&gt; &lt;code&gt;HxDYFvcXnLuy4VdxXCooUXrch8DZW34oUteQ6N2EFxEr&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Explorer:&lt;/strong&gt; &lt;a href="https://explorer.solana.com/address/HxDYFvcXnLuy4VdxXCooUXrch8DZW34oUteQ6N2EFxEr?cluster=devnet" rel="noopener noreferrer"&gt;View on Devnet&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Extension:&lt;/strong&gt; &lt;code&gt;TransferFeeConfig&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--decimals&lt;/span&gt; 6 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--transfer-fee-basis-points&lt;/span&gt; 100 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--transfer-fee-maximum-fee&lt;/span&gt; 1000000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;--transfer-fee-basis-points 100&lt;/code&gt; means 1% of every transfer is withheld before&lt;br&gt;
the recipient gets credited. The withheld amount sits in the recipient's token&lt;br&gt;
account until a privileged instruction sweeps it to the treasury.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When would you use this?&lt;/strong&gt;&lt;br&gt;
Creator royalties on a community token. A protocol fee on a stablecoin. A DAO&lt;br&gt;
treasury skim that funds development every time the token changes hands. The key&lt;br&gt;
insight: the fee is enforced by the Token-2022 program itself, not by your API.&lt;br&gt;
Nobody can route around it by calling the program directly.&lt;/p&gt;

&lt;p&gt;On Day 51 I ran the full lifecycle — transfer, inspect the withheld amount, then&lt;br&gt;
sweep it back:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token transfer &lt;span class="nv"&gt;$MINT&lt;/span&gt; 1000 &lt;span class="nv"&gt;$RECIPIENT&lt;/span&gt; &lt;span class="nt"&gt;--expected-fee&lt;/span&gt; 10
spl-token withdraw-withheld-tokens &lt;span class="nv"&gt;$MY_TA&lt;/span&gt; &lt;span class="nv"&gt;$RECIPIENT_TA&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;--expected-fee 10&lt;/code&gt; flag is a safety assertion. If the mint's fee math&lt;br&gt;
doesn't produce exactly 10 tokens withheld, the instruction aborts. It is the&lt;br&gt;
on-chain equivalent of an idempotency check.&lt;/p&gt;


&lt;h2&gt;
  
  
  Mint 2 — Transfer Fee + Interest Stacked (Day 52)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mint:&lt;/strong&gt; &lt;code&gt;A6TAeNgxBVwYna8NqQVmBpQzjVYKoZA3e68yMvoVVUva&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Explorer:&lt;/strong&gt; &lt;a href="https://explorer.solana.com/address/A6TAeNgxBVwYna8NqQVmBpQzjVYKoZA3e68yMvoVVUva?cluster=devnet" rel="noopener noreferrer"&gt;View on Devnet&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Extensions:&lt;/strong&gt; &lt;code&gt;TransferFeeConfig&lt;/code&gt; + &lt;code&gt;InterestBearingConfig&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--decimals&lt;/span&gt; 6 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--transfer-fee-basis-points&lt;/span&gt; 100 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--transfer-fee-maximum-fee&lt;/span&gt; 1000000 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--interest-rate&lt;/span&gt; 5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One command, two TLV entries, two completely different mechanics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the interest extension does — and does NOT do:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the subtlety most tutorials skip. The &lt;code&gt;InterestBearingConfig&lt;/code&gt; extension&lt;br&gt;
does &lt;strong&gt;not&lt;/strong&gt; mint new tokens. The raw amount stored on-chain never changes between&lt;br&gt;
transactions. What changes is the &lt;em&gt;UI amount&lt;/em&gt; — the number your wallet displays.&lt;/p&gt;

&lt;p&gt;The formula is: &lt;code&gt;UI amount = raw_amount × e^(rate × time_elapsed)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The network clock and the rate stored on the mint are all the CLI needs to compute&lt;br&gt;
a growing display number every time you query. I proved this by reading the balance&lt;br&gt;
twice with a 30-second sleep between them, with zero transactions in between:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token accounts &lt;span class="nv"&gt;$MINT&lt;/span&gt; &lt;span class="nt"&gt;--verbose&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'NR==3'&lt;/span&gt;
&lt;span class="nb"&gt;sleep &lt;/span&gt;30
spl-token accounts &lt;span class="nv"&gt;$MINT&lt;/span&gt; &lt;span class="nt"&gt;--verbose&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'NR==3'&lt;/span&gt;
&lt;span class="c"&gt;# Output:&lt;/span&gt;
&lt;span class="c"&gt;# 999032.271358&lt;/span&gt;
&lt;span class="c"&gt;# 999032.762062   ← +0.49 tokens, no transaction fired&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think of it like a savings account display ticker. The number on screen grows.&lt;br&gt;
The ledger entry does not change until a real transaction touches it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two extensions, zero conflict:&lt;/strong&gt; TransferFeeConfig operates on raw amounts at&lt;br&gt;
transfer time. InterestBearingConfig operates on the display layer at query time.&lt;br&gt;
They are orthogonal, which is why they compose cleanly on a single mint.&lt;/p&gt;


&lt;h2&gt;
  
  
  Mint 3 — Non-Transferable / Soul-Bound (Day 54)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mint:&lt;/strong&gt; &lt;code&gt;BQzJeZVZgkSvAYPj9f1M1apv56P7kggAgPNc9uSq7T5m&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Explorer:&lt;/strong&gt; &lt;a href="https://explorer.solana.com/address/BQzJeZVZgkSvAYPj9f1M1apv56P7kggAgPNc9uSq7T5m?cluster=devnet" rel="noopener noreferrer"&gt;View on Devnet&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Extension:&lt;/strong&gt; &lt;code&gt;Non-transferable&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token &lt;span class="nt"&gt;--program-2022&lt;/span&gt; &lt;span class="nt"&gt;--enable-non-transferable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I minted one badge token to myself, then deliberately tried to send it to a throwaway wallet. Here is the exact runtime rejection:&lt;br&gt;
Program log: Instruction: TransferChecked&lt;br&gt;
Program log: Transfer is disabled for this mint&lt;br&gt;
Program TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb failed: custom program error: 0x25&lt;br&gt;&lt;br&gt;
Error &lt;code&gt;0x25&lt;/code&gt; is decimal 37, the &lt;code&gt;NonTransferable&lt;/code&gt; entry in the Token-2022 error&lt;br&gt;
enum. The rejection came from the validator, not from the CLI or the RPC layer.&lt;br&gt;
There is no way to call the program "around" the extension. The rule lives on the&lt;br&gt;
asset.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token display &lt;span class="nv"&gt;$MINT&lt;/span&gt;
&lt;span class="c"&gt;# Extensions&lt;/span&gt;
&lt;span class="c"&gt;#   Non-transferable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;When would you use this?&lt;/strong&gt;&lt;br&gt;
Completion certificates. Event attendance proofs. KYC credentials tied to a&lt;br&gt;
specific wallet. Anything where the point is that the credential belongs to the&lt;br&gt;
holder and cannot be resold or delegated.&lt;/p&gt;

&lt;p&gt;In Web2 you would enforce this with a database constraint or an API check. The&lt;br&gt;
risk is that anyone who can reach the database directly can break the rule. On&lt;br&gt;
Solana the rule is in the program. The program is in the validator. There is no&lt;br&gt;
around.&lt;/p&gt;




&lt;h2&gt;
  
  
  What surprised me
&lt;/h2&gt;

&lt;p&gt;I expected the stacking to be complicated. It wasn't. Two flags at creation time,&lt;br&gt;
two TLV entries in the same byte buffer, and the CLI just prints both in the&lt;br&gt;
&lt;code&gt;Extensions&lt;/code&gt; block of &lt;code&gt;spl-token display&lt;/code&gt;. The Token-2022 design is genuinely&lt;br&gt;
composable in a way that feels like it was designed by someone who got burned by&lt;br&gt;
non-composable systems before.&lt;/p&gt;

&lt;p&gt;The interest extension surprised me most. I came in expecting it to mint tokens.&lt;br&gt;
It doesn't. It's a view function disguised as a balance. Once I understood that,&lt;br&gt;
I stopped thinking of it as a financial primitive and started thinking of it as&lt;br&gt;
a display configuration. That reframe changed how I'd use it in a real product —&lt;br&gt;
probably for a points or loyalty system where the raw backing supply is fixed but&lt;br&gt;
the displayed "value" grows over time.&lt;/p&gt;

&lt;p&gt;If I were building a real product today, I'd reach for TransferFeeConfig for any&lt;br&gt;
token that needs sustainable protocol revenue, and NonTransferable for any&lt;br&gt;
credential or badge that should be identity-bound. The interest extension I'd hold&lt;br&gt;
for a specific display-layer use case where the raw supply needs to stay auditable&lt;br&gt;
but the user-facing number should grow.&lt;/p&gt;

&lt;p&gt;All code and terminal output is in my public build log:&lt;br&gt;
👉 &lt;a href="https://github.com/gopichandchalla16/100-days-of-solana" rel="noopener noreferrer"&gt;https://github.com/gopichandchalla16/100-days-of-solana&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Day 55 of #100DaysOfSolana&lt;/em&gt;                  &lt;/p&gt;

</description>
      <category>100daysofsolana</category>
      <category>web3</category>
      <category>tutorial</category>
      <category>learning</category>
    </item>
    <item>
      <title>Solana NFTs Without Metaplex: What I Learned Building with Token Extensions published: true</title>
      <dc:creator>Gopichand</dc:creator>
      <pubDate>Tue, 09 Jun 2026 05:22:24 +0000</pubDate>
      <link>https://dev.to/gopichand_dev/solana-nfts-without-metaplex-what-i-learned-building-with-token-extensionspublished-true-1070</link>
      <guid>https://dev.to/gopichand_dev/solana-nfts-without-metaplex-what-i-learned-building-with-token-extensionspublished-true-1070</guid>
      <description>&lt;p&gt;Before this week I thought you needed Metaplex to build a real Solana NFT. It turns out you can mint a full NFT, stamp metadata directly onto it, group it inside a collection, audit every byte, and mutate it live — using only the Token Extensions program and the SPL token CLI. No third-party framework required.&lt;/p&gt;

&lt;p&gt;This post covers what I built during Days 44–47 of &lt;a href="https://mlh.link/solana-100" rel="noopener noreferrer"&gt;#100DaysOfSolana&lt;/a&gt;, what surprised me coming from a Web2 background, and what I would build next.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Mental Model: What a Solana NFT Actually Is
&lt;/h2&gt;

&lt;p&gt;Before writing a single command, I had to unlearn something. In Web2, an NFT feels like a record in a database that points to a JPEG. On Solana, it is simpler and more precise than that.&lt;/p&gt;

&lt;p&gt;A Solana NFT is just a &lt;strong&gt;mint account&lt;/strong&gt; with three properties set just right:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Supply&lt;/td&gt;
&lt;td&gt;1 (exactly one token exists)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decimals&lt;/td&gt;
&lt;td&gt;0 (cannot be split)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mint authority&lt;/td&gt;
&lt;td&gt;(not set) — disabled forever&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That is it. The "NFT-ness" is not a special program. It is a configuration of the same &lt;a href="https://solana.com/docs/tokens/extensions" rel="noopener noreferrer"&gt;SPL Token primitives&lt;/a&gt; that power every fungible token on the network.&lt;/p&gt;

&lt;p&gt;What makes a &lt;em&gt;modern&lt;/em&gt; Solana NFT different from a bare 1-of-1 token is the &lt;a href="https://solana.com/docs/tokens/extensions" rel="noopener noreferrer"&gt;Token Extensions program (Token-2022)&lt;/a&gt;. Instead of storing metadata in a separate account managed by Metaplex, Token Extensions lets you stamp the name, symbol, URI, and custom fields directly onto the mint account itself. Everything lives in one place. Any wallet, any marketplace, any RPC node can read it without trusting a third-party indexer.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Built: Four Days, Four Commands
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Day 44 — First NFT with on-chain metadata
&lt;/h3&gt;

&lt;p&gt;I minted a 1-of-1 token using the Token-2022 program, initialized a &lt;a href="https://solana.com/docs/tokens/extensions/metadata" rel="noopener noreferrer"&gt;Metadata Pointer extension&lt;/a&gt; on it, and attached a name, symbol, and URI pointing to a JSON file on GitHub Gist.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create the mint with metadata extension enabled&lt;/span&gt;
spl-token create-token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-metadata&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--decimals&lt;/span&gt; 0 &lt;span class="se"&gt;\&lt;/span&gt;
  ./nftTnVuyNU1kwTgv7edG6BPmHCtp2NMrawbw94kwZTF.json

&lt;span class="c"&gt;# Stamp name, symbol, and URI directly onto the mint&lt;/span&gt;
spl-token initialize-metadata &lt;span class="se"&gt;\&lt;/span&gt;
  nftTnVuyNU1kwTgv7edG6BPmHCtp2NMrawbw94kwZTF &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"First Light"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"LIGHT"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://gist.githubusercontent.com/gopichandchalla16/..."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mint address: &lt;code&gt;nftTnVuyNU1kwTgv7edG6BPmHCtp2NMrawbw94kwZTF&lt;/code&gt;&lt;br&gt;
&lt;a href="https://explorer.solana.com/address/nftTnVuyNU1kwTgv7edG6BPmHCtp2NMrawbw94kwZTF?cluster=devnet" rel="noopener noreferrer"&gt;View on Solana Explorer (devnet)&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Day 45 — NFT collection using Group and Member extensions
&lt;/h3&gt;

&lt;p&gt;I created a separate collection mint using the &lt;a href="https://solana.com/docs/tokens/extensions/group-member" rel="noopener noreferrer"&gt;Group extension&lt;/a&gt;, then minted two member NFTs and registered each one under the collection using the Member extension.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Register a member NFT into the collection&lt;/span&gt;
spl-token group-member-initialize &lt;span class="se"&gt;\&lt;/span&gt;
  &amp;lt;MEMBER_MINT&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &amp;lt;COLLECTION_MINT&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The collection mint ended up with &lt;code&gt;Size: 2, Max Size: 3&lt;/code&gt;. Each member NFT carries a &lt;code&gt;Group&lt;/code&gt; field that points byte-for-byte to the collection mint — the on-chain equivalent of a foreign key.&lt;/p&gt;




&lt;h3&gt;
  
  
  Day 46 — Auditing every byte on devnet
&lt;/h3&gt;

&lt;p&gt;Instead of trusting that everything worked, I read both mints back from devnet the same way a senior engineer reviews their own work before shipping.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token display nftTnVuyNU1kwTgv7edG6BPmHCtp2NMrawbw94kwZTF
spl-token display AC3peC3tdZUnLY44zGYC7YAuEaPknkMcRqsmAyvXJtMx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key check was this line inside &lt;code&gt;Token Group Member&lt;/code&gt; on each member NFT:&lt;br&gt;
Group: AC3peC3tdZUnLY44zGYC7YAuEaPknkMcRqsmAyvXJtMx ✅&lt;br&gt;&lt;br&gt;
That address matches the collection mint exactly. Phantom and every marketplace reads this field to verify collection membership — without trusting any off-chain index. That is what "verifiable provenance" actually means. Not marketing. Just two byte arrays comparing equal.&lt;/p&gt;


&lt;h3&gt;
  
  
  Day 47 — Mutating metadata live
&lt;/h3&gt;

&lt;p&gt;This was the day I stopped treating the NFT like a fragile artifact and started treating it like a live row of data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Rename it&lt;/span&gt;
spl-token update-metadata nftTnVuy... name &lt;span class="s2"&gt;"Field Notes"&lt;/span&gt;

&lt;span class="c"&gt;# Add a custom field — the schema is completely open&lt;/span&gt;
spl-token update-metadata nftTnVuy... rarity legendary

&lt;span class="c"&gt;# Remove it&lt;/span&gt;
spl-token update-metadata nftTnVuy... rarity &lt;span class="nt"&gt;--remove&lt;/span&gt;

&lt;span class="c"&gt;# Swap the URI to point at a new metadata JSON&lt;/span&gt;
spl-token update-metadata nftTnVuy... uri https://gist.githubusercontent.com/janvinsha/...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every command was one transaction. Every change appeared in Explorer within seconds.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Surprising Part
&lt;/h2&gt;

&lt;p&gt;Three things hit differently than I expected coming from Web2.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The on-chain layer and the off-chain layer move at different speeds.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When I renamed the NFT to "Field Notes", Explorer showed the new name in seconds. But the image — which lives at the URI I pointed at, hosted on GitHub Gist — stayed cached in wallets for much longer. The on-chain pointer updates instantly. The thing it points at does not. This is why serious NFT projects use &lt;a href="https://www.arweave.org/" rel="noopener noreferrer"&gt;Arweave&lt;/a&gt; or &lt;a href="https://ipfs.tech/" rel="noopener noreferrer"&gt;IPFS&lt;/a&gt; for permanent image hosting instead of a mutable HTTP server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. There is no separate NFT program.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I kept waiting to discover the "real" NFT layer. There is none. The same Token-2022 program that handles transfer fees, interest-bearing tokens, and compliance controls is also the program that handles NFT metadata and collections. Extensions compose on the same primitives.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The metadata schema is a blank canvas.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;additional_metadata&lt;/code&gt; array accepts any key-value pair you want. I stamped &lt;code&gt;rarity: legendary&lt;/code&gt; onto a live mint in one CLI call and watched it appear on Explorer. No migrations. No schema definitions. No contract upgrades. Just one transaction.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Would Build Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Permanent image hosting&lt;/strong&gt; — move the image URI from GitHub Gist to Arweave so the pointer and the asset are both permanent&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic NFT&lt;/strong&gt; — use the mutable metadata to track something that changes over time, like XP or level in a game (Solana's official &lt;a href="https://solana.com/developers/guides/token-extensions/dynamic-meta-data-nft" rel="noopener noreferrer"&gt;Dynamic Metadata NFT guide&lt;/a&gt; covers this pattern)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metaplex comparison&lt;/strong&gt; — &lt;a href="https://developers.metaplex.com/core" rel="noopener noreferrer"&gt;Metaplex Core&lt;/a&gt; is the dominant alternative NFT standard on Solana, with a different account structure and royalty model. I want to build the same collection in both standards and write a direct comparison.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Resources I Actually Used
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://solana.com/docs/tokens/extensions" rel="noopener noreferrer"&gt;Token Extensions overview&lt;/a&gt; — the canonical reference&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://solana.com/docs/tokens/extensions/metadata" rel="noopener noreferrer"&gt;Metadata Pointer and Token Metadata&lt;/a&gt; — how metadata lives on the mint&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://solana.com/docs/tokens/extensions/group-member" rel="noopener noreferrer"&gt;Token Groups and Members&lt;/a&gt; — how collection membership works&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://solana.com/developers/guides/token-extensions/dynamic-meta-data-nft" rel="noopener noreferrer"&gt;Dynamic Metadata NFTs guide&lt;/a&gt; — the official Solana guide for what comes next&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://explorer.solana.com/?cluster=devnet" rel="noopener noreferrer"&gt;Solana Explorer (devnet)&lt;/a&gt; — for verifying every change live&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;All the code and terminal output from every day is in my public repo:&lt;br&gt;
👉 &lt;a href="https://github.com/gopichandchalla16/100-days-of-solana" rel="noopener noreferrer"&gt;github.com/gopichandchalla16/100-days-of-solana&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This post is part of #100DaysOfSolana. Follow along or jump in any day at &lt;a href="https://mlh.link/solana-100" rel="noopener noreferrer"&gt;mlh.link/solana-100&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>100daysofsolana</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>nft</category>
    </item>
    <item>
      <title>44 Days of Solana: From an Empty README to a Live NFT on-chain — My Finish-Up-A-Thon Story</title>
      <dc:creator>Gopichand</dc:creator>
      <pubDate>Thu, 04 Jun 2026 05:55:51 +0000</pubDate>
      <link>https://dev.to/gopichand_dev/44-days-of-solana-from-an-empty-readme-to-a-live-nft-on-chain-my-finish-up-a-thon-story-fmg</link>
      <guid>https://dev.to/gopichand_dev/44-days-of-solana-from-an-empty-readme-to-a-live-nft-on-chain-my-finish-up-a-thon-story-fmg</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-05-21"&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Honestly, I almost didn't write this post.&lt;/p&gt;

&lt;p&gt;Not because I didn't have anything to show — but because I kept telling myself&lt;br&gt;
"it's not done yet." Sound familiar?&lt;/p&gt;

&lt;p&gt;Back in early 2026, I started a repo called&lt;br&gt;
&lt;strong&gt;&lt;a href="https://github.com/gopichandchalla16/100-days-of-solana" rel="noopener noreferrer"&gt;100 Days of Solana&lt;/a&gt;&lt;/strong&gt;.&lt;br&gt;
The idea was simple: learn Solana development from absolute zero, build&lt;br&gt;
something on-chain every single day, and document it publicly.&lt;/p&gt;

&lt;p&gt;Day 1, I generated a keypair. That was it. One file in the repo —&lt;br&gt;
a README with a title and no code. I had no blockchain background,&lt;br&gt;
only a Web2 history in Python and JavaScript. I didn't even know&lt;br&gt;
what "rent" meant in the context of Solana accounts.&lt;/p&gt;

&lt;p&gt;But I kept showing up. 44 days later, here's what that same repo became:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Wallets, airdrops, SOL transfers, SPL token creation&lt;/li&gt;
&lt;li&gt;✅ Token-2022 extensions — transfer fees, interest-bearing tokens,
default frozen, non-transferable (soulbound), permanent delegate&lt;/li&gt;
&lt;li&gt;✅ A fully named, on-chain NFT — "First Light" — with metadata,
image, and permanently locked supply. Minted using &lt;strong&gt;only&lt;/strong&gt; the Solana CLI.
No Metaplex. No framework.&lt;/li&gt;
&lt;li&gt;✅ 9 published DEV.to articles translating every concept into
Web2-friendly language&lt;/li&gt;
&lt;li&gt;✅ Every single transaction signature linked to Solana Explorer
so you can verify my work on-chain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This project means more to me than any side project I've ever started.&lt;br&gt;
It's proof that 30 minutes a day, compounded over 44 days,&lt;br&gt;
produces something real and verifiable.&lt;/p&gt;

&lt;p&gt;And GitHub Copilot is a big reason I didn't quit on Day 8, Day 23, or Day 39.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔗 Repo:&lt;/strong&gt; &lt;a href="https://github.com/gopichandchalla16/100-days-of-solana" rel="noopener noreferrer"&gt;https://github.com/gopichandchalla16/100-days-of-solana&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🌐 "First Light" — My First NFT, Live on Solana Devnet
&lt;/h3&gt;

&lt;p&gt;I built this NFT end-to-end using nothing but &lt;code&gt;spl-token&lt;/code&gt; CLI commands.&lt;br&gt;
No framework. No JS. Just me, the terminal, and a lot of patience.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Name&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;First Light&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Symbol&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;LIGHT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Mint Address&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nftTnVuyNU1kwTgv7edG6BPmHCtp2NMrawbw94kwZTF&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Program&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Token-2022&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Supply&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1 (locked forever)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Decimals&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Extensions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;metadataPointer&lt;/code&gt; + &lt;code&gt;tokenMetadata&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Mint Authority&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Disabled 🔒&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;🔗 &lt;a href="https://explorer.solana.com/address/nftTnVuyNU1kwTgv7edG6BPmHCtp2NMrawbw94kwZTF?cluster=devnet" rel="noopener noreferrer"&gt;View "First Light" on Solana Explorer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The vanity keypair starting with &lt;code&gt;nft&lt;/code&gt; took about 20 minutes to generate&lt;br&gt;
locally using &lt;code&gt;solana-keygen grind&lt;/code&gt;. Every character you see in that address&lt;br&gt;
was intentional.&lt;/p&gt;




&lt;h3&gt;
  
  
  📋 Every Step — Verified On-Chain
&lt;/h3&gt;

&lt;p&gt;Here are all 5 transactions, in order. You can click any of them and&lt;br&gt;
see exactly what happened on the Solana blockchain:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;What I Did&lt;/th&gt;
&lt;th&gt;Verified Transaction&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Created mint account, initialized metadata pointer, initialized mint&lt;/td&gt;
&lt;td&gt;&lt;a href="https://explorer.solana.com/tx/3iXwaWfk8YfVMQRvPGHdzAMKEZ2xK45EXciYt8mDc47QGGptkqpBEca2LxAup4wUHKZ1NjhWTy6RJpU6rpbjzXtz?cluster=devnet" rel="noopener noreferrer"&gt;3iXwa…jzXtz&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Initialized token metadata — name, symbol, URI&lt;/td&gt;
&lt;td&gt;&lt;a href="https://explorer.solana.com/tx/45PYGZMbBXBP3S1Fuo6jqNi4Uv8gq2qbQ4GFnaPEVRoY5durKMK5SiY3UHW3rESjGptPPShGWfKA37YgBuXKv2D4?cluster=devnet" rel="noopener noreferrer"&gt;45PYG…Kv2D4&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Created the associated token account&lt;/td&gt;
&lt;td&gt;&lt;a href="https://explorer.solana.com/tx/gWLGogf4iCfWu62iw4mVLnaEQQ3zv7pebvP4tMKGmL1UA5xttqPQnwjWHxebPpyV6L3GBPboaLXo3EGuNoYmmgj?cluster=devnet" rel="noopener noreferrer"&gt;gWLGo…Ymmgj&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Minted exactly 1 token&lt;/td&gt;
&lt;td&gt;&lt;a href="https://explorer.solana.com/tx/3B8MS16hQ4itmB3pr76SfGZUkhzvMFtmtGggCGzpTbeUjLDqh7n37qMb8aWugnKAFFaNKhqsFJZAHtxZYfTwrQoP?cluster=devnet" rel="noopener noreferrer"&gt;3B8MS…wrQoP&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Revoked mint authority — forever&lt;/td&gt;
&lt;td&gt;&lt;a href="https://explorer.solana.com/tx/3YhopR7CCQwGkShGYcTx2Rnibg8oYgQXd1HiYi8DqcpQiZre4QUHk5pBrHSdzXwkk2TVRdXyEcfVpeMuwX3kckqo?cluster=devnet" rel="noopener noreferrer"&gt;3Yhop…kckqo&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;No one can ever mint another LIGHT token. That is by design.&lt;/p&gt;




&lt;h3&gt;
  
  
  📰 9 Published DEV.to Articles (300+ total reactions)
&lt;/h3&gt;

&lt;p&gt;These are not just summaries of what I did. Each one is a full&lt;br&gt;
explanation written specifically for Web2 developers entering the&lt;br&gt;
Solana ecosystem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/gopichand_dev/your-public-key-is-your-identity-what-web2-devs-need-to-know-about-solana-4lpm"&gt;Your Public Key Is Your Identity — What Web2 Devs Need to Know About Solana&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/gopichand_dev/solana-transactions-explained-for-backend-developers-with-real-failures-2ido"&gt;Solana Transactions Explained for Backend Developers (With Real Failures)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/gopichand_dev/i-built-5-token-extension-combinations-on-solana-this-week-heres-what-each-one-does-4ck3"&gt;I Built 5 Token Extension Combinations on Solana This Week — Here's What Each One Does&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📊 Where the Project Stands
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🟣 Daily Build Progress&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;44 / 100 Days Complete&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🖤 DEV.to Articles&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;9 Published&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🟢 On-Chain Transactions&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Live on Solana Devnet&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📄 License&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;MIT&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔒 NFT Mint Authority&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Disabled Forever&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  The Comeback Story
&lt;/h2&gt;

&lt;p&gt;Let me be honest about where this project started and where it almost ended.&lt;/p&gt;

&lt;h3&gt;
  
  
  Day 1 — What the repo actually looked like
&lt;/h3&gt;

&lt;p&gt;gopichandchalla16/100-days-of-solana&lt;br&gt;
└── README.md ← literally just a title&lt;br&gt;&lt;br&gt;
That was it. I had written "100 Days of Solana — learning in public"&lt;br&gt;
and committed it at midnight. No code. No plan. Just a title and the&lt;br&gt;
pressure of having put it on GitHub.&lt;/p&gt;

&lt;p&gt;The first week was rough. The Solana docs are not beginner-friendly&lt;br&gt;
if you're coming from Web2. The Token-2022 documentation is especially&lt;br&gt;
sparse. I spent 3 hours on Day 4 just trying to understand why my&lt;br&gt;
airdrop wasn't showing up (I was checking the wrong cluster).&lt;/p&gt;

&lt;p&gt;There were three moments where I almost stopped entirely:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Day 8&lt;/strong&gt; — I couldn't figure out why my token transfer kept failing&lt;br&gt;
with a cryptic &lt;code&gt;0x1&lt;/code&gt; error. I had been at it for two hours and it was&lt;br&gt;
past midnight. I nearly closed the laptop and told myself I'd "come back to it."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Day 23&lt;/strong&gt; — I hit a wall with Token-2022 extension architecture.&lt;br&gt;
I understood how individual extensions worked but not how to compose&lt;br&gt;
them safely. Nothing I read explained it in plain terms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Day 39&lt;/strong&gt; — The NFT build broke on step 2 of 5. My metadata wasn't&lt;br&gt;
being initialized because I ran &lt;code&gt;initialize-mint&lt;/code&gt; before&lt;br&gt;
&lt;code&gt;initialize-metadata-pointer&lt;/code&gt;. The error wasn't obvious.&lt;br&gt;
I almost started over from scratch.&lt;/p&gt;

&lt;p&gt;I didn't quit any of those nights. GitHub Copilot helped me through&lt;br&gt;
each one — and I'll explain exactly how in the Copilot section.&lt;/p&gt;




&lt;h3&gt;
  
  
  Day 44 — What the repo became
&lt;/h3&gt;

&lt;p&gt;gopichandchalla16/100-days-of-solana&lt;br&gt;
├── day-01/ through day-44/ ← 44 documented daily builds&lt;br&gt;
├── 9 DEV.to articles published&lt;br&gt;
├── Every tx signature verified on Solana Explorer&lt;br&gt;
├── Token-2022 extensions built and tested:&lt;br&gt;
│ ├── Transfer fees (compliance use case)&lt;br&gt;
│ ├── Interest-bearing tokens (DeFi use case)&lt;br&gt;
│ ├── Default frozen + thaw (regulated assets)&lt;br&gt;
│ ├── Non-transferable / soulbound (credentials)&lt;br&gt;
│ └── Permanent delegate (revocable access)&lt;br&gt;
├── NFT "First Light" — vanity keypair, Token-2022,&lt;br&gt;
│ on-chain metadata, locked supply&lt;br&gt;
└── README with live progress bar, week logs,&lt;br&gt;
all explorer links&lt;br&gt;&lt;br&gt;
The difference between Day 1 and Day 44 is not just the code.&lt;br&gt;
It's the understanding behind it.&lt;/p&gt;




&lt;h3&gt;
  
  
  The 3 moments that defined this project
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Day 13 — The account model finally made sense.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I had been running &lt;code&gt;solana balance&lt;/code&gt; and &lt;code&gt;spl-token create-account&lt;/code&gt; for&lt;br&gt;
days without really understanding &lt;em&gt;why&lt;/em&gt; Solana accounts need rent.&lt;br&gt;
Then I sat down and wrote a DEV.to article explaining it with a&lt;br&gt;
Web2 analogy: &lt;em&gt;accounts are like database rows, rent is like a monthly&lt;br&gt;
hosting fee — stop paying and the row gets deleted.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Writing that article forced me to understand it deeply enough to&lt;br&gt;
explain it simply. After Day 13, I stopped copying commands and started&lt;br&gt;
understanding what each one actually does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Days 36–40 — Five Token-2022 extension combinations in one week.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This was the hardest week. I built:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A transfer fee token (simulating a transaction tax)&lt;/li&gt;
&lt;li&gt;An interest-bearing token (simulating a yield-bearing asset)&lt;/li&gt;
&lt;li&gt;A default-frozen token with thaw authority (compliance gating)&lt;/li&gt;
&lt;li&gt;A non-transferable soulbound token (on-chain credential)&lt;/li&gt;
&lt;li&gt;A permanent delegate token (revocable programmatic access)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each one is a real devnet transaction. Each one has a verifiable&lt;br&gt;
signature on Solana Explorer. Each one taught me something different&lt;br&gt;
about how Token-2022 is designed to handle real-world financial&lt;br&gt;
and compliance scenarios.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Days 43–44 — My first NFT. No Metaplex. Just the CLI.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I wanted to understand NFTs at the protocol level — not through&lt;br&gt;
a framework, not through a library, but through raw &lt;code&gt;spl-token&lt;/code&gt; commands.&lt;/p&gt;

&lt;p&gt;I generated a vanity keypair starting with &lt;code&gt;nft&lt;/code&gt; using &lt;code&gt;solana-keygen grind&lt;/code&gt;.&lt;br&gt;
I added two Token-2022 extensions: &lt;code&gt;metadataPointer&lt;/code&gt; and &lt;code&gt;tokenMetadata&lt;/code&gt;.&lt;br&gt;
I minted exactly 1 token. I disabled the mint authority forever.&lt;/p&gt;

&lt;p&gt;"First Light" now lives on-chain permanently with its name, symbol,&lt;br&gt;
and metadata URI intact. Nobody can create another one. That's what makes it an NFT.&lt;/p&gt;




&lt;h3&gt;
  
  
  The biggest technical lesson of 44 days
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Token-2022 extensions cannot be added after mint creation. Ever.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There's no workaround. No patch. No update instruction.&lt;br&gt;
You must decide your full extension set before you run&lt;br&gt;
&lt;code&gt;initialize-mint&lt;/code&gt;. It's like designing a database schema —&lt;br&gt;
you can't add a non-nullable column without a migration.&lt;/p&gt;

&lt;p&gt;I learned this the hard way on Day 38 when I tried to add&lt;br&gt;
&lt;code&gt;interest-bearing&lt;/code&gt; to an existing mint. The transaction failed&lt;br&gt;
and I had to start the token from scratch. That 30-minute mistake&lt;br&gt;
became the most important architectural lesson I've had in 44 days.&lt;/p&gt;




&lt;h2&gt;
  
  
  My Experience with GitHub Copilot
&lt;/h2&gt;

&lt;p&gt;I want to be specific here, not just say "Copilot helped a lot."&lt;br&gt;
Here are the exact moments where it made the difference.&lt;/p&gt;




&lt;h3&gt;
  
  
  When I was stuck on &lt;code&gt;0x11&lt;/code&gt; at midnight (Day 37)
&lt;/h3&gt;

&lt;p&gt;My compliance-gated token transfer failed with error &lt;code&gt;0x11&lt;/code&gt; —&lt;br&gt;
&lt;code&gt;AccountFrozen&lt;/code&gt;. I knew the token was frozen by design but I thought&lt;br&gt;
I had thawed it. The transaction kept failing anyway.&lt;/p&gt;

&lt;p&gt;I was staring at the error in my terminal. Copilot's inline suggestion&lt;br&gt;
explained what I was missing: &lt;strong&gt;both the sender's ATA and the&lt;br&gt;
recipient's ATA need to be thawed&lt;/strong&gt; — not just the sender's.&lt;br&gt;
One suggestion. One minute. Problem solved.&lt;/p&gt;

&lt;p&gt;Without Copilot, I would have been digging through the SPL Token&lt;br&gt;
source code for the next hour — or worse, I would have given up&lt;br&gt;
and moved on without truly understanding the error.&lt;/p&gt;




&lt;h3&gt;
  
  
  When soulbound tokens confused me (Day 40)
&lt;/h3&gt;

&lt;p&gt;Non-transferable tokens are conceptually simple — once minted to a&lt;br&gt;
wallet, they can never move. But when I tried to demonstrate this&lt;br&gt;
by attempting a transfer, the transaction failed with &lt;code&gt;0x25&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I didn't expect the error. Copilot explained: non-transferable tokens&lt;br&gt;
can be burned but not transferred. It then suggested I write a burn&lt;br&gt;
script to demonstrate the constraint properly — which turned into&lt;br&gt;
the best hands-on example in my Week 6 article.&lt;/p&gt;

&lt;p&gt;The bug became the feature. That happens a lot when Copilot is involved.&lt;/p&gt;




&lt;h3&gt;
  
  
  Writing CLI commands faster and correctly
&lt;/h3&gt;

&lt;p&gt;The Token-2022 program ID is 44 characters long:&lt;br&gt;
TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb&lt;br&gt;&lt;br&gt;
Before Copilot, I copied this from docs and sometimes mis-pasted it.&lt;br&gt;
With Copilot, it autocompleted the entire ID, the &lt;code&gt;--program-id&lt;/code&gt; flag,&lt;br&gt;
all the relevant options, and even the correct sequence of commands.&lt;/p&gt;

&lt;p&gt;The sequence matters enormously in Token-2022. For the NFT build,&lt;br&gt;
&lt;code&gt;initialize-metadata-pointer&lt;/code&gt; &lt;strong&gt;must&lt;/strong&gt; come before &lt;code&gt;initialize-mint&lt;/code&gt;.&lt;br&gt;
The Solana docs don't emphasize this clearly for beginners.&lt;br&gt;
Copilot's autocomplete surfaced the correct order naturally,&lt;br&gt;
in context, while I was typing. That saved me from the exact error&lt;br&gt;
that had broken my build on Day 39.&lt;/p&gt;




&lt;h3&gt;
  
  
  Turning raw terminal output into readable articles
&lt;/h3&gt;

&lt;p&gt;Every DEV.to article I wrote started the same way:&lt;br&gt;
a terminal window full of transaction signatures, error codes,&lt;br&gt;
and hex-encoded account data.&lt;/p&gt;

&lt;p&gt;Copilot helped me turn that raw output into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clear Web2 analogies that explain Solana concepts without jargon&lt;/li&gt;
&lt;li&gt;A consistent structure: &lt;em&gt;what I planned → what broke → what I learned&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Opening paragraphs that hook readers who have never touched blockchain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nine articles. 300+ reactions across all of them.&lt;br&gt;
That audience engagement would not exist without Copilot helping me&lt;br&gt;
bridge the gap between "developer notes" and "readable article."&lt;/p&gt;




&lt;h3&gt;
  
  
  Explaining the "why" — not just the "how"
&lt;/h3&gt;

&lt;p&gt;This is the thing I appreciate most about Copilot, and it's hard to&lt;br&gt;
quantify. When a command worked, I often didn't fully understand &lt;em&gt;why&lt;/em&gt;&lt;br&gt;
it worked. Copilot's inline comments filled those gaps constantly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;"This flag enables close authority so you can reclaim rent later."&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"The metadata pointer must be initialized first because the mint
instruction reads the extension list."&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"Revoking mint authority is a one-way operation — there's no
re-enable instruction in Token-2022."&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These micro-explanations compounded over 44 days into real,&lt;br&gt;
deep understanding of the protocol. I'm not just writing Solana&lt;br&gt;
commands anymore. I understand what they do and why they exist.&lt;/p&gt;




&lt;h3&gt;
  
  
  The honest summary
&lt;/h3&gt;

&lt;p&gt;GitHub Copilot didn't write this project for me.&lt;br&gt;
Every transaction on Solana Explorer is a decision I made,&lt;br&gt;
a command I typed, a concept I understood.&lt;/p&gt;

&lt;p&gt;But Copilot removed the friction that would have made me quit.&lt;br&gt;
It turned 2-hour debugging sessions into 10-minute ones.&lt;br&gt;
It turned terminal output into articles people actually read.&lt;br&gt;
It turned "I don't understand this" into "oh, that's why."&lt;/p&gt;

&lt;p&gt;44 days in. 56 to go. I'm not stopping.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;🔗 GitHub Repo:&lt;/strong&gt; &lt;a href="https://github.com/gopichandchalla16/100-days-of-solana" rel="noopener noreferrer"&gt;https://github.com/gopichandchalla16/100-days-of-solana&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📰 DEV Profile:&lt;/strong&gt; &lt;a href="https://dev.to/gopichand_dev"&gt;https://dev.to/gopichand_dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🐦 X / Twitter:&lt;/strong&gt; &lt;a href="https://x.com/GopichandAI" rel="noopener noreferrer"&gt;https://x.com/GopichandAI&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you're a Web2 developer curious about Solana — follow the repo.&lt;br&gt;
Every day folder has the exact commands I ran, the errors I hit,&lt;br&gt;
and what I learned. It's all there.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;#100DaysOfSolana #Solana #Web3 #BuildInPublic&lt;/em&gt;             &lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>githubcopilot</category>
      <category>web3</category>
    </item>
    <item>
      <title>I Built 5 Token Extension Combinations on Solana This Week — Here's What Each One Does</title>
      <dc:creator>Gopichand</dc:creator>
      <pubDate>Tue, 02 Jun 2026 06:04:10 +0000</pubDate>
      <link>https://dev.to/gopichand_dev/i-built-5-token-extension-combinations-on-solana-this-week-heres-what-each-one-does-4ck3</link>
      <guid>https://dev.to/gopichand_dev/i-built-5-token-extension-combinations-on-solana-this-week-heres-what-each-one-does-4ck3</guid>
      <description>&lt;p&gt;If you have ever used a brokerage account, you already understand token extensions.&lt;/p&gt;

&lt;p&gt;Your brokerage locks your account until you verify your identity. A stock you own cannot be&lt;br&gt;
transferred to someone else without compliance checks on both sides. A professional license&lt;br&gt;
is tied to you — the issuing body can revoke it, but you cannot sell it. An interest-bearing&lt;br&gt;
savings account accrues value over time without you doing anything.&lt;/p&gt;

&lt;p&gt;All of these are real-world rules applied to value. &lt;strong&gt;Token-2022 extensions let you encode&lt;br&gt;
those same rules directly into a Solana token mint&lt;/strong&gt; — at the protocol level, not the&lt;br&gt;
application layer. No backend. No database. No API that can go down.&lt;/p&gt;

&lt;p&gt;Over the past several days I built five different token configurations as part of my&lt;br&gt;
&lt;a href="https://github.com/gopichandchalla16/100-days-of-solana" rel="noopener noreferrer"&gt;100 Days of Solana&lt;/a&gt; challenge.&lt;br&gt;
Here is what I learned.&lt;/p&gt;


&lt;h2&gt;
  
  
  What Are Token Extensions?
&lt;/h2&gt;

&lt;p&gt;Token-2022 is Solana's upgraded token program&lt;br&gt;
(&lt;code&gt;TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb&lt;/code&gt;).&lt;br&gt;
It is backwards-compatible with the original SPL Token program, but it lets you attach&lt;br&gt;
&lt;strong&gt;extensions&lt;/strong&gt; to a mint at creation time.&lt;/p&gt;

&lt;p&gt;Extensions are stored as TLV (type-length-value) blobs in the mint account's data.&lt;br&gt;
Each extension adds bytes, and those bytes cost rent. More extensions = bigger account =&lt;br&gt;
more SOL locked at creation. That is the core tradeoff to understand before you design&lt;br&gt;
a token.&lt;/p&gt;


&lt;h2&gt;
  
  
  Extension 1 — Interest-Bearing Tokens
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Web2 analogy:&lt;/strong&gt; A savings account that accrues interest over time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--interest-rate&lt;/span&gt; 500
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This sets an initial rate of &lt;strong&gt;500 basis points (5%)&lt;/strong&gt;. The rate can be updated later by&lt;br&gt;
the rate authority:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token set-interest-rate &amp;lt;MINT_ADDRESS&amp;gt; 15000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What surprised me:&lt;/strong&gt; The extension does NOT mint new tokens. It is purely a&lt;br&gt;
&lt;strong&gt;calculation layer&lt;/strong&gt;. Wallets and apps read the rate and elapsed time to display an&lt;br&gt;
adjusted "UI balance." The raw on-chain balance stays the same. When you run&lt;br&gt;
&lt;code&gt;spl-token display&lt;/code&gt;, you see both:&lt;br&gt;
Current rate: 15000bps&lt;br&gt;
Average rate: 500bps ← historical average is preserved&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Use cases:&lt;/strong&gt; Yield-bearing stablecoins, loyalty points that grow over time,&lt;br&gt;
reward tokens for long-term holders.&lt;/p&gt;


&lt;h2&gt;
  
  
  Extension 2 — Transfer Fees
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Web2 analogy:&lt;/strong&gt; A payment processor that takes a cut of every transaction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--transfer-fee&lt;/span&gt; 100 50000
&lt;span class="c"&gt;# 100 basis points (1%) fee, max 50000 tokens per transfer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fees are collected at the &lt;strong&gt;token account level&lt;/strong&gt; (withheld in the recipient's account),&lt;br&gt;
not sent automatically. The withdrawal authority must harvest them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token withdraw-withheld-tokens &amp;lt;DESTINATION&amp;gt; &lt;span class="nt"&gt;--include-mints&lt;/span&gt; &amp;lt;MINT&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What surprised me:&lt;/strong&gt; The fee is enforced by the Token-2022 program itself on every&lt;br&gt;
&lt;code&gt;TransferChecked&lt;/code&gt; instruction. No smart contract needed. No way to bypass it from&lt;br&gt;
the frontend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use cases:&lt;/strong&gt; Protocol revenue, DAO treasury funding, creator royalties on every transfer.&lt;/p&gt;


&lt;h2&gt;
  
  
  Extension 3 — Default Account State (Frozen)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Web2 analogy:&lt;/strong&gt; A brokerage that freezes every new account until KYC passes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-freeze&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--default-account-state&lt;/span&gt; frozen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every token account created for this mint starts in a &lt;strong&gt;frozen&lt;/strong&gt; state. Nobody can&lt;br&gt;
receive, send, or burn tokens until the freeze authority explicitly thaws them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token thaw &amp;lt;TOKEN_ACCOUNT_ADDRESS&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The key insight I learned the hard way:&lt;/strong&gt; It is not enough for the &lt;em&gt;sender&lt;/em&gt; to be&lt;br&gt;
thawed. The &lt;em&gt;recipient&lt;/em&gt; must also be thawed. Both sides need to pass the compliance check.&lt;/p&gt;

&lt;p&gt;When I tried to transfer from a thawed account to a still-frozen one:    Program log: Error: Account is frozen (custom program error: 0x11)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Use cases:&lt;/strong&gt; Regulated security tokens, KYC-gated stablecoins, permissioned loyalty&lt;br&gt;
programs.&lt;/p&gt;


&lt;h2&gt;
  
  
  Extension 4 — Non-Transferable (Soulbound)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Web2 analogy:&lt;/strong&gt; A professional certification that belongs to you — you cannot sell it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-non-transferable&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--decimals&lt;/span&gt; 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;--decimals 0&lt;/code&gt; because credentials are whole units. You either have the credential or&lt;br&gt;
you don't.&lt;/p&gt;

&lt;p&gt;Any transfer attempt fails immediately:                                  Program log: Transfer is disabled for this mint (custom program error: 0x25)&lt;br&gt;&lt;br&gt;
&lt;code&gt;0x25&lt;/code&gt; = decimal 37 = &lt;code&gt;NonTransferableError&lt;/code&gt; in the Token-2022 source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use cases:&lt;/strong&gt; DAO membership badges, hackathon completion certificates,&lt;br&gt;
verified contributor status, employee access tokens.&lt;/p&gt;


&lt;h2&gt;
  
  
  Extension 5 — Permanent Delegate (Revocable)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Web2 analogy:&lt;/strong&gt; Your employer can revoke your access badge at any time, without&lt;br&gt;
asking you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-permanent-delegate&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-non-transferable&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-metadata&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--decimals&lt;/span&gt; 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Combining &lt;code&gt;--enable-non-transferable&lt;/code&gt; with &lt;code&gt;--enable-permanent-delegate&lt;/code&gt; creates a&lt;br&gt;
&lt;strong&gt;revocable soulbound token&lt;/strong&gt;: the holder cannot move it, but the issuer can burn it&lt;br&gt;
from any account without the holder's signature.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Revoke the credential — no holder signature needed&lt;/span&gt;
spl-token burn &amp;lt;RECIPIENT_TOKEN_ACCOUNT&amp;gt; 1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--owner&lt;/span&gt; ~/.config/solana/id.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What surprised me:&lt;/strong&gt; The Solana runtime logs a warning whenever a token account is&lt;br&gt;
created for a mint with a permanent delegate:&lt;br&gt;
Warning: Mint has a permanent delegate,&lt;br&gt;
so tokens in this account may be seized at any time&lt;br&gt;&lt;br&gt;
Full transparency baked in at the protocol level. The holder is informed at account&lt;br&gt;
creation — not buried in a ToS.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Cost of Extensions
&lt;/h2&gt;

&lt;p&gt;Each extension adds bytes to the mint account. More bytes = more rent-exempt SOL:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Configuration&lt;/th&gt;
&lt;th&gt;Data Size&lt;/th&gt;
&lt;th&gt;Rent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Default frozen only&lt;/td&gt;
&lt;td&gt;171 bytes&lt;/td&gt;
&lt;td&gt;~0.0021 SOL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Interest-bearing only&lt;/td&gt;
&lt;td&gt;222 bytes&lt;/td&gt;
&lt;td&gt;~0.0024 SOL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transfer fees + Interest + Metadata&lt;/td&gt;
&lt;td&gt;599 bytes&lt;/td&gt;
&lt;td&gt;~0.0051 SOL&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Metadata is the biggest cost driver because it stores variable-length strings&lt;br&gt;
(name, symbol, URI) directly inside the mint account. Every character costs rent.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Cannot Be Changed After Creation
&lt;/h2&gt;

&lt;p&gt;This is the part that matters most before mainnet deployment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Extensions cannot be added after mint creation.&lt;/strong&gt; The account is allocated with
exactly the space for the declared extensions. You must plan upfront.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The permanent delegate cannot be removed&lt;/strong&gt; once set (only transferred to a different
address if the current delegate signs).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-transferable is permanent.&lt;/strong&gt; Once set, no authority can enable transfers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it like a database schema. Define it before you insert the first row.&lt;/p&gt;




&lt;h2&gt;
  
  
  Inspecting Any Token Extension Config
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token display &amp;lt;MINT_ADDRESS&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This single command decodes every extension in the mint account and prints it in&lt;br&gt;
human-readable form. I now run this before touching any Token-2022 mint I didn't&lt;br&gt;
create myself.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where to Go Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://solana.com/docs/tokens/extensions" rel="noopener noreferrer"&gt;Token Extensions official docs&lt;/a&gt; — the
canonical reference, well-maintained&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.solana-program.com/docs/token-2022/extensions" rel="noopener noreferrer"&gt;Token-2022 Extensions Guide&lt;/a&gt; —
deeper per-extension implementation notes&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/gopichandchalla16/100-days-of-solana" rel="noopener noreferrer"&gt;My full 100 Days of Solana repo&lt;/a&gt; —
every command I ran, every error I hit, documented day by day&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The best way to learn these is to run the CLI commands yourself on devnet. Each failure&lt;br&gt;
message tells you exactly what rule was violated and which error code fired. That feedback&lt;br&gt;
loop is faster than any tutorial.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This post is part of my #100DaysOfSolana challenge — building and documenting in public&lt;br&gt;
every day. Follow along on &lt;a href="https://twitter.com/GopichandAI" rel="noopener noreferrer"&gt;X @GopichandAI&lt;/a&gt; or&lt;br&gt;
&lt;a href="https://github.com/gopichandchalla16" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;                                                                     &lt;/p&gt;

</description>
      <category>100daysofsolana</category>
      <category>web3</category>
      <category>blockchain</category>
      <category>learning</category>
    </item>
    <item>
      <title>Transfer Fees, Metadata, and Soulbound Tokens: A Tour of Solana Token Extensions</title>
      <dc:creator>Gopichand</dc:creator>
      <pubDate>Sun, 24 May 2026 17:05:43 +0000</pubDate>
      <link>https://dev.to/gopichand_dev/transfer-fees-metadata-and-soulbound-tokens-a-tour-of-solana-token-extensions-42bj</link>
      <guid>https://dev.to/gopichand_dev/transfer-fees-metadata-and-soulbound-tokens-a-tour-of-solana-token-extensions-42bj</guid>
      <description>&lt;p&gt;I spent the last five days building tokens on Solana — and it completely&lt;br&gt;
changed how I think about what a "token" actually is.&lt;/p&gt;

&lt;p&gt;Coming from Web2 and EVM development, I assumed a token was a number in a&lt;br&gt;
database with some transfer logic wrapped around it. On Solana, it's much&lt;br&gt;
closer to a configurable protocol object. Here's everything I learned across&lt;br&gt;
Days 29–33 of my #100DaysOfSolana challenge.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Starting Point: Two Token Programs
&lt;/h2&gt;

&lt;p&gt;Solana has two token programs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SPL Token (original)&lt;/strong&gt; — simple, battle-tested, does the basics&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token Extensions Program (Token-2022)&lt;/strong&gt; — everything the original does,
plus built-in extensions for fees, metadata, soulbound tokens, and more&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I used Token-2022 for almost everything this week because it lets you attach&lt;br&gt;
behavior directly to the mint — no separate smart contract needed.&lt;/p&gt;


&lt;h2&gt;
  
  
  Day 29 — Creating My First SPL Token
&lt;/h2&gt;

&lt;p&gt;The first thing that surprised me: a token on Solana is two separate accounts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mint account&lt;/strong&gt; — holds the token's configuration (supply, decimals,
mint authority)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token account&lt;/strong&gt; — holds a specific wallet's balance of that token
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token &lt;span class="nt"&gt;--decimals&lt;/span&gt; 9
spl-token create-account &amp;lt;MINT_ADDRESS&amp;gt;
spl-token mint &amp;lt;MINT_ADDRESS&amp;gt; 1000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In Web2, this would be one database table with a balance column. On Solana,&lt;br&gt;
the separation means the mint config is completely independent of who holds&lt;br&gt;
what — any wallet can hold any token as long as they have a token account for it.&lt;/p&gt;


&lt;h2&gt;
  
  
  Day 30 — Token-2022 with On-Chain Metadata
&lt;/h2&gt;

&lt;p&gt;The original SPL token has no name or symbol stored on-chain. You need an&lt;br&gt;
external metadata program (Metaplex) to give it an identity. Token-2022&lt;br&gt;
changes this with the &lt;strong&gt;metadata extension&lt;/strong&gt; — name, symbol, and URI live&lt;br&gt;
directly inside the mint account.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-metadata&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--decimals&lt;/span&gt; 9

spl-token initialize-metadata &amp;lt;MINT_ADDRESS&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"GopichandToken"&lt;/span&gt; &lt;span class="s2"&gt;"GOPI"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://your-metadata-uri.json"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;spl-token display &amp;lt;MINT_ADDRESS&amp;gt;&lt;/code&gt; and you'll see the name and symbol&lt;br&gt;
sitting right there in the mint account output. No external call. No&lt;br&gt;
separate metadata program. The token &lt;em&gt;is&lt;/em&gt; the metadata.&lt;/p&gt;


&lt;h2&gt;
  
  
  Day 31 — Transfer Fees at the Protocol Level
&lt;/h2&gt;

&lt;p&gt;This is where it got interesting. I attached a &lt;strong&gt;1% transfer fee&lt;/strong&gt; to a&lt;br&gt;
token mint — meaning every transfer automatically withholds 1% in the&lt;br&gt;
recipient's token account, uncollectable by the recipient, waiting for the&lt;br&gt;
mint authority to withdraw.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--transfer-fee-basis-points&lt;/span&gt; 100 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--transfer-fee-maximum-fee&lt;/span&gt; 5000 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--decimals&lt;/span&gt; 9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After transferring 100 tokens, the recipient got 99. The 1 withheld token&lt;br&gt;
sat locked in their account until I ran:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token withdraw-withheld-tokens &lt;span class="se"&gt;\&lt;/span&gt;
  &amp;lt;MY_TOKEN_ACCOUNT&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &amp;lt;RECIPIENT_TOKEN_ACCOUNT&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Web2, building a platform fee on transfers requires intercepting every&lt;br&gt;
transaction in your backend. On Solana, it's a flag on the mint. The&lt;br&gt;
program enforces it — not your server.&lt;/p&gt;


&lt;h2&gt;
  
  
  Day 32 — The Full Lifecycle in One Sitting
&lt;/h2&gt;

&lt;p&gt;Day 32 was a consolidation day. No new concepts — just proving I could&lt;br&gt;
build the complete token lifecycle from scratch without checking notes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create Token-2022 mint with metadata + 2% transfer fee&lt;/li&gt;
&lt;li&gt;Initialize metadata (name: ReinforceCoin, symbol: RFC)&lt;/li&gt;
&lt;li&gt;Create token account and mint 1000 RFC&lt;/li&gt;
&lt;li&gt;Transfer 100 to a second wallet → recipient gets 98, 2 withheld&lt;/li&gt;
&lt;li&gt;Withdraw withheld fees → balance becomes 902
Mint: 6YnDTE8cETtvKyesVM9frSeWCfpQUx757qcCQyHaBe9T
Final balance: 902 RFC ✅&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The "aha" moment: I realized the pattern is always the same regardless of&lt;br&gt;
which extensions you use. &lt;strong&gt;Create → configure → mint → transfer →&lt;br&gt;
collect.&lt;/strong&gt; The specifics change. The lifecycle doesn't.&lt;/p&gt;


&lt;h2&gt;
  
  
  Day 33 — Soulbound Tokens
&lt;/h2&gt;

&lt;p&gt;The most conceptually interesting day. I created a &lt;strong&gt;non-transferable&lt;br&gt;
token&lt;/strong&gt; — a token that is permanently locked to the wallet it's minted into.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-non-transferable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I minted 10 tokens, then tried to transfer 5 to a second wallet. The&lt;br&gt;
program rejected it instantly:&lt;br&gt;
Program log: Transfer is disabled for this mint&lt;br&gt;
custom program error: 0x25&lt;br&gt;&lt;br&gt;
That error code &lt;code&gt;0x25&lt;/code&gt; (decimal 37) is &lt;code&gt;NonTransferable&lt;/code&gt; — a first-class&lt;br&gt;
error in the Token Extensions Program. This isn't application logic that&lt;br&gt;
a clever script could bypass. The program itself rejects the instruction.&lt;/p&gt;

&lt;p&gt;What's interesting is that &lt;strong&gt;burning still works&lt;/strong&gt;. The owner can destroy&lt;br&gt;
tokens they hold. They just can't send them. After burning 3, my balance&lt;br&gt;
dropped from 10 to 7 — exactly as expected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-world uses for non-transferable tokens:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Course completion certificates&lt;/li&gt;
&lt;li&gt;KYC / identity verification&lt;/li&gt;
&lt;li&gt;Hackathon participation badges&lt;/li&gt;
&lt;li&gt;Employee credentials&lt;/li&gt;
&lt;li&gt;On-chain reputation scores&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In Web2, preventing credential trading means writing application rules that&lt;br&gt;
can be worked around. On Solana, the restriction is part of the asset itself.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Surprised Me
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The separation of mint and token accounts took longer to internalize than&lt;br&gt;
I expected.&lt;/strong&gt; I kept confusing "the mint address" with "my token account."&lt;br&gt;
They're different accounts with different purposes. The mint is the factory.&lt;br&gt;
The token account is the warehouse.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The error messages are actually readable.&lt;/strong&gt; &lt;code&gt;Transfer is disabled for&lt;br&gt;
this mint&lt;/code&gt; is exactly what it sounds like. Coming from debugging opaque&lt;br&gt;
EVM reverts, this felt refreshingly honest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extensions compose.&lt;/strong&gt; You can combine metadata + transfer fees in a&lt;br&gt;
single mint creation command. Day 32 showed me that Token-2022 isn't a&lt;br&gt;
collection of separate features — it's a composable system.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;I'm on Day 33 of 100. Next up: deeper into Token-2022 extensions&lt;br&gt;
(interest-bearing tokens, confidential transfers), then moving into&lt;br&gt;
Anchor and on-chain programs.&lt;/p&gt;

&lt;p&gt;I'm building toward AI agents that can own wallets and execute Solana&lt;br&gt;
transactions autonomously — and understanding the token layer deeply is&lt;br&gt;
a prerequisite for that.&lt;/p&gt;

&lt;p&gt;If you're following along, my full build log is at:&lt;br&gt;
👉 &lt;a href="https://github.com/gopichandchalla16/100-days-of-solana" rel="noopener noreferrer"&gt;github.com/gopichandchalla16/100-days-of-solana&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Day 34 of #100DaysOfSolana — writing in public, building in public.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>100daysofsolana</category>
      <category>blockchain</category>
      <category>web3</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Week 5 on Solana: Everything I Learned About Tokens (Days 29–31)</title>
      <dc:creator>Gopichand</dc:creator>
      <pubDate>Thu, 21 May 2026 05:07:38 +0000</pubDate>
      <link>https://dev.to/gopichand_dev/week-5-on-solana-everything-i-learned-about-tokens-days-29-31-2bko</link>
      <guid>https://dev.to/gopichand_dev/week-5-on-solana-everything-i-learned-about-tokens-days-29-31-2bko</guid>
      <description>&lt;p&gt;Five weeks into my #100DaysOfSolana challenge and I just crossed into &lt;br&gt;
the most exciting territory yet — Solana's token layer. This week I went &lt;br&gt;
from zero token knowledge to creating, branding, minting, distributing, &lt;br&gt;
and even charging fees on tokens — all on-chain. Here's everything I learned.&lt;/p&gt;
&lt;h2&gt;
  
  
  What "Tokens" Actually Means on Solana
&lt;/h2&gt;

&lt;p&gt;Before this week, I thought tokens were complicated. Smart contracts, &lt;br&gt;
deployment scripts, audits — the whole Web3 horror story.&lt;/p&gt;

&lt;p&gt;Turns out, Solana has a completely different model. The &lt;strong&gt;SPL Token Program&lt;/strong&gt; &lt;br&gt;
is a single shared, audited program already deployed on-chain. Every token &lt;br&gt;
on Solana — from USDC to memecoins to your own project token — is created &lt;br&gt;
using the same program. You never write token logic. You just call it.&lt;/p&gt;

&lt;p&gt;This is the Web2 equivalent of using Stripe instead of building your own &lt;br&gt;
payment processor. The infrastructure is already there.&lt;/p&gt;
&lt;h2&gt;
  
  
  Day 29: My First Token — Raw and Nameless
&lt;/h2&gt;

&lt;p&gt;On Day 29, I ran one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A token appeared on-chain. Supply: 0. Decimals: 9. Mint authority: me.&lt;/p&gt;

&lt;p&gt;Then I minted 100 tokens into a token account:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-account MINT_ADDRESS
spl-token mint MINT_ADDRESS 100
spl-token display MINT_ADDRESS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:                                                                   SPL Token Mint&lt;br&gt;
Address: 2M6t3SbJMz95mZ8nzF8MLq364v2ZQQ235BkxhE93g7hq&lt;br&gt;
Supply: 100000000000&lt;br&gt;
Decimals: 9&lt;br&gt;
Mint authority: AWKYsCGBcfGLSz6QpmXzRn7EJ9fRhiJsjYSLDV3c9L9y&lt;br&gt;
Freeze authority: (not set)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Key insight:&lt;/strong&gt; Supply shows &lt;code&gt;100000000000&lt;/code&gt; for 100 tokens because &lt;br&gt;
decimals = 9, so &lt;code&gt;100 × 10^9&lt;/code&gt;. All on-chain math is integer arithmetic — &lt;br&gt;
no floating point, no rounding errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One problem:&lt;/strong&gt; Explorer showed it as "Unknown Token." No name, no symbol. &lt;br&gt;
That sent me to Day 30.&lt;/p&gt;
&lt;h2&gt;
  
  
  Day 30: Giving My Token an Identity with Token-2022
&lt;/h2&gt;

&lt;p&gt;The fix: switch to &lt;strong&gt;Token Extensions Program (Token-2022)&lt;/strong&gt;. This newer &lt;br&gt;
standard embeds metadata — name, symbol, URI — directly inside the mint &lt;br&gt;
account. No separate Metaplex account needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-metadata&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--decimals&lt;/span&gt; 6

spl-token initialize-metadata MINT_ADDRESS &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"100DaysCoin"&lt;/span&gt; &lt;span class="s2"&gt;"HUNDO"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://raw.githubusercontent.com/solana-developers/opos-asset/main/assets/DeveloperPortal/metadata.json"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My token now had an identity: &lt;strong&gt;100DaysCoin (HUNDO)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Then I minted 1000 HUNDO and transferred 250 to a second wallet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token transfer MINT_ADDRESS 250 SECOND_WALLET &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--fund-recipient&lt;/span&gt; &lt;span class="nt"&gt;--allow-unfunded-recipient&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Final: &lt;strong&gt;750 HUNDO (me) / 250 HUNDO (second wallet)&lt;/strong&gt;. The &lt;br&gt;
&lt;code&gt;--fund-recipient&lt;/code&gt; flag automatically created the recipient's Associated &lt;br&gt;
Token Account (ATA) and covered rent. One flag replaces what would be &lt;br&gt;
multiple API calls in Web2.&lt;/p&gt;
&lt;h2&gt;
  
  
  Day 31: Built-in Transfer Fees — No Middleware Required
&lt;/h2&gt;

&lt;p&gt;This was the most mind-bending day. In Web2, charging a per-transaction &lt;br&gt;
fee means building middleware, hooking into payment flows, writing fee &lt;br&gt;
collection jobs. On Solana, it's one flag at mint creation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--transfer-fee-basis-points&lt;/span&gt; 100 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--transfer-fee-maximum-fee&lt;/span&gt; 5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;100 basis points = 1% fee. The program enforces it on every transfer — &lt;br&gt;
no middleware, no bypass possible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token transfer MINT_ADDRESS 100 SECOND_WALLET &lt;span class="nt"&gt;--expected-fee&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;--expected-fee&lt;/code&gt; flag is a safety check: the transfer fails if the &lt;br&gt;
calculated fee doesn't match what you specify. After the transfer:&lt;br&gt;
My wallet: 900 tokens&lt;br&gt;
Second wallet: 99 tokens ← received 100, 1 withheld as fee&lt;br&gt;&lt;br&gt;
The withheld fee sits locked in the recipient's token account. Only the &lt;br&gt;
&lt;strong&gt;withdraw withheld authority&lt;/strong&gt; (set to my wallet at creation) can collect it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token withdraw-withheld-tokens MY_TOKEN_ACCOUNT SECOND_WALLET_TOKEN_ACCOUNT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Final result: &lt;strong&gt;901 tokens in my wallet&lt;/strong&gt; (900 + 1 fee swept back) ✅&lt;/p&gt;

&lt;h2&gt;
  
  
  The Mental Model That Changed Everything
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Web2 Concept&lt;/th&gt;
&lt;th&gt;Solana Equivalent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rewards program definition&lt;/td&gt;
&lt;td&gt;Mint account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User balance row in DB&lt;/td&gt;
&lt;td&gt;Token Account (ATA)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Display name / branding&lt;/td&gt;
&lt;td&gt;On-chain metadata (Token-2022)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transfer API endpoint&lt;/td&gt;
&lt;td&gt;&lt;code&gt;spl-token transfer&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Payment processor fee&lt;/td&gt;
&lt;td&gt;Transfer fee basis points&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fee collection middleware&lt;/td&gt;
&lt;td&gt;&lt;code&gt;withdraw-withheld-tokens&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Admin-only mint permission&lt;/td&gt;
&lt;td&gt;Mint authority (cryptographic)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  SPL Token vs Token-2022: Quick Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;SPL Token&lt;/th&gt;
&lt;th&gt;Token-2022&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Basic minting &amp;amp; transfers&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;On-chain metadata&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transfer fees&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Interest-bearing tokens&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Confidential transfers&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For any new token in 2026: &lt;strong&gt;Token-2022 is the default.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;Week 6 goes deeper — more Token Extensions, and eventually building &lt;br&gt;
tokens with real utility. The foundation is solid.&lt;/p&gt;

&lt;p&gt;31 days in. 69 to go.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Articles in this series:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
→ &lt;a href="https://dev.to/gopichand_dev/how-i-created-my-first-solana-token-from-scratch-spl-token-basics-explained-2m39"&gt;Day 29: SPL Token Basics&lt;/a&gt;&lt;br&gt;&lt;br&gt;
→ &lt;a href="https://dev.to/gopichand_dev/i-built-a-branded-token-on-solana-in-5-minutes-no-smart-contract-needed-32n"&gt;Day 30: Token-2022 Branded Token&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;🔗 GitHub: &lt;a href="https://github.com/gopichandchalla16/100-days-of-solana" rel="noopener noreferrer"&gt;100-days-of-solana&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Building daily → &lt;a href="https://twitter.com/GopichandAI" rel="noopener noreferrer"&gt;@GopichandAI&lt;/a&gt; | #100DaysOfSolana                                                  &lt;/p&gt;

</description>
      <category>100daysofsolana</category>
      <category>web3</category>
      <category>blockchain</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How I Created My First Solana Token from Scratch (SPL Token Basics Explained)</title>
      <dc:creator>Gopichand</dc:creator>
      <pubDate>Thu, 21 May 2026 04:48:07 +0000</pubDate>
      <link>https://dev.to/gopichand_dev/how-i-created-my-first-solana-token-from-scratch-spl-token-basics-explained-2m39</link>
      <guid>https://dev.to/gopichand_dev/how-i-created-my-first-solana-token-from-scratch-spl-token-basics-explained-2m39</guid>
      <description>&lt;p&gt;On Day 29 of my #100DaysOfSolana challenge, I created my first-ever token &lt;br&gt;
on Solana's devnet. Not by deploying a smart contract. Not by writing a &lt;br&gt;
single line of code. Just a CLI and 5 commands.&lt;/p&gt;

&lt;p&gt;Here's what I learned — and why Solana's token model is fundamentally &lt;br&gt;
different from anything in Web2.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Web2 Mental Model (and Why It Breaks Here)
&lt;/h2&gt;

&lt;p&gt;In Web2, when you build a rewards or credits system, you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a &lt;code&gt;tokens&lt;/code&gt; table in your database&lt;/li&gt;
&lt;li&gt;Write API endpoints to create, read, update balances&lt;/li&gt;
&lt;li&gt;Handle edge cases like double-spending yourself&lt;/li&gt;
&lt;li&gt;Maintain a server to keep it all running&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On Solana, &lt;strong&gt;none of that exists&lt;/strong&gt;. The SPL Token Program is a shared, &lt;br&gt;
audited, on-chain program that any developer can use — no custom backend, &lt;br&gt;
no smart contract needed. You just call it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Two Key Accounts You Need to Understand
&lt;/h2&gt;

&lt;p&gt;Before touching the CLI, understand this mental model:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mint Account&lt;/strong&gt; = the global definition of your token  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stores total supply
&lt;/li&gt;
&lt;li&gt;Stores decimal precision
&lt;/li&gt;
&lt;li&gt;Stores who has authority to mint more
&lt;/li&gt;
&lt;li&gt;One per token type
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Token Account&lt;/strong&gt; = a wallet's individual balance for ONE specific token  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Think of your wallet as a filing cabinet
&lt;/li&gt;
&lt;li&gt;Each token account is a separate folder inside it
&lt;/li&gt;
&lt;li&gt;One folder per token type you hold
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This separation is unusual coming from Web2 — but it's how Solana keeps &lt;br&gt;
its data organized and its runtime blazing fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step-by-Step: Creating My First SPL Token
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;solana config &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;--url&lt;/span&gt; devnet
solana address    &lt;span class="c"&gt;# confirm your wallet&lt;/span&gt;
solana balance    &lt;span class="c"&gt;# confirm you have SOL for fees&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I had &lt;strong&gt;6.13 SOL&lt;/strong&gt; on devnet — more than enough. No airdrop needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Create the token mint
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:                                                                  Creating token 2M6t3SbJMz95mZ8nzF8MLq364v2ZQQ235BkxhE93g7hq&lt;br&gt;
under program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA&lt;/p&gt;

&lt;p&gt;Address: 2M6t3SbJMz95mZ8nzF8MLq364v2ZQQ235BkxhE93g7hq&lt;br&gt;
Decimals: 9&lt;br&gt;&lt;br&gt;
This created a &lt;strong&gt;Mint account&lt;/strong&gt; on-chain. Supply is zero. Decimals default &lt;br&gt;
to 9. My wallet is the mint authority — the only one who can create more.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Create a token account
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-account 2M6t3SbJMz95mZ8nzF8MLq364v2ZQQ235BkxhE93g7hq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:                                                                                 Creating account B4SSsjUA1fcJmjMhmYis3EpLTSBD9GGo1DBEZAwjae7c&lt;br&gt;&lt;br&gt;
You &lt;strong&gt;cannot&lt;/strong&gt; receive tokens directly into your wallet. You need a &lt;br&gt;
dedicated token account for each token type. This is the "folder in the &lt;br&gt;
filing cabinet."&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Mint some supply
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token mint 2M6t3SbJMz95mZ8nzF8MLq364v2ZQQ235BkxhE93g7hq 100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:                                                                               Minting 100 tokens&lt;br&gt;
Token: 2M6t3SbJMz95mZ8nzF8MLq364v2ZQQ235BkxhE93g7hq&lt;br&gt;
Recipient: B4SSsjUA1fcJmjMhmYis3EpLTSBD9GGo1DBEZAwjae7c                  &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Inspect everything
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token supply 2M6t3SbJMz95mZ8nzF8MLq364v2ZQQ235BkxhE93g7hq
&lt;span class="c"&gt;# → 100&lt;/span&gt;

spl-token accounts
&lt;span class="c"&gt;# Token                                         Balance&lt;/span&gt;
&lt;span class="c"&gt;# 2M6t3SbJMz95mZ8nzF8MLq364v2ZQQ235BkxhE93g7hq  100&lt;/span&gt;

spl-token display 2M6t3SbJMz95mZ8nzF8MLq364v2ZQQ235BkxhE93g7hq
&lt;span class="c"&gt;# SPL Token Mint&lt;/span&gt;
&lt;span class="c"&gt;#   Address:          2M6t3SbJMz95mZ8nzF8MLq364v2ZQQ235BkxhE93g7hq&lt;/span&gt;
&lt;span class="c"&gt;#   Program:          TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA&lt;/span&gt;
&lt;span class="c"&gt;#   Supply:           100000000000&lt;/span&gt;
&lt;span class="c"&gt;#   Decimals:         9&lt;/span&gt;
&lt;span class="c"&gt;#   Mint authority:   AWKYsCGBcfGLSz6QpmXzRn7EJ9fRhiJsjYSLDV3c9L9y&lt;/span&gt;
&lt;span class="c"&gt;#   Freeze authority: (not set)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Decimals Trick
&lt;/h2&gt;

&lt;p&gt;Notice the supply shows &lt;code&gt;100000000000&lt;/code&gt; even though I minted &lt;code&gt;100&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That's because decimals = 9, so:&lt;br&gt;
100 tokens × 10^9 = 100,000,000,000 raw units&lt;br&gt;&lt;br&gt;
This is identical to how SOL works with lamports:                                       1 SOL = 1,000,000,000 lamports&lt;br&gt;&lt;br&gt;
All on-chain arithmetic is integer math — no floating point, no rounding &lt;br&gt;
errors. The CLI handles the conversion for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "Mint Authority" Actually Means
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;mint authority&lt;/code&gt; field is your wallet address — meaning &lt;strong&gt;only you&lt;/strong&gt; &lt;br&gt;
can call &lt;code&gt;spl-token mint&lt;/code&gt; to create more supply. &lt;/p&gt;

&lt;p&gt;This is the on-chain equivalent of "only the admin can issue new credits" &lt;br&gt;
in a Web2 system. Except here, it's enforced by cryptography, not by &lt;br&gt;
an &lt;code&gt;if (user.role === 'admin')&lt;/code&gt; check in your backend.&lt;/p&gt;

&lt;p&gt;You can also permanently disable minting (set supply to fixed) by &lt;br&gt;
running &lt;code&gt;spl-token authorize YOUR_MINT mint --disable&lt;/code&gt;. Once done, &lt;br&gt;
it's irreversible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Freeze Authority: What It Is and Why I Left It Unset
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Freeze authority: (not set)&lt;/code&gt; means no one can freeze token accounts &lt;br&gt;
holding this token. If freeze authority were set, the authority could &lt;br&gt;
prevent specific wallets from sending or receiving the token — useful &lt;br&gt;
for compliance in real-world asset tokens, but not needed here.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Big Picture
&lt;/h2&gt;

&lt;p&gt;You just created a digital asset. Not a database row, not an API response &lt;br&gt;
— a real token living on a public blockchain that anyone in the world &lt;br&gt;
can verify right now:&lt;/p&gt;

&lt;p&gt;🔗 &lt;a href="https://explorer.solana.com/address/2M6t3SbJMz95mZ8nzF8MLq364v2ZQQ235BkxhE93g7hq?cluster=devnet" rel="noopener noreferrer"&gt;View on Solana Explorer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tomorrow (Day 30), I upgraded this with &lt;strong&gt;Token-2022&lt;/strong&gt; — giving the token &lt;br&gt;
a real name, symbol, and on-chain metadata. The difference is dramatic.&lt;/p&gt;




&lt;p&gt;🔗 Full code: &lt;a href="https://github.com/gopichandchalla16/100-days-of-solana/tree/main/day-29-spl-token" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Building daily → &lt;a href="https://twitter.com/GopichandAI" rel="noopener noreferrer"&gt;@GopichandAI&lt;/a&gt; | #100DaysOfSolana Day 29/100                                                                                                             &lt;/p&gt;

</description>
      <category>100daysofsolana</category>
      <category>web3</category>
      <category>blockchain</category>
      <category>beginners</category>
    </item>
    <item>
      <title>I Built a Branded Token on Solana in 5 Minutes (No Smart Contract Needed)</title>
      <dc:creator>Gopichand</dc:creator>
      <pubDate>Thu, 21 May 2026 04:40:48 +0000</pubDate>
      <link>https://dev.to/gopichand_dev/i-built-a-branded-token-on-solana-in-5-minutes-no-smart-contract-needed-32n</link>
      <guid>https://dev.to/gopichand_dev/i-built-a-branded-token-on-solana-in-5-minutes-no-smart-contract-needed-32n</guid>
      <description>&lt;p&gt;I spent years thinking "creating a token" meant writing complex smart contract &lt;br&gt;
code, deploying it, hoping nothing breaks. Today on Day 30 of my &lt;/p&gt;

&lt;h1&gt;
  
  
  100DaysOfSolana challenge, I created a fully branded token — with a name,
&lt;/h1&gt;

&lt;p&gt;symbol, and on-chain metadata — in under 5 minutes. No Solidity. No Rust. &lt;br&gt;
Just a CLI.&lt;/p&gt;

&lt;p&gt;Here's exactly what I did and what it means.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with Yesterday's Token
&lt;/h2&gt;

&lt;p&gt;On Day 29, I created my first SPL token on Solana devnet. It worked — but &lt;br&gt;
when I looked it up on Solana Explorer, it showed up as "Unknown Token." Just &lt;br&gt;
a random address with no name, no symbol, no identity.&lt;/p&gt;

&lt;p&gt;That's like launching a rewards program for your app but forgetting to give &lt;br&gt;
it a name. Users would see a random ID and have no idea what it represents.&lt;/p&gt;

&lt;p&gt;Today I fixed that using &lt;strong&gt;Token-2022&lt;/strong&gt; — Solana's next-generation token program.&lt;/p&gt;

&lt;h2&gt;
  
  
  Token-2022 vs the Original SPL Token Program
&lt;/h2&gt;

&lt;p&gt;The original SPL Token Program is solid but basic. To add metadata (name, &lt;br&gt;
symbol, image), you'd traditionally need a separate Metaplex account — an &lt;br&gt;
extra transaction, extra cost, extra complexity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Token Extensions Program (Token-2022)&lt;/strong&gt; changes this. It lets you embed &lt;br&gt;
metadata &lt;em&gt;directly inside the mint account itself&lt;/em&gt;. One account. Everything &lt;br&gt;
in one place. Fewer transactions, lower cost.&lt;/p&gt;

&lt;p&gt;Think of it like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Web2 Concept&lt;/th&gt;
&lt;th&gt;Solana Equivalent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Reward program definition&lt;/td&gt;
&lt;td&gt;Mint account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Display name / branding&lt;/td&gt;
&lt;td&gt;On-chain metadata (name, symbol, URI)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User balance record&lt;/td&gt;
&lt;td&gt;Associated Token Account (ATA)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transfer API&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;spl-token transfer&lt;/code&gt; instruction&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What I Built: 100DaysCoin (HUNDO)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Token name:&lt;/strong&gt; 100DaysCoin
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Symbol:&lt;/strong&gt; HUNDO
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decimals:&lt;/strong&gt; 6
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Program:&lt;/strong&gt; Token Extensions (Token-2022)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mint:&lt;/strong&gt; &lt;code&gt;3zX5oyL9skYKWo2ZoUHgBwLpG9BzLe1ViuXLgH8joqFt&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step-by-Step: How I Did It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Create the mint with metadata enabled
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-token &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--program-id&lt;/span&gt; TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-metadata&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--decimals&lt;/span&gt; 6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;--program-id&lt;/code&gt; flag tells the CLI to use Token-2022 instead of the &lt;br&gt;
original SPL Token Program. The &lt;code&gt;--enable-metadata&lt;/code&gt; flag activates the &lt;br&gt;
metadata extension on the mint.&lt;/p&gt;

&lt;p&gt;Output:                                                                                  Creating token 3zX5oyL9skYKWo2ZoUHgBwLpG9BzLe1ViuXLgH8joqFt&lt;br&gt;
Address: 3zX5oyL9skYKWo2ZoUHgBwLpG9BzLe1ViuXLgH8joqFt&lt;br&gt;
Decimals: 6                                                              &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Initialize on-chain metadata
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token initialize-metadata &lt;span class="se"&gt;\&lt;/span&gt;
  3zX5oyL9skYKWo2ZoUHgBwLpG9BzLe1ViuXLgH8joqFt &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"100DaysCoin"&lt;/span&gt; &lt;span class="s2"&gt;"HUNDO"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://raw.githubusercontent.com/solana-developers/opos-asset/main/assets/DeveloperPortal/metadata.json"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This writes the token's name, symbol, and a URI directly onto the mint &lt;br&gt;
account. The URI points to a JSON file with extended details — description, &lt;br&gt;
image, attributes. This is now verifiable by anyone on-chain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Create a token account and mint supply
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spl-token create-account 3zX5oyL9skYKWo2ZoUHgBwLpG9BzLe1ViuXLgH8joqFt
spl-token mint 3zX5oyL9skYKWo2ZoUHgBwLpG9BzLe1ViuXLgH8joqFt 1000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Balance check:                                                                       1000                                                                                 &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Transfer tokens to a second wallet
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;solana-keygen new &lt;span class="nt"&gt;--outfile&lt;/span&gt; ~/second-wallet.json &lt;span class="nt"&gt;--no-bip39-passphrase&lt;/span&gt;

spl-token transfer 3zX5oyL9skYKWo2ZoUHgBwLpG9BzLe1ViuXLgH8joqFt 250 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="si"&gt;$(&lt;/span&gt;solana-keygen pubkey ~/second-wallet.json&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--fund-recipient&lt;/span&gt; &lt;span class="nt"&gt;--allow-unfunded-recipient&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;--fund-recipient&lt;/code&gt; flag is key — it automatically creates the recipient's &lt;br&gt;
Associated Token Account (ATA) and covers the rent cost from my wallet. In &lt;br&gt;
Web2 terms, it's like your API automatically creating a user's balance row &lt;br&gt;
before their first transaction.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final balances
&lt;/h3&gt;

&lt;p&gt;My wallet: 750 HUNDO ✅&lt;br&gt;
Second wallet: 250 HUNDO ✅                                                            &lt;/p&gt;

&lt;h2&gt;
  
  
  The "Aha" Moment
&lt;/h2&gt;

&lt;p&gt;In Web2, building a token/rewards system means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database schema for the currency definition&lt;/li&gt;
&lt;li&gt;CRUD API endpoints for balance management
&lt;/li&gt;
&lt;li&gt;Custom transfer logic with double-spend protection&lt;/li&gt;
&lt;li&gt;A server running 24/7 to keep it all alive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On Solana with Token-2022:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;create-token&lt;/code&gt; = currency definition&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;create-account&lt;/code&gt; = user balance row&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;transfer&lt;/code&gt; = transfer API&lt;/li&gt;
&lt;li&gt;Zero server. Zero maintenance. Publicly verifiable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And critically — the metadata lives &lt;strong&gt;on-chain&lt;/strong&gt;. Not in your database. Not &lt;br&gt;
on your server. On a public ledger that anyone can read, forever.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;Day 31 onward: deeper into token extensions — transfer fees, &lt;br&gt;
interest-bearing tokens, and eventually building tokens with real utility. &lt;br&gt;
The foundation is set.&lt;/p&gt;




&lt;p&gt;🔗 Full code + notes: &lt;a href="https://github.com/gopichandchalla16/100-days-of-solana/tree/main/day-30-token2022-metadata" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;br&gt;&lt;br&gt;
🔗 Mint on Explorer: &lt;a href="https://explorer.solana.com/address/3zX5oyL9skYKWo2ZoUHgBwLpG9BzLe1ViuXLgH8joqFt?cluster=devnet" rel="noopener noreferrer"&gt;Solana Explorer&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Building daily → &lt;a href="https://twitter.com/GopichandAI" rel="noopener noreferrer"&gt;@GopichandAI&lt;/a&gt; | #100DaysOfSolana Day 30/100                &lt;/p&gt;

</description>
      <category>100daysofsolana</category>
      <category>web3</category>
      <category>blockchain</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Solana's Account Model Explained for Web2 Developers (No Blockchain Experience Needed)</title>
      <dc:creator>Gopichand</dc:creator>
      <pubDate>Mon, 18 May 2026 06:57:15 +0000</pubDate>
      <link>https://dev.to/gopichand_dev/solanas-account-model-explained-for-web2-developers-no-blockchain-experience-needed-4acg</link>
      <guid>https://dev.to/gopichand_dev/solanas-account-model-explained-for-web2-developers-no-blockchain-experience-needed-4acg</guid>
      <description>&lt;p&gt;If you're a Web2 developer looking at Solana for the first time, the account &lt;br&gt;
model will either click immediately or confuse you completely. I was in the &lt;br&gt;
second camp — until I spent 26 days building on Solana daily as part of the &lt;br&gt;
100 Days of Solana challenge.&lt;/p&gt;

&lt;p&gt;Here's the explanation I wish I'd had on Day 1.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Filesystem Analogy
&lt;/h2&gt;

&lt;p&gt;Think of Solana like a filesystem.&lt;/p&gt;

&lt;p&gt;Each account is a &lt;strong&gt;file&lt;/strong&gt;. Every file has metadata (owner, permissions, size) &lt;br&gt;
and contents (data). Programs are &lt;strong&gt;executable files&lt;/strong&gt;. Data accounts are the &lt;br&gt;
&lt;strong&gt;documents&lt;/strong&gt; those programs read and write. The System Program is the &lt;br&gt;
&lt;strong&gt;operating system kernel&lt;/strong&gt; that manages file creation and ownership transfers.&lt;/p&gt;

&lt;p&gt;That's the whole model. Let's go deeper.&lt;/p&gt;
&lt;h2&gt;
  
  
  Everything Is an Account
&lt;/h2&gt;

&lt;p&gt;In Ethereum, there are two types of things: externally owned accounts (wallets) &lt;br&gt;
and contract accounts (smart contracts). They behave differently.&lt;/p&gt;

&lt;p&gt;Solana has one type: &lt;strong&gt;accounts&lt;/strong&gt;. Everything — your wallet, a smart contract, &lt;br&gt;
a token mint, a clock showing the current time — is an account. They all live &lt;br&gt;
in one flat key-value store where the key is a 32-byte address and the value &lt;br&gt;
is the account itself.&lt;/p&gt;

&lt;p&gt;This uniformity is powerful once it clicks.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Five Fields Every Account Has
&lt;/h2&gt;

&lt;p&gt;Every single Solana account — whether it's your wallet or the System Program &lt;br&gt;
itself — has exactly five fields. Here's what they look like when you inspect &lt;br&gt;
your own wallet with the Solana CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;solana account &lt;span class="si"&gt;$(&lt;/span&gt;solana address&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Public Key: AWKYsCGBcfGLSz6QpmXzRn7EJ9fRhiJsjYSLDV3c9L9y&lt;br&gt;
Balance: 6.137925 SOL&lt;br&gt;
Owner: 11111111111111111111111111111111&lt;br&gt;
Executable: false&lt;br&gt;
Rent Epoch: 18446744073709551615&lt;br&gt;&lt;br&gt;
And in JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"lamports"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6137925000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"base64"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"owner"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"11111111111111111111111111111111"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"executable"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rentEpoch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;18446744073709551615&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"space"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break each field down:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. lamports&lt;/strong&gt; — your SOL balance in the smallest unit. 1 SOL = 1,000,000,000 &lt;br&gt;
lamports. My wallet has 6,137,925,000 lamports = 6.137925 SOL. Think of &lt;br&gt;
lamports like wei in Ethereum, or paise in INR — the atomic unit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. data&lt;/strong&gt; — a raw byte array. For a basic wallet, this is empty (0 bytes). &lt;br&gt;
For a token mint, it's 82 bytes of structured data. For a program, it's the &lt;br&gt;
compiled bytecode. This field holds the entire state of the account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. owner&lt;/strong&gt; — the program that controls this account. My wallet is owned by &lt;br&gt;
&lt;code&gt;11111111111111111111111111111111&lt;/code&gt; — the System Program. Only the owner program &lt;br&gt;
can modify the account's data or debit its lamports. Anyone can &lt;em&gt;add&lt;/em&gt; lamports, &lt;br&gt;
but only the owner can &lt;em&gt;remove&lt;/em&gt; them. This one rule is most of Solana's &lt;br&gt;
security model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. executable&lt;/strong&gt; — a boolean. &lt;code&gt;false&lt;/code&gt; for wallets and data accounts. &lt;code&gt;true&lt;/code&gt; &lt;br&gt;
for programs. When you call a program, Solana checks this flag first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. rent_epoch&lt;/strong&gt; — deprecated. Ignore it. It's always set to the maximum u64 &lt;br&gt;
value (18446744073709551615) for all rent-exempt accounts, which is everything &lt;br&gt;
on mainnet today.&lt;/p&gt;
&lt;h2&gt;
  
  
  Programs Don't Store Their Own State
&lt;/h2&gt;

&lt;p&gt;This is the part that surprises every Web2 developer.&lt;/p&gt;

&lt;p&gt;In Web2, a server typically owns its own database. In Solana, &lt;strong&gt;programs are &lt;br&gt;
stateless&lt;/strong&gt;. A program's executable code lives in one account. Any data it &lt;br&gt;
needs to read or write lives in &lt;em&gt;separate&lt;/em&gt; data accounts that are passed in &lt;br&gt;
with each transaction.&lt;/p&gt;

&lt;p&gt;Here's the direct comparison:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Web2&lt;/th&gt;
&lt;th&gt;Solana&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Web server&lt;/td&gt;
&lt;td&gt;Program account (executable=true)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;Data account (executable=false)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database row&lt;/td&gt;
&lt;td&gt;Individual account's &lt;code&gt;data&lt;/code&gt; field&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP request&lt;/td&gt;
&lt;td&gt;Transaction instruction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Request body&lt;/td&gt;
&lt;td&gt;Instruction data + account list&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Why does this matter? Because it means Solana can process transactions in &lt;br&gt;
parallel. If two transactions touch different accounts, they can run at the &lt;br&gt;
same time. That's a big reason Solana achieves 3,000–4,000 TPS on mainnet.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Ownership Rules Are Simple But Powerful
&lt;/h2&gt;

&lt;p&gt;Three rules govern everything:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Only the owner program can modify an account's data&lt;/li&gt;
&lt;li&gt;Only the owner program can debit lamports from an account
&lt;/li&gt;
&lt;li&gt;Anyone can credit (send) lamports to any account&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. No complex permission system. No role-based access control. Just: &lt;br&gt;
you own it, you control it.&lt;/p&gt;

&lt;p&gt;When you send SOL to someone, the System Program (owner of both wallets) &lt;br&gt;
executes the transfer. When a token program moves a token, it's the owner of &lt;br&gt;
the token account doing the write. The ownership chain is always clear.&lt;/p&gt;
&lt;h2&gt;
  
  
  Rent Exemption
&lt;/h2&gt;

&lt;p&gt;Every account must hold a minimum lamport balance proportional to its data &lt;br&gt;
size to stay on-chain permanently. This is called being &lt;strong&gt;rent-exempt&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For a basic wallet (0 bytes of data):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;solana rent 0
&lt;span class="c"&gt;# Rent-exempt minimum: 0.00089088 SOL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a token mint account (82 bytes):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;solana rent 82
&lt;span class="c"&gt;# Rent-exempt minimum: 0.0015 SOL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think of it as a deposit you make to reserve space on the network. You get it &lt;br&gt;
back if you ever close the account. The network needs this mechanism to prevent &lt;br&gt;
people from spamming millions of empty accounts.&lt;/p&gt;
&lt;h2&gt;
  
  
  Seeing It All in Practice
&lt;/h2&gt;

&lt;p&gt;After 26 days of building on Solana, the account model stopped being abstract &lt;br&gt;
and became &lt;em&gt;obvious&lt;/em&gt;. When I inspected the System Program itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;solana account 11111111111111111111111111111111
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Owner: NativeLoader1111111111111111111111111111111&lt;br&gt;
Executable: true&lt;br&gt;
Data: system_program ← literally the program name in bytes&lt;br&gt;&lt;br&gt;
And the Clock sysvar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;solana account SysvarC1ock11111111111111111111111111111111
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
                                                                                        Owner: Sysvar1111111111111111111111111111111111111&lt;br&gt;
Executable: false&lt;br&gt;
Length: 40 bytes ← slot, epoch, unix timestamp packed as binary&lt;br&gt;&lt;br&gt;
The pattern is always the same: &lt;code&gt;executable=true&lt;/code&gt; means it's code, &lt;br&gt;
&lt;code&gt;executable=false&lt;/code&gt; means it's data. The owner tells you who controls it. The &lt;br&gt;
data tells you what it stores.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Mental Model That Clicked For Me
&lt;/h2&gt;

&lt;p&gt;After weeks of building, here's the one-sentence summary:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Solana is a global key-value store. Keys are 32-byte addresses. Values are &lt;br&gt;
accounts with 5 fields. Programs are accounts that transform other accounts &lt;br&gt;
when you call them.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Everything else — tokens, NFTs, DeFi protocols, oracles — is built on top of &lt;br&gt;
this foundation. Once you see it, you can't unsee it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm building in public with the &lt;a href="https://mlh.link/solana-100" rel="noopener noreferrer"&gt;100 Days of Solana&lt;/a&gt; &lt;br&gt;
challenge by MLH. Follow along on &lt;a href="https://github.com/gopichandchalla16/100-days-of-solana" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; &lt;br&gt;
and &lt;a href="https://twitter.com/GopichandAI" rel="noopener noreferrer"&gt;X/Twitter&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Day 27 of 100. #100DaysOfSolana&lt;/em&gt;                                                                        &lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
      <category>beginners</category>
      <category>100daysofsolana</category>
    </item>
    <item>
      <title>Solana Transactions Explained for Backend Developers (With Real Failures)</title>
      <dc:creator>Gopichand</dc:creator>
      <pubDate>Sat, 09 May 2026 11:00:56 +0000</pubDate>
      <link>https://dev.to/gopichand_dev/solana-transactions-explained-for-backend-developers-with-real-failures-2ido</link>
      <guid>https://dev.to/gopichand_dev/solana-transactions-explained-for-backend-developers-with-real-failures-2ido</guid>
      <description>&lt;p&gt;I've been building on Solana for the past few weeks as part of the &lt;/p&gt;

&lt;h1&gt;
  
  
  100DaysOfSolana challenge by MLH. Days 15–19 were all about transactions —
&lt;/h1&gt;

&lt;p&gt;sending them, reading them, tracking them through confirmation stages, and &lt;br&gt;
deliberately breaking them. Here's what I learned, explained for backend &lt;br&gt;
developers who think in HTTP requests and database calls.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Solana Transaction Is Not an API Call
&lt;/h2&gt;

&lt;p&gt;When you hit a REST endpoint, you send a request and get a response. &lt;br&gt;
If it fails, you retry. No cost, no permanent record, no cryptographic proof &lt;br&gt;
it ever happened.&lt;/p&gt;

&lt;p&gt;A Solana transaction is different in every one of those ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It requires a &lt;strong&gt;cryptographic signature&lt;/strong&gt; from the fee payer's private key&lt;/li&gt;
&lt;li&gt;It is &lt;strong&gt;permanently recorded on-chain&lt;/strong&gt; whether it succeeds or fails&lt;/li&gt;
&lt;li&gt;It &lt;strong&gt;expires&lt;/strong&gt; after ~60–90 seconds based on a recent blockhash&lt;/li&gt;
&lt;li&gt;It &lt;strong&gt;costs a fee even if it fails&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last point surprised me the most. Let me show you with real output.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Anatomy of a Transaction
&lt;/h2&gt;

&lt;p&gt;Every Solana transaction has these parts:&lt;br&gt;
Signature 0: 2xQrSQU...&lt;br&gt;
Account 0: srw- AWKYsCGB... (fee payer)&lt;br&gt;
Account 1: -rw- 8nwngJPM...&lt;br&gt;
Account 2: -r-x 11111111... (System Program)&lt;br&gt;
Instruction 0&lt;br&gt;
Program: 11111111... (System Program)&lt;br&gt;
Transfer { lamports: 9999000000000 }&lt;br&gt;
Recent Blockhash: FVSnvFfG...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Signature&lt;/strong&gt; — cryptographic proof the fee payer authorized this tx&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accounts&lt;/strong&gt; — every account the tx will read or write must be declared upfront&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instructions&lt;/strong&gt; — the actual operations (transfer SOL, call a program, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recent Blockhash&lt;/strong&gt; — acts like a timestamp + nonce; tx expires if too old&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The account permission flags (&lt;code&gt;srw-&lt;/code&gt;, &lt;code&gt;-rw-&lt;/code&gt;, &lt;code&gt;-r-x&lt;/code&gt;) tell you exactly what &lt;br&gt;
each account can do: &lt;strong&gt;s&lt;/strong&gt;igner, &lt;strong&gt;r&lt;/strong&gt;eadable, &lt;strong&gt;w&lt;/strong&gt;ritable, e*&lt;em&gt;x&lt;/em&gt;*ecutable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solana's 3 Confirmation Levels
&lt;/h2&gt;

&lt;p&gt;Unlike a database commit that's either done or not, Solana confirmation &lt;br&gt;
happens in stages:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;What it means&lt;/th&gt;
&lt;th&gt;Web2 analogy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Processed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Validator included tx in a block&lt;/td&gt;
&lt;td&gt;POST reached the server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Confirmed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;66%+ validators voted on the block&lt;/td&gt;
&lt;td&gt;200 OK from load-balanced API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Finalized&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;31+ blocks built on top&lt;/td&gt;
&lt;td&gt;DB commit flushed + replicated&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I built a live tracker that shows each stage in real time:&lt;br&gt;
Tracking confirmation stages...&lt;br&gt;
[Processed → Confirmed] ✅ reached in 0.3s&lt;br&gt;
[Confirmed → Finalized] ✅ reached in 0.2s&lt;/p&gt;

&lt;p&gt;Transaction successful! 🎉&lt;br&gt;
Signature: 3hYmkD3m...&lt;br&gt;&lt;br&gt;
On devnet, Processed→Confirmed takes ~400ms. Confirmed→Finalized takes &lt;br&gt;
~6–12 seconds. In production those numbers matter for UX decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Happens When Transactions Fail
&lt;/h2&gt;

&lt;p&gt;This is where things get interesting. I deliberately triggered a failed &lt;br&gt;
transaction by skipping preflight simulation (&lt;code&gt;skipPreflight: true&lt;/code&gt;) and &lt;br&gt;
attempting to send 9,999 SOL when my wallet only had ~6.14 SOL.&lt;/p&gt;

&lt;p&gt;Here's the real on-chain output from &lt;code&gt;solana confirm -v&lt;/code&gt;:&lt;br&gt;
Status: Error processing Instruction 0: custom program error: 0x1&lt;br&gt;
Fee: ◎0.000005&lt;br&gt;
Account 0 balance: ◎6.13593 -&amp;gt; ◎6.135925&lt;br&gt;
Account 1 balance: ◎0&lt;br&gt;
Compute Units Consumed: 150&lt;br&gt;
Log Messages:&lt;br&gt;
Program 11111111111111111111111111111111 invoke&lt;br&gt;
Transfer: insufficient lamports 6135925000, need 9999000000000&lt;br&gt;
Program 11111111111111111111111111111111 failed: custom program error: 0x1&lt;br&gt;&lt;br&gt;
Three things stand out:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The fee was charged anyway.&lt;/strong&gt;&lt;br&gt;
Account 0 balance dropped by 0.000005 SOL — just the fee, not the transfer. &lt;br&gt;
The network did work (verified signature, attempted execution), so it got paid.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The error is structured.&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;custom program error: 0x1&lt;/code&gt; from the System Program always means insufficient &lt;br&gt;
lamports. As you write your own programs, these error codes become your &lt;br&gt;
primary debugging tool — like HTTP status codes but for on-chain logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The Log Messages are your stack trace.&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;Transfer: insufficient lamports 6135925000, need 9999000000000&lt;/code&gt; tells you &lt;br&gt;
exactly what was available vs what was needed. This is how you debug failed &lt;br&gt;
instructions in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Types of Failure: Local vs On-Chain
&lt;/h2&gt;

&lt;p&gt;Not all failures reach the chain:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Failure type&lt;/th&gt;
&lt;th&gt;Where it stops&lt;/th&gt;
&lt;th&gt;Fee charged?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CLI preflight (insufficient funds check)&lt;/td&gt;
&lt;td&gt;Never leaves your machine&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;On-chain failure (skipPreflight)&lt;/td&gt;
&lt;td&gt;Executed by validators&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is why production apps use &lt;code&gt;simulateTransaction&lt;/code&gt; before submitting. &lt;br&gt;
Simulation catches errors locally for free. Every on-chain failure is real &lt;br&gt;
money, even if it's tiny amounts.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Mental Model Shift
&lt;/h2&gt;

&lt;p&gt;The biggest shift from Web2 to Solana transactions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Web2:&lt;/strong&gt; You send a request. The server decides what happens. You get a &lt;br&gt;
response. If something breaks server-side, you don't pay for it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solana:&lt;/strong&gt; You sign and broadcast a state change. Validators execute it &lt;br&gt;
atomically. The result — success or failure — is permanent and public. &lt;br&gt;
You pay regardless.&lt;/p&gt;

&lt;p&gt;The blockhash expiry (~60–90s) also changes how you think about retries. &lt;br&gt;
You can't just retry the same signed transaction forever — the blockhash &lt;br&gt;
goes stale. You need to rebuild and re-sign with a fresh blockhash.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built This Week
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Day 15&lt;/strong&gt; — Inspected transaction anatomy: signatures, accounts, 
instructions, compute units&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Day 16&lt;/strong&gt; — Sent first SOL transfer on devnet (&amp;lt;1s settlement)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Day 17&lt;/strong&gt; — Built a reusable Node.js CLI transfer tool with balance 
checks and Explorer links&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Day 18&lt;/strong&gt; — Added live confirmation tracking (Processed→Confirmed→Finalized)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Day 19&lt;/strong&gt; — Deliberately broke transactions, read on-chain errors with 
&lt;code&gt;solana confirm -v&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All code is on my GitHub: &lt;br&gt;
&lt;a href="https://github.com/gopichandchalla16/100-days-of-solana" rel="noopener noreferrer"&gt;github.com/gopichandchalla16/100-days-of-solana&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;If you're coming from a Web2 background and starting with Solana, the &lt;br&gt;
transaction model will feel strange at first. The fee-on-failure behavior, &lt;br&gt;
the blockhash expiry, and the upfront account declaration all exist for &lt;br&gt;
good reasons — they're what makes Solana fast, parallel, and predictable. &lt;br&gt;
Once it clicks, it's actually elegant.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Day 20 of #100DaysOfSolana — building in public every day 🚀&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Follow my progress: &lt;a href="https://twitter.com/GopichandAI" rel="noopener noreferrer"&gt;@GopichandAI&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>100daysofsolana</category>
      <category>blockchain</category>
      <category>web3</category>
      <category>learning</category>
    </item>
    <item>
      <title>Week 2 on Solana: When the "Public Database" Finally Clicked</title>
      <dc:creator>Gopichand</dc:creator>
      <pubDate>Mon, 04 May 2026 07:55:21 +0000</pubDate>
      <link>https://dev.to/gopichand_dev/week-2-on-solana-when-the-public-database-finally-clicked-273a</link>
      <guid>https://dev.to/gopichand_dev/week-2-on-solana-when-the-public-database-finally-clicked-273a</guid>
      <description>&lt;p&gt;I'm doing the 100 Days of Solana challenge by MLH, and Week 2 just changed how I think about blockchain data entirely.&lt;/p&gt;

&lt;p&gt;Week 1 was about identity — generating keypairs, understanding wallets, getting devnet SOL. That part felt familiar, like setting up a dev environment.&lt;/p&gt;

&lt;p&gt;Week 2 was different. Week 2 was about &lt;em&gt;reading the chain&lt;/em&gt; — and that's where the mental model shift actually happened.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I expected vs what I got
&lt;/h2&gt;

&lt;p&gt;I expected reading blockchain data to feel like calling a mysterious, slow, complex API. Something with heavy setup, authentication tokens, and confusing docs.&lt;/p&gt;

&lt;p&gt;What I got was this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;lamports&lt;/span&gt; &lt;span class="p"&gt;}&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;rpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBalance&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="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lamports&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;_000_000_000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No API key. No login. No permissions. Anyone can call this for any address, anytime.&lt;/p&gt;

&lt;p&gt;In Web2, if I want someone's account balance, I need DB credentials, role permissions, and middleware. On Solana, I just ask. Publicly. That's not a flaw — that's the design.&lt;/p&gt;

&lt;h2&gt;
  
  
  The moment it clicked
&lt;/h2&gt;

&lt;p&gt;Day 11 was a conceptual challenge: compare Solana accounts to Web2 databases. I ran:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;solana account &lt;span class="si"&gt;$(&lt;/span&gt;solana address&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
Public Key: AWKYsCGBcfGLSz6QpmXzRn7EJ9fRhiJsjYSLDV3c9L9y&lt;br&gt;
Balance: 2.5 SOL&lt;br&gt;
Owner: 11111111111111111111111111111111&lt;br&gt;
Executable: false&lt;br&gt;&lt;br&gt;
Then I ran:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;solana account TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
Owner: BPFLoaderUpgradeab1e11111111111111111111111&lt;br&gt;
Executable: true&lt;br&gt;
Length: 36 bytes&lt;br&gt;&lt;br&gt;
Same command. Same account model. One is a wallet holding SOL. The other is the Token Program — compiled code that manages every SPL token on Solana. Both are just "accounts."&lt;/p&gt;

&lt;p&gt;That's when "everything is an account" stopped being a slogan and started being a mental model.&lt;/p&gt;
&lt;h2&gt;
  
  
  The devnet vs mainnet surprise
&lt;/h2&gt;

&lt;p&gt;Day 12 was the most satisfying. One script. Two RPC connections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;devnetRpc&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSolanaRpc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;devnet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.devnet.solana.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mainnetRpc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSolanaRpc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;mainnet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.mainnet-beta.solana.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same address. Same &lt;code&gt;getBalance&lt;/code&gt; call. Completely different output:&lt;br&gt;
DEVNET → 0.001159846 SOL | Slot: 459,981,397&lt;br&gt;
MAINNET → 0.069875097 SOL | Slot: 417,486,413&lt;br&gt;&lt;br&gt;
Different balances. Different slots. Completely different transaction histories. I already knew they were separate — but &lt;em&gt;seeing&lt;/em&gt; it side by side in the terminal made it real in a way docs never did.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's still confusing
&lt;/h2&gt;

&lt;p&gt;PDAs — Program Derived Addresses. I understand they're derived from a program + seed with no private key, so only the program can sign for them. But I haven't &lt;em&gt;used&lt;/em&gt; one yet. I can describe them but I can't feel them. That's my Week 3 target.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd tell Week-1-me
&lt;/h2&gt;

&lt;p&gt;Stop thinking in tables and rows. Start thinking in accounts and owners. Every piece of state on Solana is an account. Every account has an owner program. Only that program can modify it. That's not a restriction — that's what makes the system trustless.&lt;/p&gt;

&lt;p&gt;Also: devnet is your playground. Break things there first.&lt;/p&gt;




&lt;p&gt;If you're also doing #100DaysOfSolana, drop your DEV.to link below — I want to read what clicked for you.&lt;/p&gt;

&lt;p&gt;→ My code: &lt;a href="https://github.com/gopichandchalla16/100-days-of-solana" rel="noopener noreferrer"&gt;https://github.com/gopichandchalla16/100-days-of-solana&lt;/a&gt;&lt;/p&gt;

</description>
      <category>100daysofsolana</category>
      <category>solana</category>
      <category>web3</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Your Public Key IS Your Identity: What Web2 Devs Need to Know About Solana</title>
      <dc:creator>Gopichand</dc:creator>
      <pubDate>Tue, 28 Apr 2026 16:55:00 +0000</pubDate>
      <link>https://dev.to/gopichand_dev/your-public-key-is-your-identity-what-web2-devs-need-to-know-about-solana-4lpm</link>
      <guid>https://dev.to/gopichand_dev/your-public-key-is-your-identity-what-web2-devs-need-to-know-about-solana-4lpm</guid>
      <description>&lt;p&gt;If you've been a Web2 developer for any amount of time, you know what identity &lt;br&gt;
looks like: a username in a database, an email address, a session cookie, &lt;br&gt;
maybe an OAuth token from Google. Your "identity" is really just a record that &lt;br&gt;
some company controls. They can delete it. They can lock you out. They can sell &lt;br&gt;
the data. You don't own it — you just borrow it.&lt;/p&gt;

&lt;p&gt;Solana works completely differently. And once you understand how, you can't &lt;br&gt;
unsee it.&lt;/p&gt;
&lt;h2&gt;
  
  
  It Starts with a Keypair
&lt;/h2&gt;

&lt;p&gt;When I started the 100 Days of Solana challenge, the first thing I did was run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;solana-keygen new &lt;span class="nt"&gt;--no-bip39-passphrase&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; wallet.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This generated two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;public key&lt;/strong&gt; — a 32-byte Ed25519 address like &lt;code&gt;AWKYsCGBcfGLSz6QpmXzRn7EJ9fRhiJsjYSLDV3c9L9y&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;private key&lt;/strong&gt; — stored in &lt;code&gt;wallet.json&lt;/code&gt;, never shared&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it. That keypair IS my identity on Solana. No signup form. No email &lt;br&gt;
verification. No "username already taken."&lt;/p&gt;
&lt;h2&gt;
  
  
  The SSH Key Analogy
&lt;/h2&gt;

&lt;p&gt;If you've ever set up a server on AWS or DigitalOcean, you already understand &lt;br&gt;
this model. You generate an SSH keypair, paste the public key into the server's &lt;br&gt;
&lt;code&gt;authorized_keys&lt;/code&gt; file, and prove your identity by holding the private key.&lt;/p&gt;

&lt;p&gt;Solana works identically — except instead of one server, it's the entire &lt;br&gt;
global network. Every node on Solana knows your public key. You prove ownership &lt;br&gt;
by signing transactions with your private key.&lt;/p&gt;

&lt;p&gt;The difference from Web2 is critical: &lt;strong&gt;no company stores your credentials&lt;/strong&gt;. &lt;br&gt;
There is no database row. There is no admin who can reset your password or &lt;br&gt;
lock your account.&lt;/p&gt;
&lt;h2&gt;
  
  
  What a Solana Address Actually Is
&lt;/h2&gt;

&lt;p&gt;A Solana address is a Base58-encoded 32-byte Ed25519 public key. Base58 was &lt;br&gt;
chosen deliberately — it removes visually confusing characters like &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;O&lt;/code&gt;, &lt;br&gt;
&lt;code&gt;I&lt;/code&gt;, and &lt;code&gt;l&lt;/code&gt; to prevent copy-paste mistakes.&lt;/p&gt;

&lt;p&gt;In Web2, your username lives in someone's Postgres table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'gopichand'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Solana, your identity is derived from math. It exists everywhere and nowhere &lt;br&gt;
simultaneously — it only becomes real when you sign something with the private key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cryptographic Ownership vs Company-Granted Access
&lt;/h2&gt;

&lt;p&gt;Here's the most important mental shift:&lt;/p&gt;

&lt;p&gt;In Web2, you "own" your account because a company says you do. Twitter can &lt;br&gt;
ban you. Your bank can freeze your account. Google can lock your Gmail. You &lt;br&gt;
have access because they allow it.&lt;/p&gt;

&lt;p&gt;On Solana, ownership is cryptographic. If you hold the private key, you control &lt;br&gt;
the account — period. No appeal process, no customer support ticket, no &lt;br&gt;
waiting for a human to review your case.&lt;/p&gt;

&lt;p&gt;This is both powerful and terrifying. Lose your private key? Your funds are gone &lt;br&gt;
forever. No recovery email. That's why seed phrases and hardware wallets exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Identity Enables Everything Else
&lt;/h2&gt;

&lt;p&gt;Once I had a keypair, I could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Receive devnet SOL&lt;/strong&gt; — just by sharing my public key&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connect a browser wallet&lt;/strong&gt; — Phantom connected on Day 4 without me ever 
sharing my private key&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sign transactions&lt;/strong&gt; — prove I authorized a transfer without revealing 
my secret&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Own tokens and NFTs&lt;/strong&gt; — because ownership is just a signed record on-chain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This one keypair is the foundation for token ownership, dApp interactions, &lt;br&gt;
governance votes, and on-chain reputation — across every application on the &lt;br&gt;
network, without asking anyone's permission.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which Wallet Type Should You Use?
&lt;/h2&gt;

&lt;p&gt;During Day 5 of the challenge, I compared three wallet types:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Wallet&lt;/th&gt;
&lt;th&gt;Key Storage&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CLI (&lt;code&gt;id.json&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Plaintext file&lt;/td&gt;
&lt;td&gt;Devnet scripting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Browser (Phantom)&lt;/td&gt;
&lt;td&gt;Encrypted + password&lt;/td&gt;
&lt;td&gt;dApp interactions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mobile (Phantom)&lt;/td&gt;
&lt;td&gt;Hardware-backed + biometrics&lt;/td&gt;
&lt;td&gt;Personal daily use&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hardware (Ledger)&lt;/td&gt;
&lt;td&gt;Never leaves device&lt;/td&gt;
&lt;td&gt;Long-term storage&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The underlying keypair concept is identical across all of them. What differs &lt;br&gt;
is where the private key lives and how it's protected.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Big Takeaway
&lt;/h2&gt;

&lt;p&gt;In Web2, identity is a database record owned by someone else.&lt;br&gt;
In Web3, identity is a mathematical keypair owned by you.&lt;/p&gt;

&lt;p&gt;Your public key is your username, your account number, and your proof of &lt;br&gt;
existence on the network — all at once. The private key is the only password &lt;br&gt;
that matters, and only you should ever hold it.&lt;/p&gt;

&lt;p&gt;I'm documenting every step of this journey publicly as part of the &lt;br&gt;
&lt;a href="https://www.mlh.com/events/100-days-of-solana/challenges" rel="noopener noreferrer"&gt;100 Days of Solana&lt;/a&gt; &lt;br&gt;
challenge by MLH.&lt;/p&gt;

&lt;p&gt;All my code is on GitHub: &lt;a href="https://github.com/gopichandchalla16/100-days-of-solana" rel="noopener noreferrer"&gt;github.com/gopichandchalla16/100-days-of-solana&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow along if you're on the same journey! 🚀&lt;/p&gt;

&lt;h1&gt;
  
  
  100daysofsolana #solana #web3 #blockchain #beginners
&lt;/h1&gt;

</description>
      <category>100daysofsolana</category>
      <category>solana</category>
      <category>web3</category>
      <category>blockchain</category>
    </item>
  </channel>
</rss>
