How to write a simple smart contract for Solana in Rust?

Introduction:

This rudimentary project is going to help us understand how to get started with writing a simple smart contract for Solana in Rust. By the end of this micro-guide, you should have a functioning backend for your Solana Project with the ability to run some tests that are important to make sure that our application does what we require it to.

Requirements:

You will need a few things before you can start writing out the smart contract:

Most Importantly…

⚠️ Once you have installed all the required tools, be sure to add them all to your path so you can execute them.

Now that you have all the required tools, let’s get started!

Setup:

1
solana-keygen new

For this project we will just be running tests to verify that our smart contact is working. So we will not be deploying it.

Now to confirm that solana has been installed correctly, run the following command:

1
solana-test-validator

This will start a local validator that we can use to run our tests.
If you see a counter on the screen, it means that the validator has been set up correctly.

1
anchor init <project-name>

Once this completes, go ahead and run the following command:

1
anchor build

Now inside our anchor project folder we should see an Anchor.toml file.
This file contains our programID which we will use in our rust code.
Now we also need to have a wallet to monitor and approve the transactions that take place after we run tests on our smart contract. That is also specified in the Anchor.toml file.

Writing the smart contract:

1
2
3
4
5
#[account]
pub struct Item {
pub content: String,
pub user: Pubkey,
}

Since everything on Solana is an account, we need to give it a few specific attributes such as who is the owner of the account and what is stored in said account. This is what we are doing in the struct that we have defined.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#[program]
pub mod sol_world {
use super::*;

pub fn init_item(ctx: Context<InitItem>, content: String) -> Result<()> {
let item = &mut ctx.accounts.item;
let user = &mut ctx.accounts.user;

item.content = content;
item.user = *user.key;

Ok(())
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#[derive(Accounts)]
pub struct InitItem<'info> {
#[account(
init,
payer = user,
space = 2000
)]
pub item: Account<'info, Item>,

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

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

Now in the same way we can also create a delete function:

1
2
3
4
5
6
7
8
9
10
11
12
13
#[derive(Accounts)]
pub struct FinishItem<'info> {
#[account(
mut,
has_one = user,
close = user
)]
pub item: Account<'info, Item>,

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

If you followed all the steps till now, you can write your own custom tests to verify the smart contract.

Here is an example tests function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
it("can create an item", async () => {
await program.rpc.initItem("item content", {
accounts: {
item: item.publicKey,
user: provider.wallet.publicKey,
systemProgram: anchor.web3.SystemProgram.programId,
},
signers: [item],
});

let newItem = await program.account.item.fetch(item.publicKey);

assert.strictEqual(newItem.content, "item content");
assert.strictEqual(
newItem.user.toBase58(),
provider.wallet.publicKey.toBase58()
);
});


Once it verifies, it should look something like this:
Output

Future Scope:

Conclusion:

With this I conclude my micro-guide on how to write a simple smart contract for Solana in Rust. I hope that after reading this, you were able to successfully build and test your own simple smart contract. Testing is a crucial part of writing smart contracts so I hope this was easy to understand.