Funds transferring in the Cellframe Networks is performed using transactions inputs and outputs.

  • Input is a transaction item which contains funds entering in transaction.
  • Output is also a transaction item which contains funds from the inputs of the same transaction, ready to be transferred to the input of the subsequent transaction or wallet.

So, the transfer transaction just connects some inputs with corresponding outputs.

Let’s consider an example: a regular funds transfer.

Simple Transfer Example

We want to transfer 500 CELL from the WALLET #1 to the WALLET #2.

We know that our balance is higher than 500 CELL, so we just use Node Command - TX_CREATE to provide transfer.

How does it work?

The system collects free outputs of your wallet to get 500 CELL. Why?

Note

The balance of the wallet in Cellframe is not just a one number, it is a sum of all free unspent outputs.

When a transaction is being created, the system checks the sum of all your free outputs and if it is enough, the input on the corresponding sum will be created in this transaction.

Free unspent output is a single funds input on the wallet, which hasn’t been used (spent) yet. They also called free because they are not locked.

How to see free unspent outputs of the wallet? Use Node Command - WALLET OUTPUTS.

This can be seen on the picture below. But this case is quite simple, because the sum from UNSPENT OUT #1 и UNSPENT OUT #2 purely matches 500. But in case if the sum was higher than 500, an another output will be created in the transfer transaction, which will transfer the rest of the sum back to the wallet. This case is considered below.

This principle is applied to transactions too, because one transaction can have many inputs, so the final sum (on the output) can be collected from two or more inputs if they are not enough particularly.

So there is one rule:

Important

The total sum of the all inputs must match the total sum of the all outputs in a transaction.

Then, the funds from the input is distributed between two outputs: OUT #1 and COND OUT #2.

OUT #1 - 499.95 CELL is the sum being transferred to the WALLET #2 COND OUT #2 - 0.05 CELL is the validator fee which is sent to reward transaction

To get a proper sum of tokens being transferred, count in a validator fee.

When the transaction is successfully validated, the sum from the output OUT #1 will be sent on the new UNSPENT OUT #3 of the WALLET #3. And every time, when some funds income to the wallet, there will be created corresponding UNSPENT OUT for it.

The 0.05 CELL from the COND OUT #2 will be sent later on the COND IN of another transaction where the validator will collect all rewards. This is how the validator commissions work.

Let’s consider a more complicated example.

Service Payment Example

In this example, we will show how the service payment is designed in Cellframe.

We have a 500 CELL on the WALLET #1. And we want to use a service (for example, VPN service), and spend not more than 10 CELL on it. The service cost is 5 CELL for one day (it is actually more complicated, but it doesn’t matter for example).

So we create a CONDITIONAL TRANSACTION using Node Command - TX_COND_CREATE.

In this transaction an input IN #1 with all 500 CELL is created.

Then, this input is distributed between three outputs:

OUT #1 - 489.95 CELL is sent back on the WALLET #1 as new UNSPENT OUT COND OUT #2 - 10 CELL is prescribed for paying for the service COND OUT #3 - 0.05 CELL is a validator fee

In the next two transactions we will consider journey of the 10 CELL.

The PAYMENT TRANSACTION #1:

IN COND - 10 CELL received from the COND OUT #2 of the previous transaction. Conditional Input is the only way to receive funds from the conditional output. When the funds are on the IN COND, they can be also distributed between all outputs.

COND OUT #2 - 5 CELL was paid for the service and sent to the wallet of service-provider COND OUT #2 - 4.95 CELL is a change (rest of the sum) which will be sent on the next transaction COND OUT #3 - 0.05 CELL is a validator fee

Thus, a one day of the service was fully paid. But when the day is over, a next payment is coming.

The PAYMENT TRANSACTION #2:

IN COND - this transaction takes the change 4.95 CELL as an input

COND OUT #2 - 4.9 CELL was paid for the service and sent to the wallet of service-provider COND OUT #2 - 0.05 CELL is a validator fee

All 4.9 CELL was sent to the service provider as payment. It is enough to pay for almost one day of service. If the change sum was higher than 5 CELL, there will be created another PAYMENT TRANSACTION.

