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