DEV Community

Cover image for 100 Days of Solana: Week 2 - Diving into On-chain Data and Transactions
Akanni Modupe Adegoke
Akanni Modupe Adegoke

Posted on

100 Days of Solana: Week 2 - Diving into On-chain Data and Transactions

Continuing my 100 Days of Solana journey in collaboration with MLH, the second week has been an eye-opener. While Week 1 was about setting up the foundation, Week 2 pushed me into the world of fetching, displaying, and analyzing on-chain data.

In this post, I’ll walk through how I fetched account balances, handled transaction history, and realized the striking similarities between blockchain environments and traditional Web2 staging/production workflows.


The Transparency of the Ledger

One of my first realizations this week is that the blockchain is essentially an open collection of nodes storing data publicly. Because this data is immutable and transparent, it is critical to avoid storing sensitive information on-chain. Once data is written, rolling it back is nearly impossible—similar to committing a transaction to a database without a backup.

1. Fetching Account Balances

Using the @solana/kit package, I learned how to query the balance of any account on the Devnet.

Here is the code I used to read the balance of a wallet:

import { createSolanaRpc, devnet, address } from "@solana/kit";

// Connect to devnet (Solana's test network)
const rpc = createSolanaRpc(devnet("https://api.devnet.solana.com"));

// The target wallet address
const targetAddress = address(
    "9ZfTayFVzWg5ZTsax3KbqbXrhMdhdMYJ9inuC4smxc9F"
);

// Query the balance (similar to a REST API call)
const { value: balanceInLamports } = await rpc
    .getBalance(targetAddress)
    .send();

// 1 SOL = 1,000,000,000 lamports.
const balanceInSol = Number(balanceInLamports) / 1_000_000_000;

console.log(`Address: ${targetAddress}`);
console.log(`Balance: ${balanceInSol} SOL`);
Enter fullscreen mode Exit fullscreen mode

Key Learnings:

  • RPC (Remote Procedure Call): This is the communication protocol that allows us to request services from a Solana node without needing to manage the network details ourselves.
  • Lamports: These are the smallest units of Solana. Much like Satoshis for Bitcoin, understanding the conversion is vital for accurate UI displays.

2. Deep Dive into Transactions

Next, I explored fetching transaction histories. Every transaction on Solana contains a Signature (which acts as a Transaction ID), a Slot, a Timestamp, and a Status.

I found the concept of Slots particularly interesting. In Solana, transactions are processed in batches assigned to a slot number. Think of it like an auto-incrementing ID in a database; higher slot numbers indicate more recent activity. Since Solana produces slots roughly every 400ms, the network moves incredibly fast!

import { createSolanaRpc, devnet, address } from "@solana/kit";

const rpc = createSolanaRpc(devnet("https://api.devnet.solana.com"));

// Example: Fetching activity for a Program/Token address
const targetAddress = address(
    "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"
);

// Fetch the 5 most recent transaction signatures
const signatures = await rpc
    .getSignaturesForAddress(targetAddress, { limit: 5 })
    .send();

console.log(`\nLast 5 transactions for ${targetAddress}:\n`);

for (const tx of signatures) {
    const time = tx.blockTime
        ? new Date(Number(tx.blockTime) * 1000).toLocaleString()
        : "unknown";

    console.log(`Signature : ${tx.signature}`);
    console.log(`Slot      : ${tx.slot}`);
    console.log(`Time      : ${time}`);
    console.log(`Status    : ${tx.err ? "Failed" : "Success"}`);
    console.log("---");
}
Enter fullscreen mode Exit fullscreen mode

To make this data useful, I built a simple UI Dashboard where a user can input a wallet address to see their balance and recent transaction history in real-time.


3. Blockchain vs. Traditional Databases

One of the most helpful exercises this week was comparing Solana Accounts to Traditional Databases. While they share concepts like "state," the way they handle permissions and data persistence is unique.

Check out my full comparison table here: Comparison Table


4. Devnet vs. Mainnet: Staging vs. Production

Finally, I was introduced to Mainnet-beta data. I realized that working with Solana is very similar to the Web2 lifecycle:

  • Devnet = Staging/Development Environment.
  • Mainnet = Production Environment.

The code remains almost identical; the only change is the RPC endpoint URL.

import { createSolanaRpc, devnet, mainnet, address } from "@solana/kit";

// Two separate RPC connections
const devnetRpc = createSolanaRpc(devnet("https://api.devnet.solana.com"));
const mainnetRpc = createSolanaRpc(mainnet("https://api.mainnet-beta.solana.com"));

// ... fetch logic remains the same regardless of the network!
Enter fullscreen mode Exit fullscreen mode

Seeing the same address return different balances and transaction histories across the two networks really solidified my understanding of how environments work in Web3.


Wrapping Up Week 2

This week helped me bridge the gap between "theory" and "real-world" on-chain data. I now have a much clearer understanding of the transaction object, the speed of Solana slots, and how to build dashboards that read live data.

I’m excited to see what Week 3 brings!

Join the Journey:
If you want to follow along or start your own challenge, check out the MLH 100 Days of Solana page.

Top comments (0)