Whitepaper

NxtFi: Smart Contract Decentralized Platform

Version: 1.0 (draft)

Abstract. A decentralized system that provides a unique combination of features: no proof of work required (uses proof of authority achieved through encryption keys instead), best in class encryption algorithms, fast smart-contracts and transactions (many blocks per minute), endless possibilities through smart-contracts, managed through a cryptographic authority hierarchy (similar to web SSL certificates), no fees.

1. Introduction

Since the first proposal of the blockchain technology by Satoshi Nakamoto, the rate of adoption has been increasing exponentially non stop, many forks and different alternatives now exist, yet a specific use case required a unique implementation that instead of reinventing the wheel, takes the best of all the existing ones and integrates them in a simplified way to provide all the functionality without the downsides of proof of work, slow processing times, or unpredictable fees.

2. Blockchain

Essential to any blockchain is the use of a height number that is the count of blocks that exist in the chain, and hashes that represent the unique fingerprint of each block. Including the previous block’s hash in the content of every new block before calculating the new hash of the current block, ensures the integrity of the chain.

3. Proof-of-Authority

Every block includes a digital signature, generated using the private key of the entity creating the block, and a human-readable unique identifier with the name of the entity.

The network will use the identifier to verify that the public key exists (and has not been revoked) and check the signature of the block against it before processing the block itself.

4. Authority Tree

Every day, internet browsers work using an authority tree that guarantees that every website traffic travels encrypted over the network and the website that is served to your screen is really managed by the true owner of the website.

For this to work, all internet browsers include a set of “Root Authorities” that allow for decentralized issuance and management of all the public and private keys to do all the signing and encryption necessary for a secure internet.

In the same way, this blockchain starts with one “Root Authority”, that is capable of generating all the rest of the infrastructure required for this system to work at a blockchain level with the same level of trust and security.

5. Scopes

Every block must specify a scope attribute, this provides the separation of concerns required for smart contracts to work securely in a sandboxed and isolated way.

By default every public key has a scope for that key and has write access to it.

Every smart contract has a scope for the block’s hash and has write access to it.

Scopes are managed through the grantWrite and revokeWrite functions.

6. Network

All nodes are Peers and connect to each other using a mesh architecture, connection to at least two other random nodes suffices to ensure network synchronization.

a. Heart beat

Every 5 seconds, every node sends a ping request (with a unique pingId) to all the nodes connected to it.

Every time a ping request is received by a node, the same ping request is broadcasted to the nodes connected to it, and a pong response (including the pingId and the node’s nodeId) is sent to the node that sent it.

Every time a pong is received, the pingId is used to determine the latency that exists between that node, the maximum value of all the calculated latencies is the MAX_LATENCY.

b. MAX_LATENCY

MAX_LATENCY is the maximum amount of time required for any node to broadcast a new block to all the other nodes on the network.

Tests and simulations show that MAX_LATENCY averages around ~3 seconds regardless of the size of the mesh if each node connects to at least two other nodes.

Nodes that have average network latency higher than 10 seconds are considered unhealthy.

c. New blocks

When a node adds and broadcasts a new block, it must wait MAX_LATENCY seconds, before adding a new one.

For each scope there will be a single node that can write to the blockchain.

d. Blocks conflicts

If a new block with the same height is received by the node that is trying to add a new block before MAX_LATENCY seconds, the conflict is resolved as follows:

  • If the blocks have different scope:

    A new block with the same content but new hash and rootHash values is rebased on top of the new chain HEAD block and broadcasted.

  • If the blocks have the same scope:

    The block is rejected, and the block creator receives an error response, so that he can send a revalidated and rebased block.

e. Block broadcasting

Each time a new block is received and the verifications (hash and signature) are correct, it is immediately broadcasted to all the nodes connected to it.

f. Block synchronization

If a new block with the same height as the last block is received before the double of the MAX_LATENCY time has transcurred, the conflict is resolved as follows:

  • If the hash of the new block received is lower or equal than the hash of the current block

    • Ignore the new block.

  • If the hash of the new block received is higher than current block:

    • Rollback the current block and accept the new one.

7. Incentive

The network nodes are created and maintained by its entities actors and users, the incentive is not inherently provided by the network through rewards or payments, the funding and resources required for it to work are left to be provided by the beneficiaries of the chain functionality and smart-contracts.

8. Reclaiming Disk Space

A node can choose to skip the storage of the content of blocks that don’t belong to specific scopes it is interested in.

The node can keep being part of the network as a peer to re-transmit the blocks to other peers, but not store total content of the blocks it is not interested in, reclaiming disk space.

All nodes can request any block to other peers, if a block is requested but the content was not stored locally it can relay the request to another peer recursively until a peer that is interested in that same scope (or stores all scopes) has the block and can provide it.

9. Block formatting and schema

All the block attributes are organized in a JSON object as follows:

a. Example block