As you can see, there are two new UNSPENT OUTs on the wallet of the service provider: 5 CELL and 4.95 CELL.

Technical Application

There is information about all used items.

Input

This item serves as a funds entering point into the transaction. The regular input can receive funds from the output of another previous transaction. For this Tx out prev idx and Tx prev hash of the target transaction must be specified.

FIELDS:

item type: type of the item - IN: string Tx prev hash: hash of previous transaction: string Tx out prev idx: ID of the target output; ID is the serial number of OUT in the transaction starting with 0: uint64

EXAMPLE:

  item type: IN
                Tx prev hash: 0x5D72AF540B571F87839F9433A9FE0D7E92F84946C2B3528969D6191E28AFE150
                Tx out prev idx: 2

Conditional Input

This item is like regular input prescribed to receive incoming funds from the previous transaction, but conditional input can receive funds only from the conditional outputs. The fields are quite the same, but in case of service payment, there also must be specified Receipt_idx of the receipt from the target transaction.

FIELDS:

item type: type of the item - IN COND: string Receipt_idx: ID of the receipt; optional field: int Tx_prev_hash: hash of the target previous transaction: string Tx_out_prev_idx: ID of the target output; ID is the serial number of OUT in the transaction starting with 0: uint64

EXAMPLE:

  item type: IN COND
                Receipt_idx: 0
                Tx_prev_hash: 0xAEF5F6D254387F7798BF50F176B2112ED60ABF53396D896B00A3333DC22626E9
                Tx_out_prev_idx: 0

Output

The output item serves as an exit for funds from the transaction. Usually, funds are taken to Output from the Input or Conditional Input of the same transaction. But funds can be taken also from the INPUT EMISSION item.

To transfer funds from the output, it is mandatory to specify Addr of the receiving wallet, Token ticker and Value of funds being transferred.

FIELDS:

item type: type of the item - OUT: string Addr: wallet address of the receiver: string Token: name of the token: string Coins: amount of funds being transferred in coins: string Value: amount of funds being transferred: string

EXAMPLE:

                item type: OUT 
                Addr: Rj7J7MiX2bWy8sNyWeQS3iBok3hGXuxni6Tg71GVBnjBkrvrZcrK24m7vF5CLQxprQdBchXrnUJR9hDu5SzGFU7JP4nRVnBikHsjGHph
                Token: CELL
                Coins: 4.691284117214960025
                Value: 4691284117214960025

Conditional Outputs

These items are created to provide payments, exchanges, stakes and many more. These outputs differ from regular output with a special condition, which is being fulfilled to acquire funds.

1. Fee

This item is used to pay for validator services. Once the validator approves the transaction, funds from the conditional FEE  output of this transaction can be transferred to his wallet. Almost every transaction includes this item, with very rare exceptions.

The recommended validator fee amount can be found here.

FIELDS:

item type: type of the item - OUT COND: string ts_expires: timestamp of expiration specified in RFC822 format, if not specified, never is used by default: string coins: fee size calculated in coins: string value: fee size: string subtype: subtype of the COND OUT item - FEE: string uid: unique ID of the service, 0x0000000000000000 by default: string tsd_size: size of the applied TSD sections: int

EXAMPLE:

item type: OUT COND
                ts_expires: never
                coins: 0.05
                value: 50000000000000000
                subtype: DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE
                uid: 0x0000000000000000
                tsd_size: 0

2. Service Payment

An item designed for services payment in Cellframe networks.

To pay for the use of a service, you need to specify the fee value, the kind of a unit unit (megabytes or seconds), the maximal cost per one unit max price (value), as well as the provider’s public key pkey indicated in the receipt. If the provider’s public key matches the public key specified in the receipt, the provider will be able to withdraw funds from this conditional SRV_PAY output.

FIELDS:

item type: type of the item - OUT COND: string ts_expires: timestamp of expiration specified in RFC822 format, if not specified, never is used by default: string coins: payment sum calculated in coins: string value: payment sum: string subtype: subtype of the OUT COND item - SRV_PAY: string uid: ID of the service, 0x0000000000000001 by default: string tsd_size: size of the applied TSD sections: int unit: kind of service unit, seconds or megabytes: string pkey: public key of service-provider: string max price (coins): maximal price for one unit in coins: string max price (value): maximal price for one unit: string

