My decentralized blog

Solana Study

Solana Study#

2. Reading Data from the Solana Network#

(1) Summary#

SOL is the name of the native token of Solana. Each SOL consists of 1 billion Lamports.

Accounts store tokens, NFTs, programs, and data.

Addresses point to accounts on the Solana network. Anyone can read data from a given address. Most addresses are also public keys.

(2) Accounts#

All data stored on Solana is stored in accounts. Accounts can store:

  • SOL
  • Other tokens, such as USDC
  • NFTs
  • Programs
  • Program data

(3) Introduction to SOL#

SOL is the native token of Solana - SOL is used for paying transaction fees, rent for accounts, etc. SOL is sometimes displayed with the symbol ◎. Each SOL consists of 1 billion Lamports.

Similar to how financial applications typically perform mathematical calculations in cents (dollars) and pence (pounds), Solana applications typically transact, spend, store, and process SOL as Lamports, only converting to whole SOL for display to users.

(4) Addresses#

Addresses uniquely identify accounts. Addresses are typically displayed as base-58 encoded strings, such as dDCQNnDmNbFVi8cQhKAgXhyhXeJ625tvwsunRyRc7c8. Most addresses on Solana are also public keys. Whoever controls the matching key for an address controls the account - for example, someone with the key can send tokens from that account.

(5) Code#

import { PublicKey,LAMPORTS_PER_SOL,Keypair,Connection, clusterApiUrl } from "@solana/web3.js";
console.log("Generating key pair");
const keypair = Keypair.generate();
console.log(`The public key is: `, keypair.publicKey.toBase58());
console.log(`The secret key is: `, keypair.secretKey);
console.log("Creating connection");
const connection = new Connection(clusterApiUrl("devnet"));
// console.log(connection)
console.log(`✅ Connected!`)
console.log("Getting account balance");
const address = new PublicKey('4pa3H5FwfPPSYH8JGKiKb91mgjx6iVbt4X3XJAdV7s5g');
const balance = await connection.getBalance(address);
const balanceInSol = balance / LAMPORTS_PER_SOL;
console.log(`The balance of the account at ${address} is ${balanceInSol} SOL`); 
console.log(`✅ Finished!`)

3. Creating Transactions on the Solana Network#

(1) Summary#

All modifications to on-chain data occur through transactions. Transactions are primarily a set of instructions that call Solana programs. Transactions are atomic, meaning they either succeed (if all instructions are executed correctly) or fail, as if the transaction never ran at all.

(2) Transactions are atomic#

Any modification to on-chain data occurs through transactions sent to programs.

Transactions on Solana are similar to transactions elsewhere: they are atomic. Atomicity means that the entire transaction either runs or fails.

Think of something like an online payment:

  • Your account balance is deducted
  • The bank transfers funds to the merchant

Both of these things need to happen for the transaction to be successful. If either one fails, neither happens, instead of paying the merchant without deducting from your account, or deducting from the account without paying the merchant.

Atomic means the transaction either happens (meaning all individual steps succeeded) or the entire transaction fails.

(3) Transactions contain instructions#

The steps in a transaction on Solana are called instructions.

Each instruction contains:

  • An array of accounts to read from and/or write to. This is what makes Solana fast - transactions affecting different accounts are processed simultaneously.
  • The public key of the program to call.
  • Data passed to the program being called, structured as a byte array.

When running a transaction, one or more Solana programs are called with the instructions included in the transaction.

(4) Code#

