Getting started with Solana and Anchor
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
- Install Solana
- Use Solana locally
- Generate your local key pair
- Install Anchor
- Install yarn
- Create a new Anchor project
- Build and deploy
- Run a local ledger
- Update your program ID
- Anchor scripts
- Anchor test
- Anchor localnet
- Conclusion
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 runninganchor 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.
Now that, we're all set up and we understand our development cycle, let's start building things! 🔥