EXAMPLE:

 item type: OUT COND
            ts_expires: never
            coins: 0.06
            value: 60000000000000000
            subtype: DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY
            uid: 0x0000000000000001
            tsd_size: 0
            unit: 0x00000002
            pkey: 0x3E6079BA2AC5F73836BB15A64D8BAF597A0EB0931054BDEEE760E5B0673EFD6A
            max price(coins): 0.0
            max price(value): 0

3. Exchange Service

This item is designed for operations on the Cellframe Decentralized Exchange Service (DEX). It allows users to exchange tokens buy_token at specified rate between users within a specific network net id.

FIELDS:

item type: type of the item - OUT COND: string ts_expires: timestamp of expiration specified in RFC822 format, if not specified, never is used by default: string coins: sum of tokens being exchanged in coins: string value: sum of tokens being exchanged: string subtype: subtype of the OUT COND item - SRV_XCHANGE: string uid: ID of the service, 0x2 by default: string tsd_size: size of the applied TSD sections: int net id: ID of the network where order is placed: string buy_token: ticker of token being bought: string rate: exchange rate calculated this way “token_buy/token_sell”: string

Network ID's in the Cellframe:

Backbone - id=0x0404202200000000
KelVPN - id=0x1807202300000000
mileena - id=0x000000000000cccc
raiden - id=0x000000000000bbbb
riemann - id=0x000000000000dddd
subzero - id=0x000000000000acca

EXAMPLE:

item type: OUT COND
            ts_expires: never
            coins: 1.0
            value: 1000000000000000000
            subtype: DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE
            uid: 0x0000000000000002
            tsd_size: 0
            net id: 0x000000000000dddd
            buy_token: mtKEL
            rate: 1.0

4. Staking Service

An item created for the staking service, specifically designed to lock a certain amount of funds value in a specified conditional output for a defined period of time time_unlock.

FIELDS:

item type: type of the item - OUT COND: string ts_expires: timestamp of expiration specified in RFC822 format, if not specified, never is used by default: string coins: amount of funds to lock in coins: string value: amount of funds to lock: string subtype: subtype of the OUT COND item - SRV_STAKE_LOCK: string uid: ID of the service, 0x12 by default: string time_unlock: timestamp in RFC822 format that specifies when the funds will be unlocked: string

EXAMPLE:

 
 item type: OUT COND
                Header:
                ts_expires: never
                coins: 81.0
                value: 81000000000000000000
                subtype: DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK
                uid: 0x0000000000000012
                time_unlock: Fri, 06 Mar 2026 04:00:01 +0700

5. Delegated Staking Service

This item is involved in the operation of the delegated staking service. With its help, you can delegate your “consensus weight” to another node signer_node_addr, meaning that your m-tokens from the address signing_addr in the amount of value will contribute to the total weight of the specified node.

FIELDS:

item type: type of the item - COND OUT: string ts_expires: timestamp of expiration specified in RFC822 format, if not specified, never is used by default: string coins: amount of funds being delegated in coins: string value: amount of funds being delegated: string subtype: subtype of the COND OUT item - SRV_STAKE_POS_DELEGATE: string uid: ID of the service, 0x13 by default: string tsd_size: size of the applied TSD sections: int signing_addr: wallet address of the staker: string with pkey hash: public key hash of the of the signing address: string signer_node_addr: node address of the target validator: string

EXAMPLE:

 item type: OUT COND
            ts_expires: never
            coins: 10.1
            value: 10100000000000000000
            subtype: DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE
            uid: 0x0000000000000013
            tsd_size: 0
            signing_addr: o9z3wUTSTicckJuozhPr6oMEAtya7JnStmo8UvkBJ9TcHc9ooUPksbmAEWSrgt9tzNRbop3XGniUJuXRWGQUbNujR4ugg1WZ3L8s9K7F
            with pkey hash: 0xC51165F05F83FDF16D682658927B65F90F930E147D31AE15662842F174538F25
            signer_node_addr: 4A34::01E2::FE8C::C0B4