Create a Solana dApp from scratch

Getting started with Solana and Anchor

Episode 2
10 months ago
12 min read

Getting started with Solana can be quite the chore without a guide. In this article, I’ll make sure we have everything ready in our local machine to get started with Solana programs using the Anchor framework.

Since there is quite a lot to go through, I'll make sure to get to the point quickly so you can re-read this article as an actionable checklist in the future. That being said, we will spend a bit of time digging through how Anchor works to better understand the "Build, Deploy, Test" cycle we will use throughout this series.

If you're a Windows user, I'm afraid this guide is more tailored for Linux and Mac users. Fortunately, Buildspace has got a nice guide for installing Solana on a Windows machine so hopefully, you can still follow along after that.

I’d also like to add that the Solana ecosystem moves relatively quickly and, therefore, some of these steps might end up changing or — fingers crossed — being simplified in the future. If that’s the case, please reach out to me and I’ll make sure to update the article accordingly.

Finally, here's a table of content in case you're re-reading this and looking for a particular section.

Install Rust

Why? Rust is the language Solana uses to build programs.

Installing Rust is as simple as running this.

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

When installed, it will add the following PATH — or similar — to your shell configurations which is good to know if you want to move that to your dotfiles or something.

export PATH="$HOME/.cargo/bin:$PATH"

You can check that rust is properly installed by running the following commands.

rustup --version
rustc --version
cargo --version

Install Solana

Similarly, you can install Solana by running the following installer script.

sh -c "$(curl -sSfL https://release.solana.com/v1.9.4/install)"

Note that newer versions might have been released since then so feel free to check for the latest version on the Solana documentation.

Installing Solana will also add a new PATH to your shell configurations. Alternatively, depending on your system, it might ask you to manually update your PATH by providing you with a line to copy/paste.

export PATH="$HOME/.local/share/solana/install/active_release/bin:$PATH"

You can check that Solana is properly installed by running the following commands.

# Check the Solana binary is available.
solana --version

# Check you can run a local validator (Run Ctrl+C to exit).
# We’ll see what this does in this article.
# Note this creates a "test-ledger" folder in your current directory.
solana-test-validator

EDIT 2022-01-15: Since Solana v1.9.4, Apple M1 users no longer need to compile the Solana binaries from source and can simply follow the instructions above! 🥳 If you have an Apple M1 computer and you're using an older version of Solana, you can read the previous instructions on this gist.

Use Solana locally

Why? Solana defaults to using the “mainnet” network. For now, we want to develop our programs locally before we deploy them for real.

solana config set --url localhost

After running this, you should see all your configs pointing to localhost URLs which is exactly what we want.

Generate your local key pair

Why? We need a public and private key to identify ourselves when using the Solana binaries locally.

First, you might want to check if you've already got a local key pair by running the following command.

solana address

If you get an error, that means you don't have one yet and so let's create a new one.

Simply run the following command and follow the steps. Personally, I don't enter a paraphrase since the generated key pair will only be used locally.

solana-keygen new

At the end of the process, you will be given a long recovery phrase that can be used to recover both your public and private key. Even though it's only used locally, I still store that recovery phrase on my password manager just in case.

Note that you can recover any key pair by running solana-keygen recover and providing the recovery phrase in the process.

Install Anchor

Why? Anchor is a Solana framework that significantly improved the developer experience when creating programs.

You can install Anchor in your local machine by running the following command.

cargo install --git https://github.com/project-serum/anchor anchor-cli --locked

Note that you can also install Anchor using npm globally but since I use multiple versions of npm via nvm I'm not a big fan of npm global dependencies.

You may run the following command to check Anchor CLI is installed properly.

anchor --version

Install yarn

Why? By default, Anchor relies on yarn to manage JavaScript libraries.

If you don't have it installed already, you can do so by running one of the following commands:

# Using npm global dependencies.
npm install -g yarn

# Using homebrew on Mac.
brew install yarn

# Using apt on Linux
apt install yarn

Create a new Anchor project

Now that we have Anchor installed, we can run anchor init to start a new project!

# Go to your dev folder (for me it’s “~/Code”).
cd ~/Code

# Create a new Anchor project.
anchor init solana-twitter

# Cd into the newly created project.
cd solana-twitter

Inside our new project, Anchor prepared a bunch of things for us:

  • A programs folder for all our Solana programs. It already comes with a very simple program we can build upon so we don't have to do all the scaffolding.
  • A tests folder for all our JavaScript tests directly interacting with our programs. Again, it already comes with a test file for our auto-generated program.
  • An Anchor.toml configuration file helping us configure our program ID, Solana clusters, test command, etc.
  • An empty app folder that will, later on, contain our JavaScript client.

