Skip to content
Snippets Groups Projects

WIP: RFC 5 : New Scalable Blockchain Protocol

Closed nanocryk requested to merge rfc5-duniter-protocol-rework into master
1 file
+ 90
42
Compare changes
  • Side-by-side
  • Inline
@@ -17,9 +17,6 @@ It aims to provide an efficient and strong base for future developments by takin
protocol (version 10), simplifying it and adding usefull elements to increase performance and
extensibility.
This document will be written as a set of chapters covering all protocol details, even existing ones.
If this RFC is accepted, this document could be used as documentation with no or small changes.
## Summary
1. [Introduction](#1-introduction)
@@ -79,18 +76,19 @@ Some specific data is stored or displayed using these bases :
### 2.4. Bytes alignments
Data should be aligned in 4 bytes blocks to improve memory speed.
Large values should be aligned, small values packed together to form 4 bytes
blocks and padding be used if alignement is not directly possible.
Data should be aligned in 4 bytes blocks to improve memory speed and layout.
Large values should be aligned, small values packed together to form *multiple of 4* bytes
blocks and padding used if alignement is not directly possible.
### 2.5. Block identifiers
Each block is indexed by its **block ID** stored as a *4 bytes unsigned integer*.
The ***genesis block*** *ID* is `0`, and each following block have a *block ID* incremented by `1`.
The ***genesis block*** *ID* is `0`, and each following block have a *block ID* incremented
by `1`.
To refeer a *block*, we use it's **blockstamp** made of its *block ID* and its *hash*. The *blockstamp*
of the genesis block *might be* `0-883228A23F8A75B342E912DF439738450AE94F5D` and the *blockstamp*
of block `443` *might be* `433-FB11681FC1B3E36C9B7A74F4DDE2D07EC2637957`.
To refeer a *block*, we use it's **blockstamp** made of its *block ID* and its *hash*.
The *blockstamp* of the genesis block *might be* `0-883228A23F8A75B342E912DF439738450AE94F5D`
and the *blockstamp* of block `443` *might be* `433-FB11681FC1B3E36C9B7A74F4DDE2D07EC2637957`.
Since hashes are stored on 32 bytes, a *blockstamp* is stored on a 36 bytes value.
@@ -106,8 +104,9 @@ in approximately 293 billion years.
Durations are expressed in eleapsed time between 2 *timestamps*.
Another way to provide dates is to reference a *blockstamp*.
Dates in the *blockchain* are calculated as the average time provided in a window of `MedianTimeBlocks` blocks.
It should be preferred to use *blockstamps* since its independent of any external influences.
Dates in the *blockchain* are calculated as the average time provided in a window of
`MedianTimeBlocks` blocks. It should be preferred to use *blockstamps* since its independent
of any external influences.
> `MedianTimeBlocks = 24` in Ǧ1 currency.
@@ -116,8 +115,12 @@ It should be preferred to use *blockstamps* since its independent of any externa
### 2.7. Keys
The new key format allow user to choose which *cryptographic system* he wants to use.
Currently only Ed25519 is supported, but others like [Schnorr signature] could be added.
In the current protocol public keys are raw data expressed in Base58 format.
We propose a new key format allowing the user to choose which *cryptographic system* he wants
to use. It also allow to desambiguate keys between currencies and store a checksum for error
detection. Currently only Ed25519 is supported, but others like [Schnorr signature] could
be added.
[Schnorr signature]: https://en.wikipedia.org/wiki/Schnorr_signature
@@ -145,14 +148,16 @@ The whole *blob* above is then formated in Base58 and displayed to the user.
> With this format it will be very unlikely someone send to an unwanted address.
The complete *checksum* (hash of all other fields) of a *public key* is known as a **compact public key** (or **compact key**)
and can be used to designate any public key in a fixed size value.
When a *complete public key* is used, it can be hashed and compared with the *compact key*.
The complete *checksum* (hash of all other fields) of a *public key* is known as a
**compact public key** (or **compact key**) and can be used to designate any public key in
a fixed size value. When a *complete public key* is used, it can be hashed and compared with
the *compact key*.
### 2.8. Identities
Each identity can be referred as its **identity hash** (or **indentity UID**) computed from the username,
the hash of its associated *compact key* and the *blockstamp* of the identity creation document.
Each identity can be referred as its **identity hash** (or **indentity UID**) computed from
the username, the hash of its associated *compact key* and the *blockstamp* of the identity
creation document.
```txt
IdentityHash = SHA256(Username + CompactKey + Blockstamp)
@@ -166,11 +171,13 @@ Each *document* is composed of a **header**, a **payload** and one or more **sig
The tuple `(magic value, currency code, document type)` is used for network propagation,
but is ellided when written into a block since they can be deduced from block data and context.
An **extention field** is provided to allow future protocol extensions without modifying this document
structure. It can contain any data but should have some sort of standard format to target specific extensions.
This format is not yet defined and will be in a future RFC, for now this extension field should be empty (size of 0).
An **extention field** is provided to allow future protocol extensions without modifying this
document structure. It can contain any data but should have some sort of standard format to
target specific extensions. This format is not yet defined and will be in a future RFC, for
now this extension field should be empty (size of 0).
The *header* and *payload* are hashed to optain a **document ID**, then *signatures* are made from it.
The *header* and *payload* are hashed to optain a **document ID**, then *signatures* are made
from it.
The header is composed of :
@@ -188,8 +195,8 @@ The header is composed of :
Payload and each signatures have alignement padding.
Cryptographic systems of signatures are not provided and matching public key types are used.
A document is valid if each public key can match a signature (with 0 bytes left and no overflows)
and each signature is valid for the document content and the public key.
A document is valid if each public key can match a signature (with 0 bytes left and no
overflows) and each signature is valid for the document content and the public key.
The document types are the following :
@@ -203,47 +210,88 @@ The document types are the following :
| Revocation | `0x23` |
| RevocationV10 | `0x24` |
> The magic value has been choosed randomly and contains data with low probability to find in UTF-8 text.
> The magic value has been choosed randomly and contains data with low probability to find
> in UTF-8 text.
>
> ### Need review
>
> Blockstamp has been removed from common header, and is now included only in documents
> needing a "non-block-insertion-time" date.
>
> For exemple, a transaction document don't seems to make use of this blockstamp. In the script, it can target
> a fixed date with a timestamp, and a relative date based on the transaction insertion or another date.
> With this primitives it should be possible to express any time requirements, so a document blockstamp
> seems unnecessary.
> For exemple, a transaction document don't seems to make use of this blockstamp. In the
> script, it can target a fixed date with a timestamp, and a relative date based on the
> transaction insertion or another date.
> With this primitives it should be possible to express any time requirements, so a document
> blockstamp seems unnecessary.
## 4. Identity document
TODO
| Size | Data |
|:----:|:-----|
| *36 bytes* | Identity document creation blockstamp |
| *1 byte* | Username length (1 to 127) |
| ... | Username in *Name64* format *(with alignement padding)*
Username must not be used in any *identity document* present in the blockchain : active or
revoked. We could also take account of *identity documents* in the pool, but since
pools have no consensus, it can't be ensured by the network.
Identity *validy frames* will be computed from the given blockstamp wich is at most the last
blockstamp at time of signature. It prevent someone to create an identity "in the future" and
allow to have duration calculation based on *signature time* and not *block insertion time*.
These validy frames are currency parameters and will be describes in more details further in
this document.
This document must only have one issuer. With this one issuer *public key* we can compute
its *compact key* and with the *username* and the *blockstamp* we can compute its
*identity hash*.
## 5. Membership document
TODO
| Size | Data |
|:----:|:-----|
| *36 bytes* | Membership document creation blockstamp |
| *32 bytes* | Identity hash
| *1 byte* | `0x00` for `OUT` / `0xFF` for `IN`
| *3 bytes* | *(padding)*
## 6. Certification document
TODO
| Size | Data |
|:----:|:-----|
| *36 bytes* | Certification document creation blockstamp |
| *32 bytes* | Target identity hash
## 7. Revocation document
TODO
| Size | Data |
|:----:|:-----|
| *4 bytes* | Filled with zeros
| *32 bytes* | Identity hash to revokate
## 8. Transaction document
To allow usage of *version 10* text-based revocation document, we have this
structure if the first field is different from 0 :
TODO
| Size | Data |
|:----:|:-----|
| *4 bytes* | Length of text
| ... | V10 Revocation document text *(with alignement padding)*
In this case, there must no issuers and signatures, since they are contained in
the text document.
## 8. Transaction document
### 8.1. Document structure
A **transaction document** describes the consumption of **sources** and the creation of **outputs**.
Since we're dealing with *Universal Dividend*s, it's possible to provide a list of UDs to spend.
Each source or UD can be spent only once, and the **sum of *inputs* values must equal the sum of *output* values**.
A **transaction document** describes the consumption of **sources** and the creation of
**outputs**. Since we're dealing with *Universal Dividend*s, it's possible to provide a list
of UDs to spend. Each source or UD can be spent only once, and the
**sum of *inputs* values must equal the sum of *output* values**.
Each *output* describes spending conditions using a **script**. This *script* is defined as an
**Abstract Syntaxic Tree** of operations which returns a boolean : can this output be used as an input of a new transaction.
This format will be describe further in this document.
Each *output* describes spending conditions using a **script**. This *script* is defined as
an **Abstract Syntaxic Tree** of operations which returns a boolean : can this output be used
as an input of a new transaction. This format will be describe further in this document.
### 8.X Script system
Loading