> For the complete documentation index, see [llms.txt](https://canopy-network.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://canopy-network.gitbook.io/docs/build/build-your-first-chain.md).

# Build Your First Chain

This guide runs a local, single-validator Canopy chain and connects the default Go Canopy Template implementation.

By the end, you will have a local chain producing blocks, a validator account created in the local keystore, a second account, and a confirmed transaction onchain. You will also have a working development environment that you can extend with your own application logic.

This is a local development environment. Do not use its generated keys, configuration, or funded genesis balances for a production deployment.

### Before you begin

Complete [Prerequisites](app://-/prerequisites.md) before starting.

For the default native workflow, you need:

* Go 1.26 or later.
* Git and Make.
* Node.js and npm, because `make build/canopy` builds the embedded wallet and explorer assets.
* Protocol Buffers tools if you plan to add custom transaction types.

You will use two terminals during this guide. Leave the node running in the first terminal and use the second terminal for account, transaction, and query commands.

### 1. Clone Canopy

Clone the Canopy repository and move into its directory:

```
git clone https://github.com/canopy-network/canopy.git
cd canopy
```

### 2. Build the Canopy node

From the repository root, build the Canopy binary:

```
make build/canopy
```

This target builds the embedded wallet and explorer assets, then compiles the Canopy command-line binary into your Go binary directory.

Verify that the binary is available:

```
canopy version
```

If your shell cannot find `canopy`, add the Go binary directory to your `PATH`:

```
export PATH="$PATH:$(go env GOPATH)/bin"
```

Add that line to your shell configuration file if you want the change to persist across new terminal sessions.

### 3. Build the Go Template implementation

The Go Canopy Template is the default application implementation used throughout the Build guides.

From the repository root, build it with:

```
make build/plugin PLUGIN=go
```

This builds the language-specific runtime implementation that will run beside the Canopy node.

The term **Canopy Template** describes the builder-facing starting point. The `PLUGIN=go` value is the technical identifier that selects the Go implementation at build and runtime.

You do not need to start this process manually. Once configured, `canopy start` manages the local Template runtime as part of the node lifecycle.

### 4. Generate local configuration

Start the node once to create the default local configuration and keystore:

```
canopy start
```

On its first run, Canopy prompts you to create a local validator key.

```
Enter password for your new private key:
Enter a nickname for this key:
```

For a disposable local environment, you may press Enter to leave the password blank and accept the default `validator` nickname. For any environment that contains meaningful funds or credentials, use a strong password and store it securely.

After the files are created, stop the node with `Ctrl+C`.

The default local data directory is:

```
~/.canopy/
```

It includes configuration, genesis state, a validator signing key, and local keystore data.

```
~/.canopy/
├── config.json
├── genesis.json
├── private_key.json
└── keystore/
```

Do not commit these files to a repository. They contain environment-specific configuration and local key material.

### 5. Configure the Go Template

Open the generated configuration file:

```
~/.canopy/config.json
```

Find the `plugin` field and set it to `go`:

```
{
  "plugin": "go"
}
```

The `go` value tells the node to start the Go Template implementation. The node and the implementation communicate locally through a Unix socket using Protocol Buffers.

Start the node again:

```
canopy start
```

On successful startup, the node should report that the Go implementation has connected. The exact log format may vary by version, but look for a message that identifies the Go contract or Template runtime as connected.

The node starts and manages the local runtime through its Template control script. You do not need to run a second copy of the implementation manually.

If you want to inspect the implementation logs separately, use:

```
tail -f /tmp/plugin/go-plugin.log
```

Leave this terminal running for the remaining steps.

### 6. Inspect the validator account

Open a second terminal.

The first node start created a local validator key and funded it in the development genesis state. List the local keystore:

```
canopy admin ks
```

The output includes the address, nickname, and validator status of each local key.

Copy the address for the `validator` key, then query its account:

```
canopy query account <validator-address>
```

The account should show a funded balance and staked amount. Amounts are expressed in the chain’s smallest denomination.

The genesis account is pre-funded only to make local development possible. It lets you submit transactions immediately without obtaining test tokens or connecting to an external network.

### 7. Create a second local account

Create a recipient account named `alice`:

```
canopy admin ks-new-key --nickname alice
```

The command returns Alice’s address. Store it for the next step.

You can query the account before it receives funds:

```
canopy query account <alice-address>
```

A newly created key may not yet have an onchain account record or may show a zero balance. That is expected. The account becomes meaningful to the chain once it receives state through a transaction.

### 8. Submit your first transaction

Send tokens from the validator account to Alice:

```
canopy admin tx-send \
  <validator-address> \
  <alice-address> \
  10000000
```

You can also use local key nicknames:

```
canopy admin tx-send validator alice 10000000
```

The amount is in the smallest unit of the local chain’s token.

The command constructs a signed `MessageSend` transaction and submits it to the node. A successful submission means the transaction has entered the mempool. It is not final until the node includes it in a block.

### 9. Verify the transaction

Wait for the next block, then query Alice’s account:

```
canopy query account <alice-address>
```

Alice’s balance should now include the amount you sent.

You can also query the transaction by the hash returned when it was submitted:

```
canopy query tx <transaction-hash>
```

Finally, confirm that the chain is producing blocks:

```
canopy query height
```

Run the height query again after a short interval. If the height increases, the local chain is producing blocks normally.

### What happened behind the scenes

Several components worked together to process the transaction.

First, the Canopy node received the signed transaction through its RPC interface and placed it in the mempool.

The node routed the transaction to the local Go Template implementation for `CheckTx()` processing. This step validates the message structure, addresses, fee requirements, and authorized signer information before the transaction is proposed in a block.

The single validator then proposed and committed a block through the local NestBFT process.

When the transaction was included in the block, the node routed it to `DeliverTx()`. The Go Template implementation read the relevant account and fee-pool records from state, checked that the sender had sufficient funds, updated the sender and recipient balances, and wrote the resulting state changes back through the Canopy finite state machine.

The `canopy query account` command then read the updated state and returned Alice’s new balance.

This is the same basic runtime model you will use when you add your own application transaction types.

### Use AI to inspect the starting point

Before changing the Template, ask your AI coding assistant to explain the existing implementation.

For example:

```
Read AGENTS.md and the Go Template README. Trace a MessageSend transaction from
its Protobuf definition through CheckTx, DeliverTx, state reads, state writes,
and the RPC command that submits it. Do not modify code yet.
```

This gives you a concrete working example before you ask the assistant to generate a new transaction type.

Once you understand the default send flow, you can define your own application behavior. Start by describing the action in plain language, then identify the transaction fields, validation rules, state records, and expected test cases.

### Docker alternative

If you prefer a containerized environment, build the Docker image for the Go implementation from the repository root:

```
make docker/plugin PLUGIN=go
```

Run the resulting image with the local Canopy data directory mounted:

```
make docker/run-go
```

The Docker workflow uses the same Canopy node, state model, and Go Template implementation. It is an alternative execution environment, not a different development model.

Consult the repository’s Docker configuration for the current port mappings and compose workflow before exposing RPC services outside your local machine.

### Troubleshooting

#### `canopy: command not found`

Your Go binary directory is not on the shell `PATH`.

```
export PATH="$PATH:$(go env GOPATH)/bin"
```

Open a new terminal or reload your shell configuration after adding the path.

#### `make build/canopy` fails while building wallet or explorer assets

The current build target also runs npm build commands for embedded web assets. Install a supported Node.js release and npm, then run the build again.

#### The Go Template implementation does not connect

Confirm that you built the implementation:

```
make build/plugin PLUGIN=go
```

Then confirm that the `plugin` value in `~/.canopy/config.json` is set to `go`.

Inspect the runtime log for details:

```
tail -f /tmp/plugin/go-plugin.log
```

#### A submitted transaction does not appear onchain

First, confirm that the chain height is advancing:

```
canopy query height
```

Then inspect pending transactions:

```
canopy query pending
```

If the transaction remains pending, inspect the node output and the Go Template runtime log for validation or connection errors.

#### The transaction fails with an insufficient-fee error

The local genesis configuration defines a minimum fee. Submit the transaction with an explicit fee that meets the configured minimum:

```
canopy admin tx-send validator alice 10000000 --fee 10000
```

Check the current local genesis and Template configuration before changing fee values.

Next, define your first custom transaction in [Build a Basic App](app://-/build-a-basic-app.md).