Now that we have our project scaffolded, let's see how we can build, deploy and test the default program generated by Anchor. That way, we'll understand more about the development cycle of building a Solana program.

Build and deploy

Anchor has two very useful commands that will delegate to the Rust compiler and Solana CLI tools to build and deploy your programs for you.

# Compiles your program.
anchor build

# Deploys your compiled program.
anchor deploy

Whilst these commands are not necessary to compile and deploy, they certainly make the developer experience a lot more enjoyable by abstracting all of the more complex commands we would otherwise need to run.

That being said, let's have a quick look at what happens when we run these commands.

Anchor build

First, our code is compiled and we will be shown any warnings or errors that occur at compile time. The Rust compiler is pretty powerful so if we did something wrong in our code, it most likely won't let use compile it.

Let's run this command on our brand new project.

anchor build

As you can see our program compiled but you should see the following warning: unused variable: 'ctx'. That's fair because the auto-generated program is so simple that it doesn't actually do anything with that ctx variable and, therefore, the compiler warns us it's not being used. We can safely ignore that warning for now.

Additionally, once our code was compiled, the target folder was updated accordingly. You don't need to fully understand what's happening inside that folder but it basically keeps track of any built releases and deployment of our program. Note that this folder is relative to your local machine and will not be committed to your git repository.

Finally, anchor build also generated an IDL file. IDL stands for "Interface Description Language" and it is quite simply a JSON file that contains all the specifications of our Solana program. It contains information about its instructions, the parameters required by these instructions, the accounts generated by the program, etc.

The purpose of this IDL file is to feed it to our JavaScript client later on so we can interact with our Solana program in a structured manner.

Anchor deploy

Running anchor deploy will take our latest build and deploy it on the cluster.

Note that the first time you build a program, it will also generate a public and private key for it — which will be stored in the target directory. The public key generated will become the unique identifier of your program — a.k.a the program ID.

