nano protocol

in #note-timknip6 years ago

https://github.com/alexbakker/gonano/blob/master/doc/protocol.md go语言实现nano,目前完成度不高,这是作者整理的nano protocol,还没仔细看,不知道更新到哪个版本的协议了

Nano Protocol

This document describes the network protocol used by the Nano cryptocurrency. It
is licensed under CC BY-SA.

At the time of writing, there is no official protocol documentation. As such,
the source code of the C++
implementation
, which is also
essentially undocumented, was studied to obtain information about the protocol.
Naming has been kept similar to the C++ implementation to avoid confusion.

Be sure to read and understand the whitepaper first:
https://nano.org/en/whitepaper. The basic concepts of Nano will not be covered
here.

Networking

Nano nodes use two internet protocols for communication, UDP and TCP.

UDP is used for ping packets, broadcasting new blocks and voting. Because ping
packets are sent regularly to other peers, hole punching will occur. Forwarding
a port for this is usually not necessary for clients.

TCP is used when large transfers need to occur. Examples of large transfers are
frontier and block transfers. Clients will usually not serve on this port,
unless they have their port forwarded.

Listeners for both of these protocols are assumed to be bound to the same port.
The default port is 7075.

Cryptographic primitives

Nano uses a number of cryptographic primitives to facilitate hashing and
signing.

For hashing, BLAKE2b is used.

For signing, a modified version of Ed25519 is used. It uses BLAKE2b as the
hashing algorithm instead of SHA-512.

Packets

The C++ implementation doesn't appear to take endianness into account. This
means that the encoding of integers is platform-dependent. The platforms that
Nano currently runs on are all little endian, so we'll assume that all integers
are encoded in little endian for now. The exception to this rule are balances,
those are encoded in big endian.

Every packet starts with a header.

LengthContents
1'R' encoded in ASCII
1Network ID encoded in ASCII
1uint8_t VersionMax
1uint8_t VersionMax
1uint8_t VersionMin
1uint8_t MessageType
2uint16_t Extensions

Network identifiers:

ValueName
ATest
BBeta
CLive

After the header, the message content follows.

Messages

There are a number of message types.

ValueNameUDPTCP
0x00Invalid
0x01Not a type
0x02Keep alive
0x03Publish
0x04Confirm Req
0x05Confirm ACK
0x06Bulk Pull
0x07Bulk Push
0x08Frontier Req
0x09Bulk Pull Blocks

Keep alive

Nodes send keep alive packets to eachother on a regular basis. This packet is
used to share a random selection of their peer list. It is also used as a ping
mechanism to make sure a node is still up and running.

LengthContents
?List of peers (up to 8)

A peer represented as an IPv6 address and a port.

LengthContents
16IPv6 address
2uint16_t Port

NOTE: The C++ implementation currently has a bug where it will do an out of
bounds read if less than 8 peers are in the packet. See also:
https://github.com/nanocurrency/raiblocks/issues/673. So for now, it's best to
always send 8 peers. If less than 8 peers are available, the rest of the list is
filled with unspecified ip's and zeroed ports.

In the C++ implementation the default interval is 60 seconds. After 5 minutes a
node is considered not alive anymore.

Publish

Publish packets are used to broadcast new blocks to nodes.

LengthContents
?Block

This packet contains a block. To learn more about what blocks look like, read
the Blocks chapter.

Confirm Req

When a node encounters a fork, it requests a vote using this packet type.

LengthContents
?Block

This packet contains a block. To learn more about what blocks look like, read
the Blocks chapter.

Confirm ACK

This packet represents a vote.

LengthContents
32Representative public key
64Signature
8uint64_t Sequence
?Block

Bulk Pull

LengthContents
32Public key of the account
32End block hash

When this packet is sent to a node, it will respond with a stream of blocks.

To indicate the end of a transmission, a block with type: "Not a type" is sent.

Bulk Push

?

Frontier Req

LengthContents
32Start public key
4uint32_t Age
4uint32_t Count

When this packet is sent to a node, it will respond with a stream of frontiers.

So, to retrieve all frontiers a node has, set the start public key to zero and
age and count to UINT32_MAX.

A frontier consists of the public key of an account and the newest block hash on
its chain.

LengthContents
32Account public key
32Newest block hash

To indicate the end of a transmission, a zeroed public key and block hash is
sent.

Bulk Pull Blocks

LengthContents
32Minimum block hash
32Maximum block hash
1uint8_t Mode
4uint32_t Count

There are two different modes.

ValueName
0x00List
0x01Checksum

Blocks

ValueName
0x00Invalid
0x01Not a type
0x02Send
0x03Receive
0x04Open
0x05Change
0x06State

Every block contains a proof of work value. Read the Work chapter to learn more
about it.

Blocks also have a 256-bit BLAKE2b hash associated with them. The way those are
calculated differs per block type.

Block signatures are calculated by signing the block hash with the account
public key.

Send

A send block is created to transfer funds to another account.

LengthContents
32Previous block hash
32Destination public key
16uint128_t Balance
64Signature
8uint64_t Work

The hash of this block is calculated by concatenating [Previous block hash,
Destination public key, Balance] and hashing the result with BLAKE2b.

Receive

A receive block is created to accept the transfer of funds that occurred in a
send block.

LengthContents
32Previous block hash
32Source block hash
64Signature
8uint64_t Work

The hash of this block is calculated by concatenating [Previous block hash,
Source block hash] and hashing the result with BLAKE2b.

Open

An open block is created to open an account.

LengthContents
32Source block hash
32Representative public key
32Account public key
64Signature
8uint64_t Work

The hash of this block is calculated by concatenating [Source block hash,
Representative public key, Account public key] and hashing the result with
BLAKE2b.

Change

A change block is created when an account wants to change its representative.

LengthContents
32Previous block hash
32Representative public key
64Signature
8uint64_t Work

The hash of this block is calculated by concatenating [Previous block hash,
Representative public key] and hashing the result with BLAKE2b.

State

State blocks (previously known as universal blocks) are meant to replace all
other block types.

LengthContents
32Account public key
32Previous block hash
32Representative public key
16uint128_t Balance
32Link
64Signature
8uint64_t Work

NOTE: For this block type, the work value is encoded in big endian.

The hash of this block is calculated by concatenating [Account public key,
Previous block hash, Representative public key, Balance, Link] and hashing the
result with BLAKE2b.

Work

To protect the network from spam, nodes need to perform some proof of work
before they can create a valid block.

A 64-bit counter and the previous block hash are concatenated and hashed using
BLAKE2b to create a 8-byte hash. If the resulting hash is below the threshold of
0xffffffc000000000, the counter is incremented and the process is repeated until
the threshold is exceeded.

Balance

Balances are represented as a 128-bit unsigned integer. They are encoded in big
endian.

Coin Marketplace

STEEM 0.26
TRX 0.11
JST 0.033
BTC 64359.90
ETH 3105.50
USDT 1.00
SBD 3.87