DEV Community

Mubarak Yakubu
Mubarak Yakubu

Posted on

From Token Watcher to Program Builder: 100 Days of Solana

I came into this program as a Web2 developer who moderates Web3 communities.

I knew Solana as "the blockchain people build products and solutions on, and launch tokens on." That's it. I'd watched projects build on it, seen the ecosystem from the outside as a community moderator and ambassador. But I'd never written a line of Solana code.

Ninety-nine days later, I have a program deployed to devnet with an agent that reads its state and a Token-2022 badge minted to my wallet.

Here's what actually changed.

What I expected

I expected blockchain development to feel like backend development with a crypto coating on top. Servers become programs. Databases become accounts. Same shape, different words.

That was wrong in a specific way.

There is no server. There's no database you can quietly edit. Everything is a transaction, and every transaction is permanent.

When I started, I assumed the authority owner could just change things after the fact. Redeploy, fix a bug, update a record. And in one sense, that's true. Programs are upgradeable by default. The upgrade authority can push new code to the same program ID.

But here's what I got wrong: you can change the code, but you can't change what the code already did.

If a wallet called your program yesterday and wrote a record, that record is on-chain. You can write a new transaction that changes its current state, but the history stays. You can't reach back and pretend it didn't happen.

That's the shift Web2 doesn't prepare you for. There's no UPDATE that erases the old value. There's no rollback. The code you deploy is the code that runs, and what it wrote is written.

The moment it clicked

The vault program.

I built a program that holds SOL, lets you deposit, lets you withdraw, and enforces that only the authority can withdraw. Small. Basic.

But when it worked, I saw something bigger. The pieces I'd been learning one at a time (accounts, PDAs, constraints, error codes, tests) stopped being separate exercises. They became a system.

I've worked in Web2 long enough to recognize that feeling. It's the moment you stop seeing a framework and start seeing the shape of something you can build. The vault was small, but it was the first time I could picture building real products this way.

What I understand now

The toolchain is what makes Solana manageable.

That's a distinction I didn't have words for until recently. The protocol is what Solana is: accounts, transactions, programs, the runtime. You could write a Solana program in raw Rust with no framework at all. It would just be painful.

The toolchain is what makes the protocol usable.

Anchor gives you structure. The #[program] macro, #[derive(Accounts)], the require! macro. Everything has a place. Without it, you're writing instruction dispatch and account validation by hand.

PDAs are a protocol feature, but knowing when and how to use them is toolchain-level knowledge. Anchor gives you a clean way to declare them: seeds = [...]. Once I understood that a PDA isn't a wallet, that it's a deterministic address only your program can sign for, half of Solana's design made sense.

The capstone's seeds are [b"ship", builder.key()]. That's it. The address itself enforces "one record per wallet." No runtime check, no guard clause. The seed is the constraint.

IDLs are the bridge between the on-chain program and everything else. The protocol doesn't know or care about IDLs. But without them, every client that wants to call your program has to hand-encode instruction bytes. With them, you get autocomplete, typed clients, and agents that know what to call.

You can learn the protocol and still not be able to build anything real. The toolchain is the difference.

What I built for the capstone

proof-of-ship. One instruction: ship(project_name, message). Any wallet can call it once to permanently record on-chain that it shipped a capstone.

Program: 6xKXthNFn8YdaPVqdrAJWDfaAxeNeBX5MZuUSaVxd7mL
Explorer: https://explorer.solana.com/address/6xKXthNFn8YdaPVqdrAJWDfaAxeNeBX5MZuUSaVxd7mL?cluster=devnet
Repo: github.com/Mubaraqq/mlh_100daysofsolana/tree/main/day-99

The capstone pulls from everything:

  • An Anchor program with a PDA whose seeds encode the rule
  • Custom errors and a runtime constraint
  • Happy-path and failure-path tests
  • A TypeScript script that calls ship on devnet
  • A read-only agent tool that fetches any wallet's ShipRecord
  • A 1-of-1 Token-2022 badge with metadata embedded in the mint

Small. Complete. Deployed.

What I'd tell another developer

Three things.

The toolchain is not the same as the protocol. You can learn Solana primitives and still not know how to build on Solana. Anchor, PDAs, and IDLs are what make the primitives usable. Don't skip them.

Account design is the hard part. Anyone can write an instruction. The interesting decisions are in the accounts: what state you store, how you derive the PDAs, what the seeds encode. A good PDA design can replace a dozen runtime checks.

Web2 instincts help, then they get in the way. The instinct to check state before writing is fine. The instinct to assume you can fix a mistake after it's made is not. On Solana, the code and the state are the contract.

What comes next

I want to build systems, not demos.

The vault program showed me I could. The capstone showed me the pieces fit together. The agent work showed me there's a whole layer of tooling being built right now that most developers haven't touched yet.

Concretely:

  • Go deeper on agent tooling, since the harness layer is where the interesting engineering is right now
  • Contribute to open source, starting with the tools I used
  • Help other developers starting behind me, since I moderated communities before I wrote code and I still want to be useful there

One hundred days ago, Solana was unfamiliar territory. Today I have a program live on devnet that anyone can look up, call, and verify.

More importantly, I can explain why it works.


This is Day 100 of #100DaysOfSolana.


Top comments (0)