A Guide to Counter DApp Development on Solana Blockchain

Posted By : Siddharth

Oct 31, 2023

This blog gives a comprehensive guide to smart contract development using Anchor for counter dApp development on the Solana blockchain.

 

About Solana 

 

Solana is a high-performance blockchain known for its remarkable speed and scalability. It uses proof-of-history (PoH) and proof-of-stake (PoS) to process thousands of transactions per second, offering low fees. Solana's native cryptocurrency is SOL. 

 

It has a growing ecosystem that enables dApps (decentralized applications) to thrive. The network focuses on decentralization and interoperability. While it has faced some challenges, Solana remains a promising platform for blockchain innovation.

 

Check It Out: What Makes Solana Blockchain Development Stand Out

 

Writing Smart Contracts on Solana using Anchor 

 

Set Up Environment 

 

Install Rust, Solana CLI, and Anchor CLI for development, for more details refer to https://www.anchor-lang.com/docs/installation.

 

Initialize Project 

 

Use Anchor CLI to create a project with smart contract templates.

 

Define Contract 

 

Write your smart contract logic in Rust within the lib.rs file, specifying state structures and initializing accounts.

 

Compile and Deploy 

 

Use Anchor CLI to compile your code into a Solana program and deploy it to the network.

 

Interact 

 

Users can interact with your contract by sending transactions to its entry points.

 

Testing 

 

Test your contract and use Anchor for upgrades.

 

Suggested Read: Exploring the Potential of Solana Smart Contract Development

 

Creating an Update Counter Smart Contract 

 

About Smart Contract 

 

This is a simple smart contract built using Anchor. This smart contract allows you to initialize a counter account and then increment and decrement it. Only the creator can increment and decrement on the counter account they created and then choose to remove it.

 

Concepts Covered:

  1. PDA - Program Derived Address
  2. Structs
  3. Modify the state of the smart contract
  4. Add Signers for signing the transaction
  5. Error Code
  6. InitSpace for default spacing of account struct
  7. Closing a created PDA and getting the Rent SOL back

 

Dependencies Version 

 

Anchor 0.28.0

 

Solana CLI 1.16.9

 

Project Creation Command

 

anchor init solana-counter

Functions and Functionality

 

First of all, we'll create an account struct that will store data.

 

#[account]
#[derive(Default, InitSpace)]
pub struct Counter {
    pub owner: Pubkey,
    pub counter: u64,
    pub bump: u8,
}

 

Explanation

 

  1. Owner: To store the owner who created the counter account
  2. Counter: To store the count of a particular counter account
  3. Bump: To store the canonical bump of the account

 

Then we'll manage this created account as follows:

 

1. Initialize: To initialize the counter account which can store the above details, below is the code to initialize a counter account. 

 

Account 

 

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(
        init,
        payer = initializer,
        seeds = [
            COUNTER_SEED.as_bytes(),
            initializer.key.as_ref()
        ],
        bump,
        space = 8 + Counter::INIT_SPACE
      )]
    pub counter_account: Account<'info, Counter>,

    #[account(mut)]
    pub initializer: Signer<'info>,

    pub system_program: Program<'info, System>,
}

 

Function 

 

pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        let counter_account = &mut ctx.accounts.counter_account;

        counter_account.owner = ctx.accounts.initializer.key();
        counter_account.counter = 0;
        counter_account.bump = *ctx.bumps.get("counter_account").unwrap();

        Ok(())
}

 

Explanation 

 

  • Counter account: a PDA type account that will be initialized first with the seeds (COUNTER_SEED and initializer account) so that for every initializer there can be a different counter account, we'll store the owner, set the counter to 0 and the canonical bump.
  • Initializer: a Signer-type account that will pay for the account creation.
  • System Program: a System Program account that will be used to create an account with the System Program.

 

2. Increment Counter: To increment the counter account, below is the code to increment a counter account. 

 

Account

 

