Skip to main content


Any changes you want to make in the state of the blockchain can be done using transactions. There are two main types of transactions: registration transaction and generic (financial) transaction (sending token from one wallet to another). In the future, more types of transactions will be added.

UrlRequest TypeDescription of parameters
/api/tx/newPOSTInput parameters: {"tx": " ... packed and signed transaction ... "} Response: {"txid": "153B7614F8051F79-3RGPJnQuajxy1r9zj5Jb9JUr4skE-6BC2"} - transaction identifier
/api/tx/status/{txid}GETInput parameters: {txid} - transaction identifier you've received from the call /api/tx/new Response: {"Res": null} - the transaction has not yet included into the block (no information yet) {"Res": {"ok": true}} - the transaction has included into the block

Example of sending a transaction using curl (the transaction body has been shortened):

~ curl -d '{"tx":"g6R0eXBlo … 2MjI4X8TfA5gc"}'

2. Dive into transaction format

In order to make a new transaction, you should send an HTTP POST request to the server. Request data should be in JSON format and contain the key 'tx' with base64-encoded transaction container.

Example banner

The transaction container is a MessagePack fixmap (first byte 0x80 - 0x8f) with the following structure:

"body": BinaryBody (binary),
"sig": Array (array of binary),
"ver": 2 (unsigned integer)

The keys of this fixmap should be encoded as a string.

The value of the 'body' is a MessagePack binary (0xc4 the first byte) with MessagePack encoded transaction payload (we referring it as a transaction body).

The transaction body is a MessagePack map (0xde, 0x80-0x8f) with one mandatory key 'k' which value indicates transaction kind and other keys depending on transaction purpose.

For the best extendability transaction kind number is unique for each kind with each transaction version. Headers with constants should be generated by scripts from supplied JSON file (priv/tx_const.json):

