Getting Started

ResourcesDescription
Integration GuidesComprehensive guides of the basics, key management, block confirmation tracking, work generation, compiling and running a node, websockets, and advanced setups
Tools & LibrariesList of community tools in various platforms and languages
Test networkInformation about how to join and use the test network
tools.nanos.ccHelpful tools for unit conversion, key management, block generation, common RPC queries
Design Overview & ReferenceAn overview and reference to common Nano protocol details
DocumentationLinks to documentation information
Getting Started GuideA step-by-step getting started guide by SomeNano

Do not hesitate to reach out to the community to start a discussion or get support.

Introduction

Below are a couple of key basics to know to get you going quickly. For a more comprehensive guide, view the Official Integration Guides.

If you are interested in directly contributing to nano development or its ecosystem, view the contribution guides.

Block-lattice

Nano's unique ledger structure, known as block-lattice, underpins its functionality. Each account has its own blockchain (account-chain), where each block is a single operation that contains the entire state for that account (balance & representative). Thus, the latest block for each account (called a frontier) is all you need to know the current state for a given account. Blocks belong to an account, thus only the private key holder can produce a valid block for that account.

Account

An account is a public-private key-pair most commonly derived deterministically from a seed. Changes to the state of an account can only be made using the private key for that account.

Seed

A series of 32 random bytes of data, usually represented as a 64 character, uppercase hexadecimal string (0-9A-F). This value is used to derive account private keys for accounts by combining it with an index and then putting that into the following hash function where || means concatenation and i is a 32-bit big-endian unsigned integer:

PrivK[i] = blake2b(outLen = 32, input = seed || i)

Private keys are derived deterministically from the seed, which means that as long as you put the same seed and index into the derivation function, you will get the same resulting private key every time.

Account Private Key

A 32-byte value, usually represented as a 64 character, uppercase hexadecimal string (0-9A-F). It can either be random (an ad-hoc key) or derived from a seed, as described above.

Account Public Key

A 32-byte value, usually represented as a 64 character, uppercase hexadecimal string (0-9A-F). It is derived from an account private key by using the ED25519 curve using Blake2b-512 as the hash function (instead of SHA-512). Usually account public keys will not be passed around in this form, rather the below address is used.

Account Address

A string that starts with nano_ (previously xrb_), then has 52 characters which are the account public key but encoded with a specific base32 encoding algorithm to prevent human transcription errors by limiting ambiguity between different characters (no O and 0 for example). Then the final 8 characters are Blake2b-40 checksum of the account public key to aid in discovering typos, also encoded with the same base32 scheme (5 bytes).

Nano account address encoding
Ex. nano_1anrzcuwe64rwxzcco8dkhpyxpi8kd7zsjc1oeimpc3ppca4mrjtwnqposrs

Wallet ID

Is just a local UUID that references a specific wallet (set of seed/private keys/info about them) in the node's local database file (pertaining to the reference C++ node implementation). Do not confuse this with a seed or private key.

Transactions

Given that an account's state can only be updated by the corresponding secret key, a transaction consists of two operations / blocks.

  1. Send block: the sender broadcasts an operation that deducts the balance of their account by the amount they are sending
  2. Receive block: the receiver broadcasts an operation that references the sender's operation and increases the balance of their account by the amount sent to them

Once the send block is confirmed by the network, the transaction is irreversible and the receiver can broadcast a receive block at any point in the future to update their balance and use the funds sent to them. Thus, the total amount of nano across send blocks without a corresponding receive block is referred to as a "Receivable Balance".

Accessing the Network

The most common way to access the network is through RPC commands to either a local or public node.

Basics

Generating an account

In most situations, you'll want to derive an account from a seed and it's best to use an existing library. For a more comprehensive guide, view the key management section of the Official Integration Guides.

import { wallet as walletLib } from 'nanocurrency-web'
const wallet = walletLib.generate()
import nanolib
seed = nanolib.generate_seed()
account_id = nanolib.generate_account_id(seed, 0)

Libraries