#[derive(Accounts)]
pub struct Update<'info> {
    #[account(
        mut,
        seeds = [
            COUNTER_SEED.as_bytes(),
            updater.key.as_ref()
        ],
        bump = counter_account.bump,
      )]
    pub counter_account: Account<'info, Counter>,

    #[account(
        mut,
        constraint = updater.key() == counter_account.owner @ ErrorCode::AccessDenied
    )]
    pub updater: Signer<'info>,
}

 

Function

 

pub fn increment_counter(ctx: Context<Update>) -> Result<()> {
        let counter_account = &mut ctx.accounts.counter_account;

        counter_account.counter += 1;

        Ok(())
}

 

Explanation 

 

  • Counter account: the same PDA account that we created before will be passed so that we can access the data from that account.
  • Updater: a Signer-type account that will pay for the account updation.

 

3. Decrement Counter: To decrement the counter account, below is the code to decrement a counter account.

 

Function 

 

pub fn decrement_counter(ctx: Context<Update>) -> Result<()> {
        let counter_account = &mut ctx.accounts.counter_account;

        require!(counter_account.counter > 0, ErrorCode::InvalidCount);

        counter_account.counter -= 1;

        Ok(())
}

 

Explanation 

 

  • Counter account: the same PDA account that we created before will be passed so that we can access the data from that account.
  • Updater: a Signer-type account that will pay for the account updation.

 

Note: We can use the same Update Account in Increment for decrement as well.

 

4. Remove Counter: To remove the counter account, below is the code to remove a counter account.

 

Account 

 

#[derive(Accounts)]
pub struct Remove<'info> {
    #[account(
        mut,
        seeds = [
            COUNTER_SEED.as_bytes(),
            remover.key.as_ref()
        ],
        bump = counter_account.bump,
        close = remover
      )]
    pub counter_account: Account<'info, Counter>,

    #[account(
        mut,
        constraint = remover.key() == counter_account.owner @ ErrorCode::AccessDenied
    )]
    pub remover: Signer<'info>,
}

 

Function 

 

pub fn remove_counter(_ctx: Context<Remove>) -> Result<()> {
        Ok(())
}

 

Explanation 

  • Counter account: the same PDA account that we created before will be passed so that we can access the data from that account.
  • Remover: a Signer type account, who will get the SOL for the account removal.

 

Steps to Deploy on Localhost

 

"solana config get" - Make sure it shows localhost configuration, if not run the command below.

 

"solana config set -url localhost"

 

After the instance is set to localhost, run the command below.

 

"anchor localnet" - This will start a local validator so that you can deploy and run the smart contract.

 

"anchor build" - This will build the smart contract.

 

"anchor keys list" - Copy the program ID that is returned and paste it in lib.rs and Anchor.toml also check if the cluster is set to "localnet".

 

"anchor build" - This will build the smart contract again with the updated program ID.

 

"anchor deploy" - This will deploy the smart contract on the localhost.

 

"anchor run test" - This will run the smart contract test cases.

 

Complete codehttps://github.com/siddharth-oodles/solana-counter

 

Explore More: Why Develop DApps on Solana

 

Solana DApp Development with Oodles 

 

Oodles Blockchain offers a wide range of dApp development services for the Solana blockchain. We enable you to develop robust Solana dApps for fintech, non-fungible token marketplaces, gaming, and beyond. Connect with our Solana developers to discuss your project needs.

Leave a

Comment

Name is required

Invalid Name

Comment is required

Recaptcha is required.

blog-detail

November 21, 2024 at 11:06 am

Your comment is awaiting moderation.

By using this site, you allow our use of cookies. For more information on the cookies we use and how to delete or block them, please read our cookie notice.

Chat with Us
Telegram Button
Youtube Button

Contact Us

Oodles | Blockchain Development Company

Name is required

Please enter a valid Name

Please enter a valid Phone Number

Please remove URL from text