import { Transaction,SystemProgram,sendAndConfirmTransaction,Connection,LAMPORTS_PER_SOL,clusterApiUrl,Keypair, PublicKey } from "@solana/web3.js"
const connection = new Connection(clusterApiUrl("devnet"), "confirmed")
// Generate a new keypair
const senderKeypair = Keypair.generate()
// Airdrop
await connection.requestAirdrop(senderKeypair.publicKey, LAMPORTS_PER_SOL)//1SOL=1000000000LAMPORTS
// Receiver
const receiverPubkey = new PublicKey("4pa3H5FwfPPSYH8JGKiKb91mgjx6iVbt4X3XJAdV7s5g")
// Get receiver's balance
const receiverBalance = await connection.getBalance(receiverPubkey)
// Get sender's balance
const senderBalance = await connection.getBalance(senderKeypair.publicKey)
console.log("sender balance:", senderBalance)
console.log("receiver balance:", receiverBalance)
const transaction = new Transaction()
const sendSolInstruction = SystemProgram.transfer({
  fromPubkey: senderKeypair.publicKey,// Public key corresponding to the sender's account
  toPubkey: receiverPubkey,// Public key corresponding to the receiver's account
  lamports: LAMPORTS_PER_SOL/2// Amount of SOL to send in Lamports


const signature =await sendAndConfirmTransaction(
    connection,// Cluster connection
    transaction,// A transaction
    [senderKeypair]// An array of keypairs that will act as signers of the transaction - in this case, we only have one signer: the sender.
// Get receiver's balance
const receiverBalance01 =await connection.getBalance(receiverPubkey)
// Get sender's balance
const senderBalance01 =await connection.getBalance(senderKeypair.publicKey)
console.log("sendered balance:", senderBalance01)
console.log("receivered balance:", receiverBalance01)
console.log("signature:", signature)

4. Creating Tokens with Token Programs#

(1) Summary#

SOL is the "native token" of Solana. All other tokens, fungible tokens, and non-fungible tokens (NFTs) are referred to as SPL tokens.

Token programs contain instructions for creating and interacting with SPL tokens.

Token mints are accounts that define specific tokens. This includes information about the token itself (such as how many decimal places it has), accounts that are allowed to mint more tokens (called mint authorities), and where to find more information about the token (such as description, image, etc.). Mint authorities can use token mints to create more tokens!

Token accounts hold the tokens from a specific token mint. For most users, the balance of each token mint is stored in an associated token account - an account composed of their wallet address and the token mint.

(2) Token Minting Steps#

  1. Creating a new Token Mint
  2. Creating Token Accounts
  3. Minting
  4. Transferring tokens from one holder to another
  5. Burning tokens

(3) Token Account#

Before tokens can be minted (new supply issued), a token account is needed to hold the newly minted tokens.

Token accounts hold tokens from a specific "mint" and have a specified account "owner". Only the owner has the authority to decrease the balance of the token account (transfer, burn, etc.), while anyone can send tokens to the token account to increase its balance.

In the Solana code you provided, this newly created account is used to hold the state and metadata of the token being minted, and you as the payer paid the fee required to create this account, and you also have the minting authority for this token.

5. Creating Solana NFTs with Metaplex#

(1) Summary#

Non-fungible tokens (NFTs) on Solana are represented as SPL tokens with associated metadata accounts, 0 decimal places, and a maximum supply of 1.

Metaplex provides a suite of tools to simplify the creation and distribution of NFTs on the Solana blockchain.

The Token Metadata program standardizes the process of attaching metadata to SPL tokens.

The Metaplex SDK is a tool that provides a user-friendly API to help developers utilize the on-chain tools provided by Metaplex.

The Candy Machine program is an NFT distribution tool used to create and mint NFTs from a collection.

The Sugar CLI is a tool that simplifies the process of uploading media/metadata files and creating a candy machine for a collection.

(2) NFTs on Solana#

6. Custom On-Chain Programs#

7. On-Chain Program Development#

(1) Anchor Program Structure#

Anchor generates boilerplate Rust code for you using macros and attributes. They provide a clear structure for your program to make reasoning about your code easier. The main high-level macros and attributes are:

  • declare_id - a macro used to declare the on-chain address of the program
  • #[program] - an attribute macro used to denote the module containing the program instruction logic
  • accounts - a trait applied to structures representing the list of accounts required by an instruction
  • #[account] - an attribute macro used to define custom account types for the program
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.