Node.js / JavaScript
NameDescription
nanocurrency-webToolkit for Nano cryptocurrency client side offline integrations without requiring NodeJS functions
nanocurrency-js🔗 A toolkit for the Nano cryptocurrency, allowing you to derive keys, generate seeds, hashes, signatures, proofs of work and blocks.
Nano.jsLibrary to interact with the nano blockchain through javascript
Typescript
NameDescription
nona-libTypeScript library to simplify interactions with the Nano currency node.
Dart
NameDescription
nanodartDart library for the NANO and BANANO cryptocurrencies - supports key generation, signing, encryption, and more.
nanoutilA Nano and Banano cryptocurrency library for the Dart programming language
Python
NameDescription
nanolibPython library for working with the NANO cryptocurrency protocol
nanopyPython implementation of NANO related functions
pippinA high performance, lightweight alternative to the NANO Node developer wallet (includes production wallet)
nanohakaseNanohakase is a python library for the Nano cryptocurrency. It aims to be the simplest Nano library out there, and is a self fork of Bananopie
nano-rpc-pypython library that dynamically generates methods based on a commands dictionary
Rust
NameDescription
nanopyrsRust rewrite of the Python nanopy library
Ruby
NameDescription
nanookRuby library for making and receiving payments and managing a nano currency node
.NET
NameDescription
Nano.NETA .NET library for Nano
Java
NameDescription
jNanoA comprehensive Java library for the Nano cryptocurrency.
Go
NameDescription
gonanoGo language support for Nano, a digital currency
Swift
NameDescription
NanoSwiftA Swift library for the Nano cryptocurrency.

Notable RPC Commands

  • key_create — create random adhoc keypair
  • key_expand — derive public key and address from a private key

Building a block

Depending on what type of block you are creating (send, receive, open, change), you will need to know the following properties:

Send

FieldDescription
previoushash of the previous block
representativeaddress of the representative, must match the previous block
accountaccount the block belongs to
balanceprevious balance minus the amount being sent (in raw)
linkaddress you are sending to

Receive

FieldDescription
previoushash of the previous block
representativeaddress of the representative, must match the previous block
accountaccount the block belongs to
balanceprevious balance plus the amount being sent in the linked block (in raw)
linkblock hash of the send transaction to this account

Open

The first transaction on an account-chain, which is always a receive, is referred to as an open block. It's a receive but the previous field is all zeros.

FieldDescription
previouswill be 0 since it's the first block
representativeaddress of the representative, must match the previous block
accountaccount the block belongs to
balanceprevious balance plus the amount being sent in the linked block (in raw)
linkblock hash of the send transaction to this account

Change

FieldDescription
previoushash of the previous block
representativeaddress of the new representative
accountaccount the block belongs to
balanceprevious balance

Notable RPC Commands

Generating Work

Every block published to the network, whether a send, receive, or representative change block, requires a small, valid Proof-of-Work to be completed above a minimum difficulty floor (threshold). As of V21, this threshold is different for different block types: send and change blocks require a higher threshold, while receive blocks are lower.

The Proof-of-Work nonce is calculated against the hash of the previous block, or the account public key if it is for an open block.

block typedifficulty thresholdcalculated against
Send or Changefffffff800000000previous block hash
Receivefffffe0000000000previous block hash
Openfffffe0000000000account public key

Proof-of-Work Resources

Broadcasting a block

To publish a block to the network, you would use the process RPC command of a node.

Notable RPC Commands

Confirming a block

The most efficient way to watch for block confirmations is via WebSockets. Additionally, you can check the status of a given block via RPC using block_info.

Notable RPC Commands

Using the test network

The test network exists primarily to conduct general integration and node upgrade testing in light volumes. By providing a network with similar parameters to the main network (work difficulty, etc.) this is the best environment for connecting test or staging versions of services and applications to for small scale tests.

Visit the official docs for more information about the test network.

Getting Test Funds

Once you have a node up and running the ledger should bootstrap from the network quickly, and then you just need some test network-specific Nano funds. We are currently working on a faucet setup to enable self-service options, but for now please reach out to argakiig#1783 on Discord or email [email protected] with the account number you would like funds distributed to for the test network.

What to build