Alexander Chepurnoy

The Web of Mind

On the Way to a Modular Cryptocurrency, Part 2: Stackable API

| Comments


The previous chapter, Generic Block Structure described how to split a blockchain-related core design of a cryptocurrency into two separate modules to wire concrete implementations in an application then.

A cryptocurrency core application provides some API for its user. In this chapter I will show how to split API implementation into pieces to wire it in an application then. The code is being used in the Scorex project, compact cryptocurrency core implementation for experiments.

Gluing Things Together

In the first place, some wrapper for Spray route is needed:

trait ApiRoute {
   val route: spray.routing.Route

Then an actor composing routes:

class CompositeHttpServiceActor(val routes: ApiRoute*) extends Actor with HttpService {

  override def actorRefFactory = context

  override def receive = runRoute( ~ _))

And then to create a new piece of API, instance of ApiRoute overriding route value is needed, see “Longer Example” in spray-routing documentation for example of a route definition(or Scorex Lagonaki sources, scorex.api.http package).

Then to glue all things together, we just create concrete actor implementation and bind it to a port. Example from Scorex Lagonaki:

lazy val routes = Seq(
  AddressApiRoute()(wallet, storedState),
  BlocksApiRoute()(blockchainImpl, wallet),

lazy val apiActor = actorSystem.actorOf(Props(classOf[CompositeHttpServiceActor], routes), "api")      

IO(Http) ! Http.Bind(apiActor, interface = "", port = settings.rpcPort)       

On the Way to a Modular Cryptocurrency, Part 1: Generic Block Structure

| Comments

The Protocols Mess Problem

In a code of a today’s cryptocurrency logical parts are very couply tied making codebase hard to understand and change. This series of articles shows how the problem could be solved by introducing separate inter-changeable injectable modules. Preliminary article “The Architecture Of A Cryptocurrency” describes possible modules in a cryptocurrency design.

This article, the first in the series describes how a block structure and a block-related functionality could be defined agnostic to implementation details of two separate modules, consensus-related and transaction-related. Code snippets using Scala language are provided. The code is being used in the Scorex project, compact cryptocurrency core implementation for experiments.

Generic Block Structure

A block consists of:

  1. Pointer to previous block
  2. Consensus-related data, e.g. nonce & difficulty target for Bitcoin, generation signature & base target for Nxt.
  3. Transactions, the most valuable part of a block for users. Some transactions- or state-related data could be also included(e.g. Merkle tree root hash for transactions or whole state after block application)
  4. Additional useful information: block structure version, timestamp etc
  5. Signature(s)

(Please note in Bitcoin there’s no a signature of a block, while we’re going to add it to make things more generic)

Making a new cryptocurrency usually means to replace (2) or (3) or both with something new. So to have an ability to make experiments fast we need to introduce some flexible and modular approach to a block structure and corresponding functions.

In the first place, we are going to introduce generic block field concept wrapping any kind of data with a possibility of serialization into json & binary form:

abstract class BlockField[T] {
  val name: String
  val value: T

  def json: JsObject
  def bytes: Array[Byte]

Then we can stack up blockfields into block, also introducing abstract ConsensusDataType & TransactionDataType types as well as abstract references to ConsensusModule & TransactionModule modules, where a module is a functional interface to be replaced with a concrete implementation then:

trait Block {
  type ConsensusDataType
  type TransactionDataType

  implicit val consensusModule: ConsensusModule[ConsensusDataType]
  implicit val transactionModule: TransactionModule[TransactionDataType]

  val consensusDataField: BlockField[ConsensusDataType]
  val transactionDataField: BlockField[TransactionDataType]

  val versionField: ByteBlockField
  val timestampField: LongBlockField
  val referenceField: BlockIdField
  val signerDataField: SignerDataBlockField

What both modules could have in common? Well, they are parsing data of a type they are parametrized with, producing a blockfield based on data and providing genesis block data details. Let’s extract this functionality into the common concept:

trait BlockProcessingModule[BlockPartDataType] {
   def parseBlockData(bytes: Array[Byte]): BlockField[BlockPartDataType]
   def formBlockData(data: BlockPartDataType): BlockField[BlockPartDataType]
   def genesisData: BlockField[BlockPartDataType]

Having this common ground, let’s define consensus and transaction interfaces.

Consensus Module

What can we do with consensus-related data from a block?

  • check whether a block is valid from module’s point of view, i.e. whether a block was generated by a right kind of participant in a right way

  • get block generator(s)(let’s not forget about multiple generators possibility, see e.g. Meni Rosenfeld’s Proof-of-Activity proposal

  • calculate block generators rewards

  • get a score of a block. Score equals to 1 in case of longest chain rule or some calculated value relative to difficulty in case of cumulative difficulty to be used to select best blockchain out of many possible options

Also, we can add a function to generate a block here, taking private key owner(to sign a block) and transaction module (to form transactional part of a block) as parameters

Considering all the functions, we can encode the interface now:

trait ConsensusModule[ConsensusBlockData] extends BlockProcessingModule[ConsensusBlockData]{
  def isValid[TT](block: Block, history: History, state: State)(implicit transactionModule: TransactionModule[TT]): Boolean
  def generators(block: Block): Seq[Account]
  def feesDistribution(block: Block): Map[Account, Long]        
  def blockScore(block: Block, history: History)(implicit transactionModule: TransactionModule[_]): BigInt
  def generateNextBlock[TT](account: PrivateKeyAccount)(implicit transactionModule: TransactionModule[TT]): Future[Option[Block]]

Transaction Module

We are going to consider a transactional part of a cryptocurrency, the most useful for an end user. An user isn’t using blockchain directly, querying some state instead:

  • There’s some initial state of the world stated in the first block of a chain( genesis block )
  • Then each block carries transactions which are atomic world state modifiers

Probably State monad could be helpful here, but for start(as we are rewriting existing project not using a true functional approach) the state interface is:

trait State {
  def processBlock(block: Block, reversal: Boolean): Unit

Please note no any querying functions are listed in the basic trait, as we are going to make state design stackable. For example, if it’s possible for a cryptocurrency to support balance querying for an arbitrary account following trait could be mixed with the basic one:

trait BalanceSheet {
  def balance(address: String, confirmations: Int): Long

to have a concrete interface to be implemented by a cryptocurrency like

trait LagonakiState extends State with BalanceSheet with AccountTransactionsHistory

In addition to state a history is to be stored as well(to send it to another peer for a reconstruction of a state, at least). Please note, history could be in a different form than the blockchain, for example, a blocktree could be explicitly stored, or blockchain with addition of block uncles as Ethereum does. I’m not going to provide History interface code here, but you can find it online.

So a transactional module contains references to concrete implementations of state and history, and few functions able to:

  • check whether a block is valid from module’s point of view(so whether all transactions within a block and transactions metadata e.g. Merkle tree root hash are valid)
  • extract transactions from a block
  • get transactions from unconfirmed pool and add corresponding metadata(on forming a new block)
  • clear duplicates from unconfirmed pool(on getting a block from the network)

The code reflecting requirements above is:

trait TransactionModule[TransactionBlockData] extends BlockProcessingModule[TransactionBlockData]{

  val state: State
  val history: History

  def isValid(block: Block): Boolean   
  def transactions(block: Block): Seq[Transaction]            
  def packUnconfirmed(): TransactionBlockData   
  def clearFromUnconfirmed(data: TransactionBlockData): Unit  

The Concrete Implementation

To develop a concrete blockchain-powered product a developer needs to provide concrete implementations of state, history, consensus & transactions modules to glue them together then in an application.

To see how that’s done in Scorex Lagonaki, take a look into LagonakiApplication.scala. While Scorex is the name of an abstract framework, Lagonaki is the name of concrete implementation wiring together:

  • SimpleTransactionModule operating with just a sequence of simplest token transfer transactions without any metadata
  • Two 100% Proof-of-Stake consensus module implementations, one is Nxt-like, other is Qora-like. It’s possible to replace one consensus algorithm with another with just a single setting in application.conf.

Further Work

The resulting application wiring together modules is much leaner than before. Some work could be done further though:

A Cryptocurrency Architecture

| Comments

Though we have thousands cryptocurrencies buzzing around at the moment, all of them share the same implementation design. Basically every cryptocurrency implementation has following parts:

  • Network Protocol
  • Consensus Protocol
  • Transaction Protocol
  • Internal State

Network Protocol

P2P network is the core of a cryptocurrency, and the core is following some network protocol. It is pretty simple usually. For example, p2p network of a cryptocurency could be implemented with asynchronous exchange of the following messages:

  • M1: Serialized unconfirmed transaction
  • M2: Serialized block
  • M3: Blockchain quality score request(e.g. height for the Bitcoin, cumulative difficulty for the NXT).
  • M4: Blockchain quality score response
  • M5: Get known peers request
  • M6: Get known peers response
  • M7: Request a block for a certain height(or with a certain parent)

The minimalistic set is pretty similar to Scorex message types. Bitcoin has more complicated protocol for sure( as well as NXT.

Let’s consider an example of a blockchain downloading with messages types given above if peer A knows only peer B and has genesis block only. So possible interaction of A and outer world where A -> (B, M2) means (peer A sends an instance of message kind M2 to peer B):

  1. A asks B for peers: A -> (B, M5)
  2. A asks B for a B’s blockchain height: A -> (B, M3)
  3. B replies for the first message with known peers C & D: B -> (A, M6)
  4. B replies for the second message with it’s height H(B): B -> (A, M4)
  5. A asks C for its blockchain height: A -> (C, M3)
  6. A asks D for its blockchain height: A -> (D, M3)
  7. C replies with its blockchain height H©: C -> (A, M4)
  8. D replies with its blockchain height H(D): D -> (A, M4)

So A have 3 known heights H(B), H©, H(D) and a bigger height means better chain(for a Proof-of-Work cryptocurrency), so A chooses peer with a best chain, e.g. D. Then it’s going to download a chain from D with a following cycle:

  1. A asks D for a block with height (2,3,…,H(D)): A -> (D, M7)
  2. D replies with a block requested serialized into a binary form: D -> (A, M2)

Any real trace is much more complicated than this example :)

Consensus Protocol

By using network protocol a node can download one chain or another or even multiple chains(as different peers can have different chains). Then the question is what is the canonical chain shared by majority, the right kind of history an user can rely on. Consensus protocol aims to solve the problem.

A node follow rules to determine canonical chain like these:

  1. Every block in a chain must be valid as well as its signature

  2. Every block must have a valid reference to its parent with first block having reference to a genesis block which is constant for an each node

  3. Every block must be generated by a party having a right to produce it

  4. From multiple chains, one having maximum score is the canonical. If few chains have the same score first seen or a random one could be chosen

Some notes about the rules:

  • Block validity fact could be changed with a new software release. Most known example of that is Bitcoin network splitting caused by 0.8 release

  • In proof-of-work cryptocurrencies a party has a right to generate block if hash of its contents
    conforms to some condition(its cheap to calculate a hash and compare it with some value while it’s hard to iterate over nonce bytes to find such a hash). In proof-of-stake cryptocurrencies a party has verifiable right to generate a block if some pseudo-random value hit is less than stake-dependent target. It’s harder to design safe Proof-of-Stake cryptocurrency, for example, majority of such currencies are vulnerable to grinding attack(Nxt is not).

  • In Bitcoin “longest chain rule” being applied while in Nxt there’s another blockchain score function called “cumulative difficulty”

  • More details on the Nxt algo:

Transaction Protocol

A block contains transactions. A transaction is the global state modifier. In simplest case it modifies balance sheet. As there’s no central party, each node need to have the same state as others(for the same block height). So each node executes all the transactions coming within blocks, and validity rules must be same for each network participant.

A transaction could be implemented in different ways depends on goals:

  • In Bitcoin, transaction has multiple inputs and outputs with a script attached to every pin.

  • Ethereum has two transaction types, contract creation and message call. See the Yellow Paper for details:

  • In Nxt, transaction has some money amount and attachments. There are some rules on attachments processing, e.g. some kind of attachment means plain or encrypted message while other means order on decentralized exchange. Such an implementation provides maximum performance for features but has own disadvantages(complicated code, hardforks on each software update).

Internal State

In Bitcoin node a can store no any state at all or use different formats for it, e.g. UTXO list or some indexes in addition. In contrast, Ethereum has state hash stored into each block, so each node must comply with state representation interface given in the Yellow Paper to check block validity. There’s also interesting proposal from Bill White(coming along with Coq theory) about using special kind of Merkle tree and storing its root into block for scalability’s sake: [;a=blob_plain;f=lightcrypto.pdf;hb=HEAD] (;a=blob_plain;f=lightcrypto.pdf;hb=HEAD).

The Protocols Mess Problem

The real problem of cryptocurrency development process is the mess of all the parts described above. The most known example, even simple change in software validation(so in Transaction Protocol) could causes

Phasing Transactions in Nxt Part 1: Introduction, Phasing-Safety

| Comments

Two-Phased Transactions are similar a bit to Bitcoin’s multisig transactions implementation in Nxt but different in many aspects as well.

Simplest example: Alice starts a Two-Phased transaction. In the first stage a transaction is included in a blockchain but it isn’t processed immediately and has the status of ‘pending’. For it to be processed, Bob has to complete the second phase of the transaction by approving it. This has to be done before the deadline set by Alice has elapsed.

Please note the biggest difference from Bitcoin’s multisig: phased transaction is going to be included into blockchain immediately.

Use cases

  • Bob approving a transaction of Alice
  • Shareholders voting whether to send another 1M Nxt to a marketing service or not
  • Multisig wallet protected from a hacker(think about BTER case etc) (needs Account Control)
  • Trustless escrows
  • Conditional or unconditional transaction happening in some certain moment in future


  • most types of transaction could be 2-phased (but not all, see “Phasing-Safe Transactions” section)!
  • different consensus types: M-of-N account consensus,shareholders voting with assets, currency holders voting with a Monetary System currency units
  • possible vote threshold setting(e.g. only accounts holding 100+ assets could vote)
  • whitelist of voters
  • transaction could be released only prior to finishHeight(or at the height exactly )

Consensus(Voting) models

  • None - synthetic mode, used for unconditional transaction execution at some height in future
  • By account - 1 account is 1 vote
  • By balance - 1 nqt is 1 vote
  • By asset - 1 qnt(asset’s quant, so non-divisible part) is 1 vote
  • By MS currency - 1 unit is 1 vote
  • By transaction - phasing transaction becomes approved if there are transactions in blockchain with hashes set in phasing transaction
  • By hash - another synthetic mode, used for pay-with-secret

Phasing-safe transactions

Not all transaction types are phaseable, so some of them couldn’t be phased at all. Some phasing transactions are phaseable but not phasing-safe, means they doesn’t make sense as phasing transactions(e.g. message could be phased, but you can read it immediately) or there’s a risk a transaction couldn’t be applied at finish height due to some changes in the outer world’s state. Following table shows phaseable & safe transaction types. Please note unsafe phasing transaction could be pretty safe in some practical case, but that’s not guaranteed by the core.

Transaction Type Is Phaseable ? Is Safe ?
Payment Yes Yes
Arbitrary Message Yes No
Alias Assignment Yes No
Alias Sell Yes No
Alias Buy Yes No
Alias Delete Yes No
Poll Creation Yes No
Vote Casting Yes No
Phasing Vote Casting Yes Yes
Hub Announcement Yes Yes
Account Info Yes Yes
Asset Issuance Yes Yes
Asset Transfer Yes Yes
Ask/Bid Order Placement Yes Yes
Order Cancellation Yes Yes
Dividend Payment Yes Yes
DGS Listing / Delisting Yes Yes
DGS Price Change Yes No
DGS Quantity Change Yes No
DGS Purchase Yes No
DGS Delivery Yes No
DGS Feedback Yes No
DGS Refund Yes No
Forging Balance Leasing Yes Yes
Tagged Data Upload No -
Tagged Data Extend No -

Voting System Guide for Developers & Experienced Users

| Comments

This blogpost describes voting system presented in NRS(Nxt Reference Software) 1.5 for application developers & experienced users. For simple use cases, wallet’s UI is self-explanatory and enough.


  • Different voting models supported: voting by account(1 account = 1 vote), balance(1 Nqt = 1 vote), asset balance(1 Qnt = 1 vote), or Monetary System token balance(1 currency unit = 1 vote)

  • Voting has finite predefined duration(finish block height, to say precisely)

  • Poll has minimum and maximum number of options to provide opinion for. E.g. choose from 2 to 5 options out of 8

  • Range is the vote parameter. E.g. give a rate from 0 to 10.

  • By combining number of options & range a lot of specific poll types could be done. E.g. binary poll is poll where range is from 0 to 1 (i.e. no or yes). UI can handles some ranges in such a meaningful way.

  • Anonymous voting ( ) is not implemented. It could be implemented with e.g. Blind signatures( but it’s not known how to implement that on top of the blockchain. So it seems an anonymous voting could be implemented by trusted 3rd party services only.


Voting models

Four voting models exist:

  • By account, 1 account = 1 Vote

  • By balance, 1 Nqt = 1 Vote (nqt, not nxt!)

  • By asset, 1 Asset Qnt = 1 Vote

  • By Monetary System token, 1 curency unit = 1 Vote

All the models could be enhanced by additional parameter, describing min balance in units(nqt/qnt/currency units).


Counting happens at the finish block height set during poll creation. And a vote being counted only if it satisfies poll parameters(min balance etc) at that finish height. Please note, a voter could vote with balance < min balance needed to vote(at height where vote has been sent), and that’s valid, but a vote will be counted only if balance >= threshold balance at poll finish height.

Mandatory Parameters

name - a poll’s title, no more than 100 characters

description - detailed poll description, no more than 1000 characters

options - possible options titles to choose from and give a rate to. Minimum one option, maximum 100.

votingModel - four possible values for by-account, by-balance, by-asset, by-token voting

finishHeight - block height in future poll is finishing and counting taking at. Minimum 1 block since inclusion height(so set current height + 2 at least), maximum 14*1440 blocks = 20160 blocks since inclusion height

minNumberOfOptions , maxNumberOfOptions - minimum and maximum number of options a voter can choose

minRangeValue , maxRangeValue - a vote’s value is within this range

minBalance - 0 by default. A vote is counted only if account balance @ finishing height (in nqts/qnts/MS tokens) >= minBalance. Mandatory for by-account voting (i.e. should be more than 0 in case of by-account voting)

minBalanceModel - used in by-account voting to distinguish which kind of units used for minbalance, nqt balance / assets / currency units. For last two options holdingId parameter is also required

Optional parameters

  • holdingId - for voting by assets or MS tokens, also used for minBalance in by-account voting


  • Voting by asset could be started by anyone, not just asset/currency issuer or even owner


  • Create poll

Use POST request to createPoll API call to create a new poll. Example with curl:

curl -d 'name=cryptos&description=rate+cryptos+you+like&finishHeight=300000&votingModel=1&minNumberOfOptions=1&maxNumberOfOptions=2&minRangeValue=-5&maxRangeValue=5&secretPhrase=very+secret+phrase&deadline=1000&feeNQT=1000000000&option00=nxt&option01=btc' http://localhost:6876/nxt?requestType=createPoll


name - mandatory - poll title, not longer than 100 chars

description - mandatory - detailed poll description, max 1000 chars

finishHeight - mandatory - height of block when voting will be finished i.e. counted(should be > current one)

votingModel - mandatory - by-asset, by-account, or by-balance. see corresponding numeric value below

minBalance - mandatory for by-account voting, optional for other types - min amount of money or assets to vote, in nxt or qnt. by default 0(if skipped)

minBalanceModel - mandatory for by-account voting - what kind of tokens to use for vote threshold, nqt/qnt/ms token. See below for possible field values.

minNumberOfOptions - mandatory - min number of options to choose

maxNumberOfOptions - mandatory - max number of options to choose

minRangeValue - mandatory - min vote value possible, no more than 100

maxRangeValue - mandatory - max vote value possible, no less than -100

holdingId - mandatory in case of by-asset voting, could be also usedin addition with minBalance in by-account voting - asset or ms token id in unsigned form

option00,option01,option02,option03,…option99 - titles of corresponding options, please note parameter is always with two digits, starting with 00

Use following numerical values to set voting model:

VotingModel.ACCOUNT = 0;
VotingModel.NQT = 1;
VotingModel.ASSET = 2;
VotingModel.CURRENCY = 3;   //MS Token

Use following numerical values to set voting minBalanceModel:

MinBalanceModel.NONE = 0;
MinBalanceModel.NQT = 1;
MinBalanceModel.ASSET = 2;
MinBalanceModel.CURRENCY = 3; //MS Token
  • Vote casting

Use POST request to castVote API call to send your vote to the NRS. Example:

curl -d 'poll=12528572507118413418&secretPhrase=secret+phrase&deadline=1000&feeNQT=100000000&vote00=1&vote00=0' http://localhost:6876/nxt?requestType=castVote

Parameters are pretty straightforward. Use poll’s transaction id as poll parameter value, use vote00..vote99 to provide weights for option00..option99 options.

Please note, poll should be included into the blockchain to vote on it.

  • Get poll data

Use GET request getPoll to get poll data, e.g.


could returns something like

{"minRangeValue":-5,"votingModel":1,"description":"rate cryptos you like","finished":false,"poll":"4555214309048629195","requestProcessingTime":1,"minNumberOfOptions":1,"minBalance":"0","accountRS":"NXT-DV37-DD8K-3Q74-8LE2W","name":"cryptos","options":["nxt","btc"],"finishHeight":300000,"maxNumberOfOptions":2,"minBalanceModel":1,"account":"7926777737834261541","maxRangeValue":5,"timestamp":45731391}
  • Get poll results

Use GET request getPollResult to get poll results, e.g.


example result:


“finished” value is false, so voting still happens!

The request accepts some interesting parameters: votingModel , holding , minBalance , minBalanceModel - you can play with these parameters to see how results could be different depending on polls' input parameters(with the same set of voters).

  • Get polls

Use POST request to getPolls :

curl -d 'account=7926777737834261541&firstIndex=0&lastIndex=5&includeFinished=true'  http://localhost:6876/nxt?requestType=getPolls

There’s additional includeFinished parameter(self-explanatory). If account=0, all limited by indexes polls in the chain (active only if includeFinished=false) will be returned.

  • Get vote(s) details

There’re two API calls to get vote details, getPollVote & getPollVotes . First one accepts poll & account parameters, while second accepts just poll (& firstIndex, lastIndex).

  • Search polls

Use searchPoll to find relevant polls by text query. Example query with all the four parameters possible.

curl -d ‘query=cryptos&firstIndex=0&lastIndex=5&includeFinished=true’ http://localhost:6876/nxt?requestType=searchPolls


If poll contains less than 20 options, fee for it’s creation is 10 Nxt, otherwise each additional option costs 1 Nxt as well.

Vote fee is 1 Nxt.


There’s only one setting at the moment which could be overriden in

# If disabled, polls are not processed at finish height and results are not stored in the database.
# When requested, poll results will be calculated on-the-fly, if the votes are still available.

Set the value to false if you run a lean node & don’t need for results of all the polls in the chain to be calculated & stored.

Use Cases & Application Ideas

Out of the scope of simple voting, there are a lot of possibilities Voting System provides:

  • Distributed shareholders meetings (using assets as voting rights)
  • Publicly verifiable community decisions (using e.g. Monetary System tokens as community currency)
  • Building consensus protocols on top of the blockchain with strong evidence of a consensus

  • (to be continued)

Internal details (for developers)

This section is for developers working with core, studying the NRS code, or writing apps working closely with the core(so using low-level Java API not HTTP, though that way isn’t recommended unless a developer knows why he’s doing that).


There are two kinds of attachments related to voting system: MessagingPollCreation & MessagingVoteCasting. Also please take a look PollBuilder helper implementing Builder pattern to create MessagingPollCreation objects:

val pb = new PollBuilder(question, desc, options, finishBlockHeight, votingModel,
      minNumberOfChoices, maxNumberOfChoices, minRangeValue, maxRangeValue) { mb =>
    minBalanceModelOpt match {
      case Some(minBalanceModel) => pb.minBalance(minBalanceModel, mb)
      case None => pb.minBalance(mb)
} => pb.holdingId(hi))


Transaction types

There are two transaction types related to VS: Messaging.POLL_CREATION and Messaging.VOTE_CASTING.

Getting data

Take a look to static methods of the Poll class to get data you want. E.g. getPoll(long id) returns poll by its id, getPollsByAccount returns polls created by an account specified etc.

Scorex - Ultracompact Cryptocurrency Engine for Hackers

| Comments


There are two huge problems around cryptocurrencies development project Scorex aims to help to solve:

  • Bitcoin source code contains more 100K lines of code(80K of C++ only), Nxt is about more than 45K line of Java code. All parts of the design(network/transactions/consensus layers) are mixed in a hard way. So researchers & developers are definitely not in a good start position to make any experiments. In opposite, Scorex is less than 4K lines of Scala code. Transactions layer is as simple as just tokens transfers. Consensus algo could be switched easily(with two consensus algos out of the box, one could be replaced with an another with just one line of code edited!)

  • Major coins forks are trying to make IPO immediately, often having just one or two pretty controversial features introduced. Scorex is intentionally not production-ready, so please participate in any non-commercial experiments built on top of it, but don’t buy tokens unless you are 100+% sure what are you doing.


  • Compact, functional, actors-powered code
  • Two 100% Proof-of-Stake consensus algos out of the box, Nxt-like and Qora-like. One algo could be replaced with an another with just one line of code edited (in Constants.scala)
  • Simplest transactions model
  • Asynchronous network layer on top of TCP
  • Command line client for the JSON API
  • Curve25519 for signatures


There are two releases planned at the moment:

Lagonaki - initial release aiming to provide modular and simple product for hackers.

Kizhi - another branch in development with proof-of-stake consensus algo allows contribution to multiple branches following our papers, along with Nothing-at-Stake attack script etc.


Lagonaki release is mostly ready, there are about 30 todos in code to get done though. We’ll fix them within next few weeks. Some documentation will be written as well. At this point it will be an announcement(this message is the pre-announcement).

Then we’ll test Nxt forging algo improvements proposals with it(a proposal document will be published within next few weeks). And then we’ll work on Kizhi.


Scorex is made by Consensus Research microteam previously worked on Proof-of-Stake investigation:

Alexander Chepurnoy aka kushti - Nxt developer & cofounder. Has few published papers in Computer Science field(finite state systems related), writing PHD at the moment.

andruiman - serial entrepreneur with theoretical physics background, big fan of Coq interactive theorem prover & functional programming.


We’re highly welcome contributions in form of pull requests, testing, issues reporting, and forking for sure :)


Also we would be happy to get donations. You can buy our asset on Nxt Assets Exchange:, Bitcoin wallet is 17YksFD7eRB4NhPfEtGrGnuvuwpkAeBd7f .

Repository URL

CAP Theorem and the Blockchain as the Database

| Comments

CAP Theorem

Before the NXT cryptocurrency I used to be a developer of a distributed system crawling articles around the Web and building Kohonen’s self-organizing map filled with them. During those days I read a lot about CAP theorem. The theorem states pretty common in everyday life principle “you can pick only two out of three” (e.g. in the “Price – Quality – Delivery” triangle). The three desirable options of any distributed system are consistency, system availability and tolerance to a partition fault. And you can pick only two of them.

CAP & Distributed Ledger - The Problem

In case of a distributed ledger CAP properties mean:

  • Consistency - all nodes have the same ledger at the same time
  • Availability - the network accepts transactions at any time
  • Partition tolerance - the network is resistant to a node(s) failure

The sad thing is that widely acceptable currency couldn’t exists without all the three conditions met. Nobody will use a currency if it’s offline during data synchronizations(CP system). Nobody will use a currency if network is vulnerable to a node failure(CA system). And for sure nobody will use currency if different nodes operate with different ledgers(PA system).

The Blockchain Solution

Blockchain is the elegant bypass of a CAP problem for storing a distributed(& decentralized) ledger. So transactions are grouped in blocks, and you can trust block only after some number of confirmations(i.e. number of new blocks added after). In case of Bitcoin, you can rely on transaction just included into the blockchain after 6 confirmations(with a negligible probability of transaction being reversed even after that), in many practical cases 2 or 3 confirmations are enough though (see original Nakamoto’s paper for precise numbers satisfy your needs).

So in terms of consistency the blockchain is about very weak consistency! Working with Riak and other databases with weak consistency, I’ve never seen anything like that.

Forging Simulation Tool for a Proof-of-Stake Cryptocurrency

| Comments


I’m the proud member of Consensus Research. Recently we published two executable simulations of forging(term for generating blocks activity in Proof-of-Stake). Multibranch forging simulation has the paper about it. I’m going to describe Nxt-like single-branch forging simulation tool in series of posts, some blogposts about multibranch will be published later also to give simplified description of the tool.

The Tool

The simulation tool is published on GitHub along with short description. Some internal details described in the Inside a Proof-of-Stake Cryptocurrency Part 4: The Executable Forging Simulation article. I don’t want to repeat myself here, so let’s take a closer look on how the tool works and what results it dumps out.

After launching the program it prints out “Starting cryptocurrency simulation…” then does its job silently and dumps out few results to the console when simulation is done:

Alt text

So it dumps out a balance of every node from it’s own balances sheet and common sub-chain length of a node with each other node. The screenshot above shows that most of nodes are agreeing on a chain with 121 or 122 blocks, while there’s a cluster of nodes having 130 blocks in common chain and one node stuck in fork at the moment of the end of an experiment with 116 common blocks.

A lot of detailed data goes into output folder, readme describes files going there.

Forging Quality

Forging quality seems to be worse than in real-world implementations e.g. Nxt mainnet blockchain: big forgers producing few blocks in a row more often(especially after connecting to a network with a genesis state), common chain is behind the current moment. I see some reasons for that:

  • in Nxt a node waits for blockchain to be downloaded then starts to forge, in simulation not
  • there are no latencies, clocks de-synchronization, also all processes are tied to the world clocks, so in case two nodes generate blocks at the same time a hard battle between forks has begun
  • Nxt Reference Software has some additional checks and patches not being presenting in the model

But our goal wasn’t to replicate Nxt forging and propagation processes, so it’s okay for now to have what we have.


Performance is bad at the moment. And I did not optimizations for the reason: for now understandability is much more important.

Simulating Different Models

Using the simulation tool a researcher can make experiments and get results quickly. For example, to change cumulative difficulty measure from sum of 1/baseTarget to sum of 1/(baseTarget^2) just one line modification needed:

cumulativeDifficulty chain = sum(map (\bl -> two64 / ((fromIntegral $ baseTarget bl)**2) ) chain)

And from first look things are getting worse after that.

Further Improvements

  • Better output, e.g. CSV format usage to work with results in Excel or statistics tools
  • Some aggregated metrics, e.g. number of forks living in a network, overall network consensus quality etc
  • Latency modelling
  • For now nodes stay online forever, better to model going offline at random moments
  • Better performance


  • We already using the mix of this tool with multibranch forging simulation to play with Nothing-at-Stake issues(a paper on that is ready and will be published soon)

  • We can make experiments very quickly (see “Simulating Different Models” section above)

  • As result, community can compare different forging models without long debates, e.g. compare Nxt & Qora forging, or see improvement proposals in action

Inside a Proof-of-Stake Cryptocurrency Part 4: The Executable Forging Simulation

| Comments


In first 3 parts Nxt-like 100% proof-of-stake forging algorithm was described. It would be exciting to run executable simulation of it to see network-wide consensus in action. And now this simulation tool is published! Please take a look to it’s README for details, and this article is about some aspects of the source code unrevealed yet.


All the code is split into three modules(files):

  • blockchain.hs, module Blockchain.Structures - basic structures and functions, building bricks for the simulated cryptocurrency network & its forging algorithm

  • simulation.hs, module Blockchain.Simulation - structures & functions related to simulation

  • launcher.hs. module Main - some auxiliary functions & main function running simulation and dumping results into files

Most of basic structures and functions were decscribed in first 3 parts of the series, so now we’re going to take a look into simulation functions.


The most important function in simulation module is systemTransform taking current state of a network along with timestamp and common data for the simulation and transforming it to resulting network state by applying some partial transformers:

systemTransform :: SimulationData -> Network -> Network
systemTransform sd network = networkForge sd $ generateTransactions sd $
            propagateLastBlock sd $ propagateTransactions sd $ downloadBlocksNetwork sd $
        dropConnections sd $ generateConnections sd $ addNode sd $ addInvestorNode sd network


  • addInvestorNode makes some initial investor online. Network starts with just one online investor out of 20, system balance is spread uniformly in a genesis block. Max number of investors online (14,000 seconds after genesis and on) are 13, means 65% forging power being online

  • addNode adds a node to the simulated network with no blockchain & empty account. The node needs to download a blockchain from other nodes.

  • generateConnections generates a connection for a node to another node if number of outgoing connection is less than a limit given in settings file(20 by default)

  • dropConnections works once per 60 seconds, drop oldest connection for a node, if number of outgoing connections equals to the limit

  • downloadBlocksNetwork selects random neighbour for each peer and check it’s cumulative difficulty, and if this metrics is better for the neighbour, the node is going to download a chunk of blockchain after common chain(14,400 blocks max)

  • propagateTransactions selects random neighbour for each peer and sends transactions from peer’s unconfirmed transactions pool a naighbour doesn’t have

  • propagateLastBlock selects nodes having last block generated by other node not more than 15 seconds ago and sends it out to a random neighbour

  • generateTransactions generates random transactions sending max 5% stake out(for account having more than 200 coins out of 1,000,000,000 issued)

  • networkForge asks each node whether it has a right to generate a block(by it’s own opinion) and if so generates blocks for forgers found and sends them out to random neighbours

Nothing-at-Stake simulation

By mixing multibranch forging simulation tool published previously with blockchain forging simulation tool described in the article it’s possible now to simulate Nothing-at-Stake attack, e.g. by mixing nodes doing blockchain forging with “attacker” doing multibranch forging. We’ll publish our work on that soon.

Conclusion & Further Work

Well, it’s the last article in the “Inside a Proof-of-Stake Cryptocurrency” series. All of them:

And executable code corresponding is on GitHub: Some modifications will be made, I want to replace all the constants with configurable parameters, at least. Performance optimization is also needed, for now it’s performance isn’t good for simplicity’s sake.

Inside a Proof-of-Stake Cryptocurrency Part 3: A Local Ledger

| Comments

Pre-Introduction: Consensus Research Group

After previous article I started to work with friend of mine, andruiman on deeper investigation of proof-of-stake. We are working now as Consensus Research group and have successful Phase 1 crowdfunding almost done.

We have published paper on multibranch forging, while I continue to describe a model of 100% Proof-of-Stake single-branch forging.


Cryptocurrency ledger lives in p2p network and as any information shared in AP distributed environment it’s a subject of inconsistency. So we will talk about local ledger as there’s no global ledger in a network though algorithms behind a cryptocurrency try to build some common view under some assumptions.

Local Ledger

In pt. 1 global network-wide structure System was defined slightly wrong for simplicity’s sake:

data System = System {
        nodes :: [Node],
        connections :: [Connection],
        accounts :: [Account]

For now this simplification becomes too rude, so we’re going to remove accounts and rename the structure to Network (connections definition also changed but just for performance’s sake)

data Network = Network {
    nodes :: [Node],
    connections :: Map Node [Node]

New field to be injected into node to store it’s local state is localView,

data Node =
    Node {
        localView :: LocalView,
        unconfirmedTxs :: [Transaction],
        account :: Account          -- simplification - one account per node
        isForging :: Bool

and consist of two entities:

data LocalView =
        nodeChain :: BlockChain,        -- simplification - one blockchain per node(but true for NRS)
        balances :: Map Account Int

The latter entity containing balances for known accounts isn’t strictly necessary but without it simple question “what’s the account balance now?” will need for whole local blockchain to be processed to answer.

To update balances during transaction processing we define ‘applyTx’ transformer function:

applyTx :: Transaction -> Map Account Int -> Map Account Int
applyTx tx blns = addMoney amt (recipient tx) $ addMoney (-amt) (sender tx) blns
    where amt = amount tx

where auxiliary function addMoney just adds some diff value to an account balance:

addMoney ::  Int -> Account ->  Map Account Int -> Map Account Int
addMoney diff acc blns = insert acc ((findWithDefault 0 acc blns) + diff) blns

To process a block, we process each transaction it contains then add sum of all transaction fees to a block generator balance:

processBlock :: Block -> Map Account Int -> Map Account Int
processBlock block priorBalances = appliedWithFees
        txs = transactions block
        txApplied = foldl (\bs tx -> applyTx tx bs) priorBalances txs
        fees = sum(map fee txs)
        appliedWithFees = addMoney fees (generator block) txApplied

A Local Ledger & The Network Consensus

In a proof-of-stake environment chance to generate block & incoming block check result are depend on a balance of an account. But information about balances is local, so all decisions are also made locally. E.g. If cluster of nodes have own view of network, they will reject blocks from other nodes and build own blockchain. Is that good or bad? Well, the question is open, as well as other consensus properties in proof-of-stake networks.

Further Work

Next chapter will be about building blocks of an executable simulation of Nxt-like single-branch forging. Sources of the simulation tool will be published the same time.