{
    "prevHash":"b3bae8163a1ead8cca911480cdfed2cfbc363e27420197dda1574da8eba282ec",
    "height": 27820,
    "version": 1,
    "data": "// IMPORT 60a8531eb2230e8c86231e9edf49209ea1feff16\ncreate: {\n  \"code\": \"i007\",\n  \"item\": \"cl1fj4icm00000vl5qgrjr56a\","id\": \"cl1fjdwyb00000wmjv2tu9msa\"\n}",
    "timestamp": 1648763783229,
    "signature": "haSTv9odYjdYljEYOUI5Q6mGXTjdMpXVZlc0myj+Jv+ibkT8m8vtkGlekjs5rCOzbAOoYJukioZjFzYvJaEqc4EF+UpdY9JqSgvCo/XA9Gy1OX1WIHxOqmIxXKkjUxGsopfzqQ+VKJGEMbALwJS9dcqXDgAUPA+1OeVuTcKbDsvEARESxwi66oq8MTW6uEqPfmw0mfK1E1A1cD4dyJp1Jq0Ri1A2iJ8NjoVT3DlpONHFjrr2AhAECXbeZHP4CgzQ64wnvzVXf8Q==",
    "by": "MUSEUM/GALLERY", 
    "scope": "MUSEUM",
    "rootPrevHash": "b3bae8163a1ead8cca911480cdfed2cfbc363e27420197dda1574da8eba282ec",
    "rootHeight": 304589,
    "hash": "453ced9c70c1aa8dd01d4144d174f0c2f9e0e0103c6f8f2181393dfcbf13ed4c"
}

b. Block attributes table

AttributeDescriptionType

prevHash

Hash of the previous block [scope]

string

height

Height of the block [scope]

number

data

Content of the block

string

timestamp

Number of milliseconds since the ECMAScript epoch

number

by

Signer of the block

string

scope

Scope of the block

string

signature

RSA-PSS signature of the object:

{ prevHash, height, version, data, timestamp, by, scope }

string

rootPrevHash

Hash of the previous block [root]

string

rootHeight

Height of the block [root]

number

hash

SHA-256 digest result of the block

string

10. Smart Contracts

Blocks that have a body attribute that start with ‘//’ characters are considered smart-contracts and are executed inside a Javascript sandbox.

Limited functionality is provided in the sandbox depending of the version parameter of the block.

Every smart contract must include a line stating the place where the importer’s code must be placed inside the contract.

// BODY

Optionally can also be specified with the keywords // INPUT and // INPUT END, as an example:

var input =
// INPUT
{
    to: "",
    amount: 0,
};
// INPUT END

a. Smart contracts

Smart contracts are used by importing them with the line:

// IMPORT <HASH_SMART_CONTRACT>

b. Smart contracts embedded functions:

FunctionDescription

put({ name: string, scope: string, value: string })

Key/Value storage

get({ name: string, scope: string })

Key/Value storage

list({ prefix: string, scope: string, limit: int, skip: int })

List existing keys

del({name: string, scope: string })

Delete any key

delMany({prefix: string, scope: string})

Delete all keys that match

All functions are scoped by the scope attribute of the block, if the block wants to read data from a different scope, the name of the element must start with “/” and include the full scope before the name of the value it wants to read.

c. Basic Storage Functionality

All basic storage is accessed through the get and put functions, allowing the smart contract to store information in a.n easily accessible manner, the value can be of type, it will be stringified before writing it to the storage, the getObject and putObject to the same but the value must be of type Object.

d. REST API Integration

Smart Contracts that make use of the database functionality, automatically serve as bridge between the web and the information in the chain.

By specifying the smart-contract hash in the url, the schema is defined by that block is used as proxy so the data can be accessed through a simple GET request

11. Keys and permissions

One central component of the chain is the key and permissions management.

A block must contain a signature generated using a private key that is then verified using the corresponding public key that should already exist in the chain.

If the public key is not found or the signature is invalid, the block is automatically rejected and is not propagated to the network, the entity who introduced the invalid block is rate-limited using exponential backoff.

Keys are structured as a tree with different levels, each key can have multiple subkeys (leafs), each subkey can have subkeys itself (if permissions allow it), and so on.

LEVEL 1LEVEL 2LEVEL 3...

ROOT

MUSEUM

MUSEUM/RECEPTION1

MUSEUM/GALLERY

MUSEUM/GALLERY/PRESSURE_IOT

Key management embedded functions

FunctionDescription

grantKey({ name: string, pubKey: string, permissions: permissionsObject })

Key Creation

revokeKey({ name: string, pubKey: string, permissions: permissionsObject })

Key Revocation

  • name new key’s name (must be prefixed with the name of the signing key), only the ROOT key can grant a new key without prefix.

  • pubKey string parameter must have been exported using SPKI standard and follow the PEM format:

`-----BEGIN PUBLIC KEY-----\n${exportedAsBase64}\n-----END PUBLIC KEY-----`
  • permissionsObject must follow the schema:

V1
{
    canGrant: Boolean,
    maxGrantLevels: Number (optional),
    expiration: milliseconds from ECMAScript epoch (optional)
}
  • canGrant is Boolean that defines if the key can grant sub-keys

  • expiration defines the expiration date of the key

12. Write permissions and Scopes

Each new key by default has write access to the scope with the same name as the key. To allow new keys to write to higher or completely different scopes, a key with admin permissions to that scope must grant permission to it.

Write permissions management functions

FunctionDescription

grantWrite({ scope: string, name: string permissions: permissionsObjectArray })

Write permission grants

revokeWrite({ scope: string, name: string permissions: permissionsObjectArray })

Write permission revocations

  • name of the key

  • permissionsObjectArray must follow the schema:

V1
[{
    recursive: boolean,
    admin: boolean
}]
  • recursive defines if all subscopes are also included.

  • admin defines if the key can give similar permissions to other keys.

Last updated