Skip to content
Snippets Groups Projects

WIP: RFC 5 : New Scalable Blockchain Protocol

Closed nanocryk requested to merge rfc5-duniter-protocol-rework into master
Compare and
1 file
+ 509
0
Compare changes
  • Side-by-side
  • Inline
+ 509
0
 
# #5 Duniter Protocol Rework for version 11
 
 
```txt
 
RFC: 5
 
Title: Duniter Protocol Rework for version 11
 
Type: Hard-fork
 
Status: WIP
 
Author: nanocryk <nanocryk@duniter.org>
 
Created: 2018-01-29
 
Last edited: 2018-01-30
 
License: AGPL-3
 
```
 
 
This document provide specifications of a reworked protocol for the Duniter project.
 
 
It aims to provide an efficient and strong base for future developments by taking the actual
 
protocol (version 10), simplifying it and adding usefull elements to increase performance and
 
extensibility.
 
 
## Summary
 
 
1. [Introduction](#1-introduction)
 
1. [Conventions](#2-conventions)
 
1. [General document format](#3-general-document-format)
 
1. [Identity document](#4-identity-document)
 
1. [Membership document](#5-membership-document)
 
1. [Certification document](#6-certification-document)
 
1. [Revocation document](#7-revocation-document)
 
1. [Transaction document](#8-transaction-document)
 
1. [Script system](#9-script-system)
 
1. Block document
 
 
## 1. Introduction
 
 
The Duniter software aims to provide *Universal Dividend*-based crypto-currency.
 
The name is made from `DU + unit + er`, as "*a tool for creating UD units*".
 
 
> *DU* stands for "Dividende Universel", "Universal Dividend" in french.
 
 
It's based on Stephane Laborde's [Relative Theory of Money] which aim to provide equality
 
to money creation between all users, in space [of users] and time.
 
 
The currency is based on a **blockchain** composed of **blocks**, linked together with
 
*cryptographic hashes*; containing *documents* for *transactions* and management of the
 
**Web of Trust** : a structure used to associate a human being with only one account, which is
 
needed to avoid a user to have multiple UD.
 
 
[Relative Theory of Money]: http://en.trm.creationmonetaire.info/
 
 
## 2. Conventions
 
 
### 2.1. Endianness
 
 
All data fields are big-endian unless otherwise specified.
 
 
### 2.2. Hashes
 
 
All *cryptographic hashes* are done with *SHA256* algorithm unless otherwise specified.
 
 
They are stored as raw bytes arrays and should be displayed in hexadecimal format.
 
 
### 2.3. Bases
 
 
Some specific data is stored or displayed using these bases :
 
 
- Base58 (for display) : Mainly used for keys, it avoids using close looking
 
characters and allow whole content selection with double-clicking.
 
 
The alphabet is `123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz`.
 
- Base64 (for display) : Data format used for non user-friendly data such as signatures.
 
 
The alphabet is `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`.
 
- Name64 (for storage) : Allow to store names in a more compact way that raw ASCII/UTF-8 text.
 
Each character is stored on 6bits, and remove any invalid characters.
 
 
The alphabet is `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-`.
 
 
### 2.4. Bytes alignments
 
 
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`.
 
 
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.
 
 
> Note that is says "might be" because the hash is not known in advence.
 
 
### 2.6. Dates
 
 
All dates are stored in [UNIX timestamp format][unix-timestamp], as the number of seconds
 
since 00:00:00 UTC on January 1, 1970. They are stored in a 64bit format to
 
avoid [year 2038 problem][year-2038-problem]. In this format the counter will overflow
 
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.
 
 
> `MedianTimeBlocks = 24` in Ǧ1 currency.
 
 
[unix-timestamp]: https://en.wikipedia.org/wiki/Unix_time
 
[year-2038-problem]: https://en.wikipedia.org/wiki/Unix_time#Representing_the_number
 
 
### 2.7. Keys
 
 
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
 
 
Public and private keys have this format :
 
 
| Size | Data |
 
|:----:|:-----|
 
| *4 bytes* | Checksum
 
| *2 bytes* | Cryptographic system (determine `size` of payload)
 
| *2 bytes* | Currency code
 
| *`size` bytes* | Payload
 
| *`4 - (size % 4)` bytes* | Padding
 
 
Depending of the context, `size` will be the size of the public or private key.
 
Private keys are never stored in the blockchain, but can be used in clients or other protocols.
 
 
For now only `Ed25519` is defined for type `0`, with
 
 
| Size | Data |
 
|:----:|:-----|
 
| *32 bytes* | Public key
 
| *64 bytes* | Private key
 
 
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 *SHA-256 hash* of all fields except the *checksum* 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 checksum is then the first 4 bytes of 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.
 
 
```txt
 
IdentityHash = SHA256(Username + CompactKey + Blockstamp)
 
```
 
 
> The `+` operation is a raw byte concatenation.
 
 
### 2.9. Currency values
 
 
TODO
 
 
## 3. General document format
 
 
Each *document* is composed of a **header**, a **payload** and one or more **signatures**.
 
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).
 
 
The *header* and *payload* are hashed to optain a **document ID**, then *signatures* are made
 
from it.
 
 
The header is composed of :
 
 
| Size | Data |
 
|:----:|:-----|
 
| *4 bytes* | Magic value : `0xDAE2D598`
 
| *2 bytes* | Currency code
 
| *2 bytes* | Document type
 
| *2 bytes* | Payload size in bytes
 
| *2 bytes* | Number of issuers
 
| ... | List of issuers *complete public keys* with alignement padding for each
 
| *1 byte* | Extension field size in bytes (0 to 255)
 
| ... | Extension field with alignement padding
 
 
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.
 
 
The document types are the following :
 
 
| Name | Code |
 
|:-----|:----:|
 
| Block | `0x00` |
 
| Transaction | `0x10` |
 
| Identity | `0x20` |
 
| Membership / Leaver | `0x21`/`0x22` |
 
| Certification | `0x23` |
 
| Revocation | `0x24` |
 
 
> The magic value has been choosed randomly and contains data with low probability to find
 
> in UTF-8 text.
 
 
## 4. Identity document
 
 
| Size | Data |
 
|:----:|:-----|
 
| *36 bytes* | HEAD blockstamp while creating this document |
 
| *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
 
 
| Size | Data |
 
|:----:|:-----|
 
| *36 bytes* | HEAD blockstamp while creating this document |
 
| *32 bytes* | Identity hash
 
| *3 bytes* | *(padding)*
 
 
If the document code is `0x21`, it's an opt-in.
 
 
If the document code is `0x22`, it's an opt-out.
 
 
## 6. Certification document
 
 
| Size | Data |
 
|:----:|:-----|
 
| *36 bytes* | HEAD blockstamp while creating this document |
 
| *32 bytes* | Target identity hash
 
 
## 7. Revocation document
 
 
| Size | Data |
 
|:----:|:-----|
 
| *4 bytes* | Filled with zeros
 
| *32 bytes* | Identity hash to revocate
 
 
To allow usage of *version 10* text-based revocation document, we have this
 
structure if the first field is different from 0 :
 
 
| Size | Data |
 
|:----:|:-----|
 
| *4 bytes* | Length of text (in characters)
 
| ... | 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
 
 
A **transaction document** describes the consumption of **sources** and the creation of
 
**outputs**. Since we're dealing with *Universal Dividends*, 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** system which will be
 
described below.
 
 
| Size | Data |
 
|:----:|:-----|
 
| *36 bytes* | HEAD blockstamp while creating this document
 
| *1 byte* | Number of UD inputs |
 
| *1 byte* | Number of unspent inputs |
 
| *1 byte* | Number of outputs |
 
| *1 byte* | *(padding)* |
 
|
 
| | **For each UD** : |
 
| *32 bytes* | UD creator identity hash |
 
| *36 bytes* | Blockstamp of UD creation |
 
|
 
| | **For each unspent input** : |
 
| *32 bytes* | Source transaction document hash |
 
| *1 byte* | Source output index |
 
| ... | *Unlock parameters (with alignement padding with `Nop` opcodes)* |
 
|
 
| | **For each output** : |
 
| *4 bytes* | Unsigned currency value |
 
| ... | *Lock script (with alignement padding with `Nop` opcodes)* |
 
 
## 9. Script system
 
 
> This system is heavily inspired by Bitcoin script system discribed
 
> [here](https://en.bitcoin.it/wiki/Script). It adds to it transaction data reflection
 
> (such as outputs, amounts); merkelized scripts and multiple cryptographic systems
 
> support.
 
 
The script system is simple, **stack-based** and processed from left to right. It is intentionnaly
 
**not Turing-complete, with no loops**.
 
 
A *transaction* is valid if nothing in the script triggers a failure and the stack contains
 
only one `true` value.
 
 
That stacks hold *byte vectors*. When used as numbers, byte vectors are interpreted as
 
**big-endian variable-length integers** with two's complement fir sign handling. 0 can also be
 
represented by a null-length vector. Byte vectors are interpreted as *booleans* where `false`
 
is represented by 0 and `true` by any other value.
 
 
A **main stack** and **alt stack** are available and empty by default. The executed script is
 
the concatenation of the *unlock parameters* and the *lock script*. Thus the
 
*unlock paramters* is a script putting data onto the stack which will be popped by the *lock script*.
 
 
> We'll refeer to the **main stack** as **the stack** and precise **alt stack** when necessary.
 
 
### Opcodes
 
 
| Opcode | Hex | Word | Input | Output | Description |
 
|:------:|:---:|:-----|:------|:-------|:------------|
 
| | | | | | **Constants**
 
| `0` | `0x00` | `C0`, `Zero`, `False` | *none* | *empty value* | An empty array is pushed on the stack.
 
| `1-75` | `0x01-0x4b` | `PushData1-PushData75` | *special* | *data* | The next *opcode* bytes is data to be pushed on the stack.
 
| `76` | `0x4c` | `PushData1B` | *special* | *data* | The next byte contains the number of bytes to be pushed on the stack.
 
| `77` | `0x4d` | `PushData2B` | *special* | *data* | The next two bytes contains the number of bytes to be pushed on the stack.
 
| `78` | `0x4e` | `PushData4B` | *special* | *data* | The next four bytes contains the number of bytes to be pushed on the stack.
 
| `80` | `0x50` | `CN1`, `NegOne`| *nothing* | `-1` | The number -1 is pushed onto the stack.
 
| `81` | `0x51` | `C1`, `One`, `True` | *nothing* | `1` | The number 1 is pushed onto the stack.
 
| `82-96` | `0x52-0x60` | `C2-C16` | *nothing* | `2-16` | The number in the word name (2-16) is pushed onto the stack.
 
|
 
| | | | | | **Flow control**
 
| `97` | `0x61` | `Nop` | *nothing* | *nothing* | Does nothing.
 
| `98` | `0x62` | `If` | `condition` | *nothing* | If the top stack value (`condition`) is not `false`, opcodes until an `Else` or `Fi` are executed, otherwise they are ignored. The top stack value is always removed.
 
| `99` | `0x63` | `IfNot` | `condition` | *nothing* | If the top stack value (`condition`) is `false`, opcodes until an `Else` or `Fi` are executed, otherwise they are ignored. The top stack value is always removed.
 
| `100` | `0x64` | `Else` | *nothing* | *nothing* | If the preceding `If`/`IfNot` was not executed then opcodes until a `Fi` are executed, otherwise they are ignored.
 
| `101` | `0x65` | `Fi` | *nothing* | *nothing* | Ends an if/else block. All blocks must end, or the transaction is **invalid**. A `Fi` without `If`/`IfNot` earlier is also not valid.
 
| `102` | `0x66` | `Assert`/`Verify` | `true`/`false` | *nothing* / *panic* | **Marks transaction as invalid** if top stack value in not `true`. The top stack value is removed.
 
| `103` | `0x67` | `Panic`/`Return` | *nothing* | *panic* | **Marks transaction as invalid.**
 
|
 
| | | | | | **Stack**
 
| `104` | `0x68` | `ToAltStack` | `xn .. x2 x1 x0 <n>` | `(alt) x0 x1 x2 .. xn` | Puts the `n` items on top of the main stack onto the top of the alt stack, one by one. Removes them from the main stack.
 
| `105` | `0x69` | `FromAltStack` | `(alt) xn .. x2 x1 x0 (main) <n>` | `x0 x1 x2 .. xn` | Puts the `n` items on top of the alt stack onto the top of the main stack, one by one. Removes them from the alt stack.
 
| `106` | `0x6a` | `Depth` | *nothing* | `<stack size>` | Puts the number of stack items onto the stack.
 
| `107` | `0x6b` | `IfDup` | `x` | `x`/`x x` | If the stop stack value is not `0`, duplicate it.
 
| `108` | `0x6c` | `Drop` | `x` | *nothing* | Removes the top stack item.
 
| `109` | `0x6d` | `Dup` | `x` | `x x` | Duplicate the top stack item.
 
| `110` | `0x6e` | `Nip` | `x1 x2` | `x2` | Removes the second-to-top stack item.
 
| `111` | `0x6f` | `Over` | `x1 x2` | `x1 x2 x1` | Copies the second-to-top stack item to the top.
 
| `112` | `0x70` | `Pick` | `xn ... x2 x1 x0 <n>` | `xn .. x2 x1 x0 xn` | The item `n` back in the stack is copied to the top.
 
| `113` | `0x71` | `Roll` | `xn ... x2 x1 x0 <n>` | `.. x2 x1 x0 xn` | The item `n` back in the stack is moved to the top.
 
| `114` | `0x71` | `Rot` | `x1 x2 x3` | `x2 x3 x1` | The top three item on the stack are rotated to the left.
 
| `115` | `0x72` | `Swap` | `x1 x2` | `x2 x1` | The top two items on the stack are swapped.
 
| `116` | `0x73` | `Tuck` | `x1 x2` | `x2 x1 x2` | The item at the top of the stack is copied and inserted before the second-to-top item.
 
| `117` | `0x74` | `Drop2` | `x1 x2` | *nothing* | Removes the top two stack items.
 
| `118` | `0x75` | `Dup2` | `x1 x2` | `x1 x2 x1 x2` | Duplicates the top two stack items.
 
| `119` | `0x76` | `Dup3` | `x1 x2 x3` | `x1 x2 x3 x1 x2 x3` | Duplicates the top three stack items.
 
| `120` | `0x77` | `Over2` | `x1 x2 x3 x4` | `x1 x2 x3 x4 x1 x2` | Copies the pair of items two spaces back in the stack to the front.
 
| `121` | `0x78` | `Rot2` | `x1 x2 x3 x4 x5 x6` | `x3 x4 x5 x6 x1 x2` | The fifth and sixth items back are moved to the top of the stack.
 
| `122` | `0x79` | `Swap2` | `x1 x2 x3 x4` | `x3 x4 x1 x2` | Swaps the top two pairs of items.
 
| `123` | `0x7a` | `IsEmpty` | `in` | `true`/`false` | Returns 1 if the top of the stack in a zero-length vector. It consumes the input, so if it needs to be used it should be duplicated first.
 
|
 
| | | | | | **Bitwise Logic**
 
| `128` | `0x80` | `Invert` | `in` | `out` | Flips all of the bits in the input.
 
| `129` | `0x81` | `BitAnd` | `x1 x2` | `out` | Bolean *and* between each bit in the inputs.
 
| `130` | `0x82` | `BitOr` | `x1 x2` | `out` | Bolean *or* between each bit in the inputs.
 
| `131` | `0x83` | `BitXor` | `x1 x2` | `out` | Bolean *exclusive or* between each bit in the inputs.
 
| `132` | `0x84` | `BitEqual` | `x1 x2` | `true`/`false` | Return 1 if the inputs are exactly equal, 0 otherwise.
 
|
 
| | | | | | **Arithmetic**
 
| | | | | | *Arithmetic inputs are limited to signed 64-bit integers, but may overflow their output.*
 
| `144` | `0x90` | `Add1` | `in` | `out` | 1 is added to the input.
 
| `145` | `0x91` | `Sub1` | `in` | `out` | 1 is subtracted from the input.
 
| `146` | `0x92` | `Negate` | `in` | `out` | The sign of the input is flipped.
 
| `147` | `0x93` | `Abs` | `in` | `out` | The input is made positive.
 
| `148` | `0x94` | `Not` | `in` | `out` | If the input is 0 or 1, it is flipped. Otherwise the output will be 0.
 
| `149` | `0x95` | `Not0` | `in` | `out` | Returns 0 if the input is 0, 1 otherwise.
 
| `150` | `0x96` | `Add` | `a b` | `out` | a is added to b.
 
| `151` | `0x97` | `Sub` | `a b` | `out` | b is subtracted from a.
 
| `152` | `0x98` | `And` | `a b` | `out` | If both a and b are not 0, the output is 1, otherwise 0.
 
| `153` | `0x99` | `Or` | `a b` | `out` | If a or b in not 0, the output is 1, otherwise 0.
 
| `154` | `0x9a` | `NumEqual` | `a b` | `out` | Returns 1 if numbers are equal, otherwise 0.
 
| `155` | `0x9b` | `NumNotEqual` | `a b` | `out` | Returns 1 if numbers are not equal, otherwise 0.
 
| `156` | `0x9c` | `NumLessThan` | `a b` | `out` | Returns 1 if a is less than b, 0 otherwise.
 
| `157` | `0x9d` | `NumGreaterThan` | `a b` | `out` | Returns 1 if a is greater than b, 0 otherwise.
 
| `158` | `0x9e` | `NumLessThanOrEqual` | `a b` | `out` | Returns 1 if a is less than or equal to b, 0 otherwise.
 
| `159` | `0x9f` | `NumGreaterThanOrEqual` | `a b` | `out` | Returns 1 if a is greater than or equal to b, 0 otherwise.
 
| `160` | `0xa0` | `Min` | `a b` | `out` | Returns the smaller of a and b.
 
| `161` | `0xa1` | `Max` | `a b` | `out` | Returns the larger of a and b.
 
| `162` | `0xa2` | `Within` | `x min max` | `out` | Returns 1 if x is within the specified range (left-inclusive), 0 otherwise.
 
| `163` | `0xa3` | `Sum` | `xn .. x2 x1 x0 <n>` | `out` | Returns the sum of the `n` top values from the stack.
 
|||||| ***Arithmetic operations on currency values (takes account of the base) :***
 
| `164` | `0xa4` | `CurrencyEqual` | `a b` | `out` | Returns 1 if numbers are equal, otherwise 0.
 
| `165` | `0xa5` | `CurrencyNotEqual` | `a b` | `out` | Returns 1 if numbers are not equal, otherwise 0.
 
| `166` | `0xa6` | `CurrencyLessThan` | `a b` | `out` | Returns 1 if a is less than b, 0 otherwise.
 
| `167` | `0xa7` | `CurrencyGreaterThan` | `a b` | `out` | Returns 1 if a is greater than b, 0 otherwise.
 
| `168` | `0xa8` | `CurrencyLessThanOrEqual` | `a b` | `out` | Returns 1 if a is less than or equal to b, 0 otherwise.
 
| `169` | `0xa9` | `CurrencyGreaterThanOrEqual` | `a b` | `out` | Returns 1 if a is greater than or equal to b, 0 otherwise.
 
| `170` | `0xaa` | `CurrencyMin` | `a b` | `out` | Returns the smaller of a and b.
 
| `171` | `0xab` | `CurrencyMax` | `a b` | `out` | Returns the larger of a and b.
 
| `172` | `0xac` | `CurrencyWithin` | `x min max` | `out` | Returns 1 if x is within the specified range (left-inclusive), 0 otherwise.
 
| `173` | `0xad` | `CurrencySum` | `xn .. x2 x1 x0 <n>` | `out` | Returns the sum of the `n` top values from the stack.
 
|
 
| | | | | | **Crypto**
 
| `176` | `0xb0` | `Hash` | `value algo` | `hash` | The input is hashed using `algo` hashing algorithm. The list of algorithms is available below.
 
| `177` | `0xb1` | `CheckSig` | `sig pubkey` | `true`/`false` | The signature must be a valid signaure for the hash of this (the spending) transaction and public key. If it is, 1 is returned, 0 otherwise.
 
| `178` | `0xb2` | `CheckSigHash` | `sig pubkey compactkey` | `true`/`false` | Same as `CheckSig`, but `compactkey` must correspond to `pubkey`. With this opcode `pubkey` can be provided only at spending, thus protecting it for cryptographic attacks.
 
| `179` | `0xb3` | `CheckMultiSig` | `sig1 sig2 ... pub1 pub2 ... <count>` | valid sig count | Verify each pair `(sign, pubn)`, return the sumber of valid transactions.
 
| `180` | `0xb4` | `CheckMultiSigHash` | `sig1 sig2 ... pub1 pub2 ... compact1 compact2 <count>` | valid sig count | Combinaison of `CheckSigHash` and `CheckMultiSig`.
 
| `181` | `0xb5` | `Eval` | `script hash` | *special* | Evaluate `script` as if it was in-place. The script must have a Merkle Root equals to `hash`. If not, **transaction is invalid**. If the script *panic* (says the transaction is invalid), the **transaction is invalid**. The script hashing algorithm is described later in this document.
 
| `182` | `0xb6` | `Unused` | `hash` | *empty value (false)* | Returns an empty value. The hash of this instruction is the provided hash. It allow to only provide hashes of unused code when using `Eval` opcode.
 
|
 
| | | | | | **Data fetching**
 
| `192` | `0xc0` | `FetchSourceSigTime` | *nothing* | `timestamp blockid` | Returns the timestamp and blockid corresponding to the blockstamp of the source transaction document (signature time). One of the 2 dates can be discarded with `Drop` or `Nip` opcodes.
 
| `193` | `0xc1` | `FetchSourceBlockTime` | *nothing* | `timestamp blockid` | Returns the timestamp and blockid corresponding to the block in which the source transaction document appears. One of the 2 dates can be discarded with `Drop` or `Nip` opcodes.
 
| `194` | `0xc2` | `FetchTargetSigTime` | *nothing* | `timestamp blockid` | Returns the timestamp and blockid corresponding to the blockstamp of the spending transaction document (signature time). One of the 2 dates can be discarded with `Drop` or `Nip` opcodes. It can be used to prevent using a source based on the date of the spending transaction.
 
| `195` | `0xc3` | `FetchTargetBlockTime` | *nothing* | `timestamp blockid` | Returns the timestamp and blockid corresponding to the block in which the spending transaction document appears. One of the 2 dates can be discarded with `Drop` or `Nip` opcodes. It can be used to prevent using a source based on the date of the spending transaction.
 
| `196` | `0xc4` | `FetchDeltaSigTime` | *nothing* | `delta_timestamp delta_blockid` | Returns the difference of timestamp and blockid between the signature time of the source and spending transaction. One of the 2 durations can be discarded with `Drop` or `Nip` opcodes. It can be used to prevent using a source based on the duration before spending.
 
| `197` | `0xc5` | `FetchDeltaBlockTime` | *nothing* | `delta_timestamp delta_blockid` | eturns the difference of timestamp and blockid between the block in which the spending transaction document appears and the spending transaction.One of the 2 durations can be discarded with `Drop` or `Nip` opcodes. It can be used to prevent using a source based on the duration before spending.
 
| `198` | `0xc6` | `FetchOutputAmount` | `output_index` | `amount base`/*empty* *empty* | Returns the amount spent by a specific output. Returns an empty value if this index is out of bound.
 
| `199` | `0xc7` | `FetchOutputScriptHash` | `output_index` | `script_hash`/*empty* | Returns the script hash of a specific output. Returns an empty value if this index is out of bound. It can be used to force specific conditions for an output.
 
 
Any undefined operators return the value `1` and doesn't mark the transaction as invalid.
 
If use before a `Assert`/`Verify` opcode, they won't mark the transaction as invalid easer.
 
Changing them to new opcodes will only restrict the set of valid transactions and outdated client will never see new opcodes as invalid.
 
With this setup it allow adding new backward-compatible features.
 
 
### Hashing algorithms list
 
 
| Code | Name |
 
|:----:|:-----|
 
| `0` | SHA-256
 
 
### Eval script hashing
 
 
TODO
 
 
### Script examples
 
 
To simplify our scripts examples, we write constants as `<data>` fields, and the stack push
 
is implied.
 
 
#### Classic pay-to-pubkey script
 
 
```txt
 
Script : <pubkey> CheckSig
 
Parameters : <sig>
 
```
 
 
Here is a step by step execution of the script
 
 
| Stack | Script | Description |
 
|:------|:-------|:------------|
 
| | `<sig> <pubkey> CheckSig` | Script and parameters are merged.
 
| `<sig> <pubkey>` | `CheckSig` | Data is pushed on the stack.
 
| `true` | | Signature is checked from top two stack items.
 
 
There is only `true` in the stack, so this transaction is valid.
 
 
#### Pay-to-compact-key script
 
 
```txt
 
Script : <compact key> CheckSigHash
 
Parameters : <sig> <pubkey>
 
```
 
 
#### 2-of-3-multisig script
 
 
```txt
 
Script : <compact1> <compact2> <compact3> 3 CheckMultiSigHash 2 NumGreaterThanEqual
 
Parameters : <sig1> <empty> <sig3> <pubkey1> <empty> <pubkey3>
 
```
 
 
### Allow usage of V10 outputs
 
 
To allow spending of transaction in V10 format, we must find a way to translate
 
the old scripts in this new format and have the exact same behavior. When a node see a V10
 
source, it convert its V10 script into a V11, and execute it. It means that we spend a V10
 
script with V11 parameters, and a client also need to do this translation to know in which
 
order add data onto the stack. Note that in the new format, it will be required to
 
duplicate a parameter if it's used multiple times.
 
 
| V10 script | V11 script | V10 parameters | V11 parameters
 
|:-----------|:------------|:---------------|:----
 
| `SIG(pubkey)` | `<pubkey> CheckSig` | `SIG(sig_index)` | `<signature>`
 
| `XHX(sha256_hash)` | `1 Hash <sha256_hash> BitEqual` | `XHX(pass)` | `<pass>`
 
| `CLVT(timestamp)` | `FetchSourceBlockTime Drop <timestamp> NumGreaterThanOrEqual` | *nothing* | *nothing*
 
| `CSV(delay)` | `FetchDeltaBlockTime Drop <delay> NumGreaterThanOrEqual` | *nothing* | *nothing*
 
|
 
| `{X} AND {Y}` | `{X} 1 ToAltStack {Y} 1 FromAltStack Add 2 NumEqual` | `{X} {Y}` | `{Y} {X}`
 
| `{X} OR {Y}` | `{X} 1 ToAltStack {Y} 1 FromAltStack Add 1 NumGreaterThanOrEqual` | `{X} {Y}` | `{Y} {X}`
 
 
> TODO : Need peer reviewing since it's a critical part of this protocol change.
Loading