"purpose": {
"0": "transfer",
"1": "srcfee",
"2": "dstfee",
"3": "gas"
"kind": {
"16": ["generic", 2],
"17": ["register", 2],
"18": ["deploy", 2],
"19": ["patch", 2],
"20": ["block", 2]

The value of the 'sig' key is MessagePack array (types 0x90-0x9f or 0xdc-0xdc). Each array item contains signature for one key. Signature format (BSig) described below. A transaction might have multiple signatures.

The value of the 'ver' key is an integer, which indicates a version of transaction format to specify which body decoder should be used. As for now it has to be 2 (0x02 in MessagePack).

3. Registration Transaction

For registration of a new wallet there is the 'register' transaction type. As we mentioned before, the transaction body is MessagePack map (or fixmap) type. The first byte of this type is the 0xDE or from a range 0x80-0x8F.

Example banner

Here is an example of registration transaction body content (shown as json, binary data represented as base64-encoded strings):

"k": 0x11,
"t": 1530106891372,
"nonce": "T1umkWY=",
"h": "Y6dVG5CvZacwlbf21oybiIHh/4h+8d2EJwF7Qp/GpCA=",
"e": {}

The value of the 'k' key should always be 0x11 for registration transactions (MessagePack positive fixint type, 0x11).

The value of the 't' key is a transaction creation timestamp (unixtime in milliseconds, MessagePack uint 64 type, 0xcf).

The value of the 'nonce' key can be any type and should be used to change the transaction hash (see comment about difficulty below).

The value of the 'h' key is sha256 hash of concatenated public keys sorted ascending (MessagePack binary type, 0xc4).

The value of the 'e' key is user defined extra data included into transaction (MessagePack map or fixmap type, 0xde, 0x80-0x8f).

4. Example of calculating the value of the 'h' key

Let's take 3 arbitrary public keys (shown as json array, binary data represented as hex string):


Please note, keys should be represented as binary data (i.e. for string 02 you should take 0x02 byte of binary data).

After sorting the keys we'll get the following order:


After concatenation step we'll get the following data:


The next step is calculating the sha256 hash of this data. Please note, we should deal with binary data (i.e. string E7 in the example should be byte 0xE7 of binary data). We calculate the hash of binary data, NOT the string of ASCII symbols.

For the data in this example the sha256 hash is


5. PoW difficulty of the registration transaction

In order to prevent mass wallets registration, we require a PoW calculation for every registration transaction. In our case, the PoW means you should change the transaction data to get a sha512 hash which meets special requirements. These requirements usually called difficulty.

You can get the current difficulty of the shard by API call (GET) /api/settings. By this API call you'll get a JSON object. The value of the key settings.current.register.diff is the difficulty of this shard.

For example, if difficulty was 16 you should get a sha265 hash of the transaction with 16 leading bits of 0 (i.e. two leading bytes should be equal to 0). You should change the value of the 'nonce' key of the registration transaction to get a hash with 16 leading 0 bits.

Please note, the hash of the transaction body doesn't put in the transaction itself. In order to check if transaction meets the difficulty requirements or not, server recalculates the sha512 hash of the transaction body. As mentioned before, you should change the value of the 'nonce' key to get the transaction data with sha512 hash containing 'difficulty' of leading bits equal to 0.

Let's take the following transaction body (shown as JSON, binary value of the 'h' key shown as hex-encoded string):

"k": 17,
"t": 1541067579755,
"nonce": 0,
"h": "957216f45873f7d09466610b887f1634359b000820bc91119e0efea70d2de64d"

Here is the hex dump of the MessagePack-encoded transaction body:


The sha512 hash of this transaction body is


The first byte of the hash is 0x38 or 00111000 in binary format. This means the difficulty of preparation for this transaction body is 2 (hash has 2 leading 0 bits).

In case we changed the value of the 'nonce' key the hash of the transaction body would change.

Here is the same transaction but we've changed the value of the 'nonce' key to 210 (shown as JSON, binary value of the 'h' key shown as hex-encoded string):

"k": 17,
"t": 1541067579755,
"nonce": 210,
"h": "957216f45873f7d09466610b887f1634359b000820bc91119e0efea70d2de64d"

Here is the hex dump of the MessagePack-encoded transaction body:


The sha512 hash of this transaction body is


The binary representation of the first two bytes of that hash is

00000000  00010100
0x00 0x14

As you can see, this hash has 11 leading 0 bits, so the difficulty of preparation for this transaction body is 11.

6. BSig container and signature format

The BSig container is a binary data of TLV format (Tag - Length - Value).

Example banner

Each signature may contain additional data, which is signed with main payload (body, data for sign).

Here are predefined fields.


The public key is mandatory. Every BSig should contain the public key tag.

Let's look at the signing procedure by an example.

Let's pretend that we have the private key 0102030405060708090001020304050607080900010203040506070809000102 and we want to sign the string 'Hello, world!'.

First of all we need to calculate public key, for this private key it'd be 02B1912FABA80FCECD2A64C574FEFE422C61106001EC588AF1BD9D7548B81064CB.

Also, we put the current timestamp into container.

Here is the binary data we have at this step:

02 21 02B1912FABA80FCECD2A64C574FEFE422C61106001EC588AF1BD9D7548B81064CB
01 08 00000164B250D800
tag 0x02 (public key), length of data 0x21, public key data
tag 0x01 (timestamp), length of data 0x08, current unixtime as microseconds in unsigned int 64 format

The next step is appending of data for signing to binary from the previous step.

# tag 0x02 (public key), length of data 0x21, public key data
02 21 02B1912FABA80FCECD2A64C574FEFE422C61106001EC588AF1BD9D7548B81064CB

# tag 0x01 (timestamp), length of data 0x08, current unixtime as microseconds in unsigned int 64 format
01 08 00000164B250D800

# 'Hello, world!' string added to the end of BSig container

Here is the resulting binary for sign (shown as hexdump):


The sha256 hash of this whole binary will be 60C3B88A5F32816F574C8FABFB45A35338A20D7C1678F20DABDBBD7F94568F15.

At the next step we calculate signature of the hash from the previous step. The signature is


Please note, we always deal with binary data. You should sign the binary data of hash (NOT it's ASCII characters representation).

At the next step, we should remove the payload which we appended to container and prepend the container with the signature tag.

FF 46 304402205250D827749F285CE174137EC88B394092E43B9E6C6774045EE5E6ED5023225202204D1628F019E57BF19C1A0FE37193355A059F22CF8203D85E112FF3B4873D46FE
02 21 02B1912FABA80FCECD2A64C574FEFE422C61106001EC588AF1BD9D7548B81064CB
01 08 00000164B250D800
tag 0xFF (signature), length of data 0x46, binary data of signature (NOT it's ASCII)
tag 0x02 (public key), length of data 0x21, binary data of public key (NOT it's ASCII)
tag 0x01 (timestamp), length of data 0x08, current unixtime as microseconds in unsigned int 64 format

7. Generic transactions

Token transfer and/or smart contract call.

Token transfer and smart contract calling transactions must contain the following mandatory keys:

f (from)source address, must be 8 byte binary (0xc4 MessagePack type)
to (to)destination address, must be 8 byte binary (0xc4)
s (seq)tx nonce, must be positive integer (0x00 - 0x7f or 0xcc - 0xcf)
t (timestamp)tx unixtime in milliseconds, positive integer (0x00 - 0x7f or 0xcc - 0xcf)
p (payload)array of amounts (see below, 0xdc or 0x90 - 0x9f)

Also, there is a couple of optional keys:

c (call)for transaction intended to call smartcontract method. This attribute should contain 2 element array (0x92), the first element is the method name (string), the second is an array of arguments (arbitrary types, but tx call with incorrect types will be dropped by smart contract)
e (extradata)map with arbitrary extra data which might be used by smart contract or wallet application. The key 'code' is reserved for 'deploy' method and should not be used for any other purposes (types 0x80 - 0x8f or 0xde - 0xdf). In order to place some text or comment to transaction it's recommended to use the key with the name 'msg'

Attribute 'p' (payload) is an array of 3 element arrays (0x93).

Here is an example of payload (shown as JSON format):

[purpose, "currency name", amount],
[purpose, "currency name", amount],
[0x00, "SK", 10],
[0x01, "SK", 3]

The first element is purpose (positive fixint, 0x00 - 0x7f) from JSON shown before.

The second element is the currency name (binary, 0xc4). If the currency name contains only ASCII characters with codes 32-126 you also can use the string type (0xa0 - 0xbf).

The third element is amount (integer, 0x00 - 0x7f, 0xcc - 0xcf). This field MUST be only the integer type. You CAN NOT use here the float type or any other type.

In case this array contains more than 3 elements, all extra elements should be ignored (it might be array generated by software with a newer version of the protocol, for example).

Clients MUST NOT add extra fields to payload array when creating a transaction, because it might break compatibility with new versions.

Here is an example of whole transaction (218 bytes, shown as base64 encoded binary):


The same transaction shown as hex dump:

# 83 = fixmap of 3 elements

# body
a4 626f6479 c45087a16b10a166c4088000200002000003a2746fc408800020

# sig
a3 736967 91c476ff473045022052a6c53d04cded72c2beee500551d80e88

# ver
37 66572 02

The transaction container is a MessagePack fixmap (shown as JSON-like format, binary data shown as hex dump):



"ver": 2

Here is the transaction body with comments:

c450   # binary, length 0x50 bytes
87 # fixmap of 7 elements

# a1 = fixstr of 1 symbol, 6b = 'k' (this is the map key name), the value is 0x10

# a1 = fixstr of 1 symbol, 66 = 'f', c408 = binary of 8 bytes,
# the value is 8000200002000003 (encoded AA010000003355443516 wallet address)

# a2 = fixstr of 2 symbols, 746f = 'to', c408 = binary of 8 bytes,
# the value is 8000200002000005 (encoded AA010000003355443737 wallet address)

# a1 = fixstr of 1 symbol, 73 = 's', cf = uint64,
# 0005798a2e4c1930 = 1541009272740144 = 2018-10-31 18:07:52.740144

# a1 = fixstr of 1 symbol, 74 = 't', cf = uint64,
# 00000166cb4f6fa4 = 1541009272740 = 2018-10-31 18:07:52.740

# a1 = fixstr of 1 symbol, 70 = 'p', 92 = fixarray of 2 elements

# 93 = fixarray of 3 elements, 00 = 0 (transfer), a2 = fixstr of 2 symbols,
# 534b = 'SK', 11 = 0x11 = 17 (amount)

# 93 = fixarray of 3 elements, 01 = 1 (srcfee), a3 = fixstr of 3 symbols,
# 464545 = 'FEE', 03 = 3 (amount)

# a1 = fixstr of 1 symbol, 65 = 'e', 81 = fixmap of 1 element

# a3 = fixstr of 3 symbols, 6d7367 = 'msg'

# a5 = fixstr of 5 symbols, 68656c6c6f = 'hello'

Here is the sig value with comments:

# 91 = fixarray of 1 element

# c476 = binary of 0x76 bytes

# below this point goes bsig

# ff47 = signature, length 0x47 bytes ( = 71 in decimal)

# 71 bytes of signature

# 0221 = public key, length 0x21 bytes ( = 33 in decimal)

# 33 bytes of public key

# 0108 = timestamp, length 8 bytes,
# 00000166cb4f6fa4 = 1541009272740 = 2018-10-31 18:07:52.740