anchor/docs/src/tutorials/tutorial-0.md

190 lines
5.7 KiB
Markdown
Raw Normal View History

# A Minimal Example
2021-01-02 16:24:35 -08:00
2021-01-04 18:29:16 -08:00
Here, we introduce Anchor's core syntax elements and project workflow. This tutorial assumes all
2021-01-05 14:18:55 -08:00
[prerequisites](../getting-started/installation.md) are installed.
2021-01-02 16:24:35 -08:00
2021-01-02 22:40:17 -08:00
## Clone the Repo
2021-01-02 16:24:35 -08:00
To get started, clone the repo.
```bash
2021-01-02 16:29:23 -08:00
git clone https://github.com/project-serum/anchor
2021-01-02 16:24:35 -08:00
```
Next, checkout the tagged branch of the same version of the anchor cli you have installed.
```bash
git checkout tags/<version>
```
Change directories to the [example](https://github.com/project-serum/anchor/tree/master/examples/tutorial/basic-0).
2021-01-02 16:24:35 -08:00
```bash
cd anchor/examples/tutorial/basic-0
```
And install any additional JavaScript dependencies:
```bash
yarn install
```
2021-01-04 18:29:16 -08:00
## Starting a Localnet
In a separate terminal, start a local network. If you're running solana
for the first time, generate a wallet.
```
solana-keygen new
```
Then run
2021-01-04 18:29:16 -08:00
```
solana-test-validator
```
Then, shut it down.
The test validator will be used when testing Anchor programs. Make sure to turn off the validator before you begin testing Anchor programs.
2021-01-05 14:18:55 -08:00
::: details
As you'll see later, starting a localnet manually like this is not necessary when testing with Anchor,
but is done for educational purposes in this tutorial.
:::
2021-01-02 22:40:17 -08:00
## Defining a Program
2021-01-02 16:24:35 -08:00
We define the minimum viable program as follows.
2021-01-04 18:29:16 -08:00
<<< @/../examples/tutorial/basic-0/programs/basic-0/src/lib.rs
2021-01-02 16:24:35 -08:00
2021-01-02 22:40:17 -08:00
* `#[program]` First, notice that a program is defined with the `#[program]` attribute, where each
2021-01-02 16:24:35 -08:00
inner method defines an RPC request handler, or, in Solana parlance, an "instruction"
handler. These handlers are the entrypoints to your program that clients may invoke, as
we will see soon.
2021-01-02 22:40:17 -08:00
* `Context<Initialize>` The first parameter of _every_ RPC handler is the `Context` struct, which is a simple
2021-01-02 18:14:38 -08:00
container for the currently executing `program_id` generic over
2021-01-02 16:24:35 -08:00
`Accounts`--here, the `Initialize` struct.
2021-01-02 22:40:17 -08:00
* `#[derive(Accounts)]` The `Accounts` derive macro marks a struct containing all the accounts that must be
2021-01-02 16:24:35 -08:00
specified for a given instruction. To understand Accounts on Solana, see the
[docs](https://docs.solana.com/developing/programming-model/accounts).
In subsequent tutorials, we'll demonstrate how an `Accounts` struct can be used to
specify constraints on accounts given to your program. Since this example doesn't touch any
accounts, we skip this (important) detail.
2021-01-02 22:40:17 -08:00
## Building and Emitting an IDL
2021-01-02 16:24:35 -08:00
After creating a program, you can use the `anchor` CLI to build and emit an IDL, from which clients
2021-01-02 22:40:17 -08:00
can be generated.
2021-01-02 16:24:35 -08:00
```bash
2021-01-02 22:40:17 -08:00
anchor build
2021-01-02 16:24:35 -08:00
```
2021-01-02 22:40:17 -08:00
::: details
The `build` command is a convenience combining two steps.
2021-01-02 16:24:35 -08:00
2021-01-02 22:40:17 -08:00
1) `cargo build-bpf`
2) `anchor idl parse -f program/src/lib.rs -o target/idl/basic_0.json`.
2021-01-02 22:40:17 -08:00
:::
2021-01-02 18:14:38 -08:00
2021-01-02 22:40:17 -08:00
Once run, you should see your build artifacts, as usual, in your `target/` directory. Additionally,
2021-01-04 18:29:16 -08:00
a `target/idl/basic_0.json` file is created. Inspecting its contents you should see
2021-01-02 16:24:35 -08:00
```json
{
"version": "0.1.0",
"name": "basic_0",
2021-01-02 16:24:35 -08:00
"instructions": [
{
"name": "initialize",
"accounts": [],
"args": []
}
]
}
```
2021-01-02 18:14:38 -08:00
2021-01-04 18:29:16 -08:00
From this file a client can be generated. Note that this file is created by parsing the `src/lib.rs`
2021-01-02 22:40:17 -08:00
file in your program's crate.
::: tip
If you've developed on Ethereum, the IDL is analogous to the `abi.json`.
:::
2021-01-04 18:29:16 -08:00
## Deploying
2021-01-02 22:40:17 -08:00
2021-01-04 18:29:16 -08:00
Once built, we can deploy the program by running
2021-01-02 22:40:17 -08:00
```bash
2021-01-04 18:29:16 -08:00
anchor deploy
2021-01-02 22:40:17 -08:00
```
2021-01-09 22:03:14 -08:00
Take note of the program's deployed address. We'll use it next.
2021-01-02 16:24:35 -08:00
## Generating a Client
2021-01-04 18:29:16 -08:00
Now that we've built a program, deployed it to a local cluster, and generated an IDL,
we can use the IDL to generate a client to speak to our on-chain program. For example,
see [client.js](https://github.com/project-serum/anchor/tree/master/examples/tutorial/basic-0/client.js).
2021-01-02 16:24:35 -08:00
2021-01-04 18:29:16 -08:00
<<< @/../examples/tutorial/basic-0/client.js#main
2021-01-02 16:24:35 -08:00
2021-01-04 18:29:16 -08:00
Notice how we dynamically created the `initialize` method under
2021-01-02 16:24:35 -08:00
the `rpc` namespace.
2021-01-05 14:18:55 -08:00
Now, make sure to plugin your program's address into `<YOUR-PROGRAM-ID>` (a mild
annoyance that we'll address next). In order to run the client, you'll also need the path
to your wallet's keypair you generated when you ran `solana-keygen new`; you can find it
by running
2021-01-04 18:29:16 -08:00
```bash
solana config get keypair
```
Once you've got it, run the client with the environment variable `ANCHOR_WALLET` set to
that path, e.g.
```bash
ANCHOR_WALLET=<YOUR-KEYPAIR-PATH> node client.js
2021-01-04 18:29:16 -08:00
```
2021-01-05 14:18:55 -08:00
You just successfully created a client and executed a transaction on your localnet.
2021-01-04 18:29:16 -08:00
## Workspaces
So far we've seen the basics of how to create, deploy, and make RPCs to a program, but
deploying a program, copy and pasting the address, and explicitly reading
an IDL is all a bit tedious, and can easily get out of hand the more tests and the more
programs you have. For this reason, we introduce the concept of a workspace.
2021-11-11 09:29:10 -08:00
Inspecting [tests/basic-0.js](https://github.com/project-serum/anchor/tree/master/examples/tutorial/basic-0/tests/basic-0.js), we see the above example can be reduced to
2021-01-04 18:29:16 -08:00
<<< @/../examples/tutorial/basic-0/tests/basic-0.js#code
The `workspace` namespace provides access to all programs in the local project and is
automatically updated to reflect the latest deployment, making it easy to change
your program, update your JavaScript, and run your tests in a fast feedback loop.
::: tip NOTE
For now, the workspace feature is only available when running the `anchor test` command,
2021-01-04 18:29:16 -08:00
which will automatically `build`, `deploy`, and `test` all programs against a localnet
in one command.
:::
Finally, we can run the test. Don't forget to kill the local validator started earlier.
We won't need to start one manually for any future tutorials.
```bash
anchor test
```
2021-01-02 16:24:35 -08:00
## Next Steps
2021-01-04 18:29:16 -08:00
We've introduced the basic syntax of writing programs in Anchor along with a productive
workflow for building and testing. However, programs aren't all that interesting without
interacting with persistent state. We'll cover that next.