Funds transferring in the Cellframe Networks is performed using transactions **inputs** and **outputs**. - **Input** is a transaction [[5. Transactions Structure#Items|item]] which contains funds entering in transaction. - **Output** is also a transaction [[5. Transactions Structure#Items|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? > [!HINT] Note > The balance of the wallet in Cellframe is not just a one number, it is a sum of all **free unspent outputs**. ![[Pasted image 20250402130001.png]] 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: > [!ERROR] 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 [[Fee#Validator Fee|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`. ![[Pasted image 20250402111703.png]] The **`PAYMENT TRANSACTION #1`**: **`IN COND`** - `10 CELL` received from the **`COND OUT #2`** of the previous transaction. **[[4. Transactions INPUT & OUTPUT#Conditional Input|Conditional Input]]** is the only way to receive funds from the **[[4. Transactions INPUT & OUTPUT#Conditional Outputs|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. - **[[4. Transactions INPUT & OUTPUT#Input|Input]]** - **[[4. Transactions INPUT & OUTPUT#Conditional Input|Conditional Input]]** - **[[4. Transactions INPUT & OUTPUT#Output|Output]]** - **[[4. Transactions INPUT & OUTPUT#Conditional Outputs|Conditional Outputs]]** ### Input This item serves as a funds entering point into the transaction. The regular **input** can receive funds from the [[3. JSON Format of Transactions#Output|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:`** ```json item type: IN Tx prev hash: 0x5D72AF540B571F87839F9433A9FE0D7E92F84946C2B3528969D6191E28AFE150 Tx out prev idx: 2 ``` ### Conditional Input This item is like regular **[[3. JSON Format of Transactions#Input|input]]** prescribed to receive incoming funds from the previous transaction, but **[[3. JSON Format of Transactions#Conditional Input|conditional input]]** can receive funds only from the **[[3. JSON Format of Transactions#Conditional Outputs|conditional outputs]]**. The fields are quite the same, but in case of service payment, there also must be specified **`Receipt_idx`** of the **[[Receipt|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:`** ```json 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:`** ```json 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 **[[fee|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:`** ```json 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 [[3. JSON Format of Transactions#Receipt|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:`** ```json 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:` ```actionscript Backbone - id=0x0404202200000000 KelVPN - id=0x1807202300000000 mileena - id=0x000000000000cccc raiden - id=0x000000000000bbbb riemann - id=0x000000000000dddd subzero - id=0x000000000000acca ``` **`EXAMPLE:`** ```json 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 **[[Stake|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:`** ```json 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 Stakes|delegated staking]]** service. With its help, you can delegate your "consensus weight" to another node **`signer_node_addr`**, meaning that your **[[Token Delegated (m-token)|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:`** ```json 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 ```