Since we've set up our cluster to be localhost earlier, we currently have no network to deploy to. That means, if you try to run anchor deploy right now, you'll get an error saying error sending request for url (http://localhost:8899/).

To fix that, we need to run a local ledger.

Run a local ledger

A local ledger is basically a simulation of a Solana cluster inside your local machine. When building locally, we don't actually want to send anything to the Solana blockchain so this is exactly what we want.

Fortunately for us, running a local ledger is as simple as running the following command.

solana-test-validator

This command will keep a session open in your terminal until you exit it by running Ctrl+C. Whilst the session is open, you now have a local ledger to deploy to! 🎉

That means you can now run anchor deploy and it successfully deploy to your local ledger.

anchor deploy

Note that all the data sent to your local ledger is stored in a test-ledger folder created in the current directory.

So let's make sure we don't commit that entire folder to our git repository by updating our .gitignore file like so.

  .anchor
  .DS_Store
  target
  **/*.rs.bk
  node_modules
+ test-ledger

Also note that exiting your local ledger (by running Ctrl+C) will not destroy any data you've sent to the cluster. However, removing that test-ledger folder will. You can achieve the same result by adding the --reset flag.

# Runs a new empty local ledger.
solana-test-validator --reset

Update your program ID

Now that we've run anchor build and anchor deploy for the first time, we need to update our program ID.

As we've mentioned above, a new key pair for our program is generated on the very first deployment. Before that, we simply don't know what the public address of our program will be.

Your program ID should be displayed when running anchor deploy but you may also access it by using the following Solana command.

solana address -k target/deploy/solana_twitter-keypair.json
# Outputs something like: 2EKFZUwMrNdo8YLRHn3CyZa98zp6WH7Zpg16qYGU7htD

Depending on how you named your anchor project, this file might be called something else so you may have to look at the target/deploy folder to find the right file.

Okay now that we know our program ID, let's update it.

When we created our new project using anchor init, Anchor used a random placeholder in two places as our program ID that we can now replace.

First, in our Anchor.toml configuration file.

[programs.localnet]
solana_twitter = "2EKFZUwMrNdo8YLRHn3CyZa98zp6WH7Zpg16qYGU7htD"

Then, in the lib.rs file of our Solana program. In my case, that's programs/solana-twitter/src/lib.rs.

use anchor_lang::prelude::*;
use anchor_lang::solana_program::system_program;

declare_id!("2EKFZUwMrNdo8YLRHn3CyZa98zp6WH7Zpg16qYGU7htD");

Finally, we need to build and deploy one more time to make sure our program is compiled with the right identifier.

anchor build
anchor deploy

Anchor scripts

Before we wrap up this article, I’d like to make sure we can run the generated tests on our program.

If you look inside your Anchor.toml file, you'll notice a scripts section containing a test script.

[scripts]
test = "yarn ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"

This is already configured for us so that it'll run all the tests inside our tests folder using Mocha.

To run that script, run the following command.

anchor run test

If you have a local ledger running — via solana-test-validator — and you've built and deployed your project properly — via anchor build and anchor deploy — then you should see the test passing!

Note that you can add any custom script to your Anchor.toml configuration file and use anchor run to execute it. Here's a quick example.

[scripts]
test = "..."
my-custom-script = "echo 'Hello world!'"
anchor run my-custom-script
# Outputs: Hello world!

Anchor test

Alright, we now know the full development cycle. First, you need a local ledger, then you can build, deploy and test. Here's a quick recap:

# Start the local ledger.
solana-test-validator

# Then, on a separate terminal session.
anchor build
anchor deploy
anchor run test

Well, it turns out anchor has a special command that takes care of that full cycle for us. It's called:

anchor test

⛔️ Not to confuse with anchor run test that only runs the test script inside your Anchor.toml file.

So what does anchor test actually do?

  • First, it starts a local ledger that will be automatically terminated at the end of the command. That means you cannot run anchor test if you already have a local ledger running. Make sure to terminate any local ledger before running anchor test, this is a common gotcha. Also, note that it uses the --reset flag to make sure our tests always start with the same empty data.
    solana-test-validator --reset
    
  • Now, Anchor is ready to build, deploy and run the tests.
    anchor build
    anchor deploy
    anchor run test
    

The anchor test command is really powerful when developing your Solana programs locally. It abstracts away all the faff and lets you focus on your program.

Remember though that running anchor test immediately after generating a new project — via anchor init — will not work because you'll first need to update your program ID after the first deployment.

Therefore I suggest, you build and deploy manually the very first time and once you've updated your program ID, you can start using anchor test.

Anchor localnet

If you end up working on other Anchor projects, you might come across the anchor localnet command. This command is very similar to anchor test except that it does not run any test and does not terminate the local ledger at the end.

Thus, it is basically the equivalent to:

solana-test-validator --reset
anchor build
anchor deploy

# The local ledger will stay active after deployment.

This command is typically used to quickly spin up your program when working on your frontend client.

Conclusion

Phew, we got there in the end! Congratulations on setting up your local machine with Solana and Anchor. On top of that, we now have a fully scaffolded project we can use to build our Twitter in Solana project.

I do hope you didn't encounter too many issues along the way. I know setting up things on your machine can be a real nightmare especially when the technology is moving quickly. If you have any issues feel free to add a comment to this article or better yet, create an issue on the GitHub repository below so anyone can jump in and help you across all episodes.

If you want to see the code we generated during this episode, here's a link to the episode-2 branch of this series' repository.

View Episode 2 on GitHub

Now that, we're all set up and we understand our development cycle, let's start building things! 🔥

← Previous episode
What are we building?

Discussions

Author avatar
Đorđe Zeljić
10 months ago

First of all, great post(s)!

If you have trouble running anchor deploy and getting --program-id error, there is opened issue on GH: https://github.com/project-serum/anchor/issues/1000

💖 1

Discussion

Getting started with Solana and Anchor
Author avatar
Đorđe Zeljić
10 months ago

First of all, great post(s)!

If you have trouble running anchor deploy and getting --program-id error, there is opened issue on GH: https://github.com/project-serum/anchor/issues/1000

💖 1
Author avatar
Loris Leiva
10 months ago

Thanks for sharing! 🍺

💖 0

Would you like to chime in?

You must be a member to add a reply to a discussion.

Fortunately, it only takes two click to become one. See you on the other side! 🌸

Become a Member
Author avatar
Ahmed Ali
10 months ago

About time someone starts such great content! Thank you for the amazing series! can't stress how useful it is. Even after reading and fiddling around Solana and Anchor documentation, I am still finding this series helpful and putting things together quite nicely!

💖 1

Discussion

Getting started with Solana and Anchor
Author avatar
Ahmed Ali
10 months ago

About time someone starts such great content! Thank you for the amazing series! can't stress how useful it is. Even after reading and fiddling around Solana and Anchor documentation, I am still finding this series helpful and putting things together quite nicely!

💖 1
Author avatar
Loris Leiva
10 months ago

Thank you! ❤️

💖 0

Would you like to chime in?

You must be a member to add a reply to a discussion.

Fortunately, it only takes two click to become one. See you on the other side! 🌸

Become a Member
Author avatar
akangaziz
9 months ago

awesome summary. well done!

if you use M1, the quickest way to run your local solana validator is by using docker: https://github.com/metaspan/solana-docker-mac-m1

💖 0

Discussion

Getting started with Solana and Anchor
Author avatar
akangaziz
9 months ago

awesome summary. well done!

if you use M1, the quickest way to run your local solana validator is by using docker: https://github.com/metaspan/solana-docker-mac-m1

💖 0

Would you like to chime in?

You must be a member to add a reply to a discussion.

Fortunately, it only takes two click to become one. See you on the other side! 🌸

Become a Member
Author avatar
yiksanchan
9 months ago

Awesome! Though I run into an issue: anchor run test throws TypeError: mixin.wrap is not a function. More details can be found https://github.com/lorisleiva/solana-twitter/issues/1

Look forward to any help!

💖 0

Discussion

Getting started with Solana and Anchor
Author avatar
yiksanchan
9 months ago

Awesome! Though I run into an issue: anchor run test throws TypeError: mixin.wrap is not a function. More details can be found https://github.com/lorisleiva/solana-twitter/issues/1

Look forward to any help!

💖 0

Would you like to chime in?

You must be a member to add a reply to a discussion.

Fortunately, it only takes two click to become one. See you on the other side! 🌸

Become a Member
Author avatar
Nemanja
8 months ago

If you get error

Error: failed to get recent blockhash: FetchError: request to http://localhost:8899/ failed, reason: connect ECONNREFUSED ::1:8899

You need to update test file to use

const provider = anchor.Provider.local("http://127.0.0.1:8899"); anchor.setProvider(provider);

if someone know why is this, let us know :)

💖 0

Discussion

Getting started with Solana and Anchor
Author avatar
Nemanja
8 months ago

If you get error

Error: failed to get recent blockhash: FetchError: request to http://localhost:8899/ failed, reason: connect ECONNREFUSED ::1:8899

You need to update test file to use

const provider = anchor.Provider.local("http://127.0.0.1:8899"); anchor.setProvider(provider);

if someone know why is this, let us know :)

💖 0

Would you like to chime in?

You must be a member to add a reply to a discussion.

Fortunately, it only takes two click to become one. See you on the other side! 🌸

Become a Member
Author avatar
Dohyeon lee
8 months ago

Hi! Thank you for the great article! I want to ask a question about the anchor deploy part. After I have deployed the program, the test-ledger folder was not created in the current directory while I did not get any error. Are there any places where the test-ledger folder can be saved to?

Thanks!

💖 0

Discussion

Getting started with Solana and Anchor
Author avatar
Dohyeon lee
8 months ago

Hi! Thank you for the great article! I want to ask a question about the anchor deploy part. After I have deployed the program, the test-ledger folder was not created in the current directory while I did not get any error. Are there any places where the test-ledger folder can be saved to?

Thanks!

💖 0
Author avatar
Loris Leiva
8 months ago

Yes, if you only use the anchor CLI commands, Anchor will create a test-ledger folder for you inside another .anchor hidden folder where all the anchor stuff lives.

The test-ledger folder will be created if you use the solana-test-validator command.

💖 0

Would you like to chime in?

You must be a member to add a reply to a discussion.

Fortunately, it only takes two click to become one. See you on the other side! 🌸

Become a Member
Author avatar
Shaun
7 months ago

Hello there, I am facing the following error upon typing

anchor build

can you please help

Compiling solana-twitter v0.1.0 (/home/sadaf/mynewTwitter/solana-twitter/programs/solana-twitter) error[E0412]: cannot find type ProgramResult in this scope --> programs/solana-twitter/src/lib.rs:8:52 | 8 | pub fn initialize(ctx: Context<Initialize>) -> ProgramResult { | ^^^^^^^^^^^^^ not found in this scope

warning: unused import: anchor_lang::solana_program::system_program --> programs/solana-twitter/src/lib.rs:2:5 | 2 | use anchor_lang::solana_program::system_program; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: #[warn(unused_imports)] on by default

For more information about this error, try rustc --explain E0412. warning: solana-twitter (lib) generated 1 warning error: could not compile solana-twitter due to previous error; 1 warning emitted

💖 2

Discussion

Getting started with Solana and Anchor
Author avatar
Shaun
7 months ago

Hello there, I am facing the following error upon typing

anchor build

can you please help

Compiling solana-twitter v0.1.0 (/home/sadaf/mynewTwitter/solana-twitter/programs/solana-twitter) error[E0412]: cannot find type ProgramResult in this scope --> programs/solana-twitter/src/lib.rs:8:52 | 8 | pub fn initialize(ctx: Context<Initialize>) -> ProgramResult { | ^^^^^^^^^^^^^ not found in this scope

warning: unused import: anchor_lang::solana_program::system_program --> programs/solana-twitter/src/lib.rs:2:5 | 2 | use anchor_lang::solana_program::system_program; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: #[warn(unused_imports)] on by default

For more information about this error, try rustc --explain E0412. warning: solana-twitter (lib) generated 1 warning error: could not compile solana-twitter due to previous error; 1 warning emitted

💖 2
Author avatar
MEMPOOL
3 months ago

did you manage to solve it? I having the same error.

💖 0

Would you like to chime in?

You must be a member to add a reply to a discussion.

Fortunately, it only takes two click to become one. See you on the other side! 🌸

Become a Member
Author avatar
Few things to add:
7 months ago

I don't have web development experience, im a game/VR developer. So few notes for those who are approaching this tutorial from non-web domains:

Before starting this tutorial:

Make sure you have build-essential installed (sudo apt-get install build-essential) otherwise you will have linker error.

make sure you have libudev installed (sudo apt-get install libudev)

Make sure you have libssl-dev and not just libssl (apt install libssl-dev)

Make sure your nodejs version (node --version) is above 11 (mine was 10.9 or something and it gave errors).

Also, before starting work on any new project, its generally a good idea to run apt-get update and apt-get upgrade commands.

💖 0

Discussion

Getting started with Solana and Anchor
Author avatar
Few things to add:
7 months ago

I don't have web development experience, im a game/VR developer. So few notes for those who are approaching this tutorial from non-web domains:

Before starting this tutorial:

Make sure you have build-essential installed (sudo apt-get install build-essential) otherwise you will have linker error.

make sure you have libudev installed (sudo apt-get install libudev)

Make sure you have libssl-dev and not just libssl (apt install libssl-dev)

Make sure your nodejs version (node --version) is above 11 (mine was 10.9 or something and it gave errors).

Also, before starting work on any new project, its generally a good idea to run apt-get update and apt-get upgrade commands.

💖 0

Would you like to chime in?

You must be a member to add a reply to a discussion.

Fortunately, it only takes two click to become one. See you on the other side! 🌸

Become a Member
Author avatar
Marcin Kożuchowski
5 months ago

Hi Lori, love your tutorial. I got a nice fix for y'all There's no need to build and deploy the program to check the program addres with " solana address -k target/deploy/solana_twitter-keypair.json" command. Just after anchor init cd into the directory and run anchor keys list It will show you the keys, and you can update lib.rs and anchor.toml

💖 0

Discussion

Getting started with Solana and Anchor
Author avatar
Marcin Kożuchowski
5 months ago

Hi Lori, love your tutorial. I got a nice fix for y'all There's no need to build and deploy the program to check the program addres with " solana address -k target/deploy/solana_twitter-keypair.json" command. Just after anchor init cd into the directory and run anchor keys list It will show you the keys, and you can update lib.rs and anchor.toml

💖 0

Would you like to chime in?

You must be a member to add a reply to a discussion.

Fortunately, it only takes two click to become one. See you on the other side! 🌸

Become a Member
Author avatar
Philip Lee
5 months ago

Just wanted let you know I couldnt install anchor, kept getting errors about missing things. Finally someone helped me and said these 2 commands need run first:

sudo apt-get update sudo apt-get install libssl-dev libudev-dev pkg-config zlib1g-dev llvm clang cmake make

After that it all installed... think its worth adding to tutorial, Im on Windows WSL

💖 0

Discussion

Getting started with Solana and Anchor
Author avatar
Philip Lee
5 months ago

Just wanted let you know I couldnt install anchor, kept getting errors about missing things. Finally someone helped me and said these 2 commands need run first:

sudo apt-get update sudo apt-get install libssl-dev libudev-dev pkg-config zlib1g-dev llvm clang cmake make

After that it all installed... think its worth adding to tutorial, Im on Windows WSL

💖 0

Would you like to chime in?

You must be a member to add a reply to a discussion.

Fortunately, it only takes two click to become one. See you on the other side! 🌸

Become a Member

Would you like to chime in?

You must be a member to start a new discussion.

Fortunately, it only takes two click to become one. See you on the other side! 🌸

Become a Member