- Capacity: The minimum amount of CKB required for the cell's occupied capacity.
- Lock: A user-defined lock script.
- Type: The standard
xUDTscript.code_hash:XUDT_CODE_HASHhash_type:XUDT_HASH_TYPEargs:[ckbc-vault-type-hash (32 bytes)] + [flags (4 bytes)]ckbc-vault-type-hash: The Blake2b hash of theckbc-vault-typescript.flags:0xE0000000(little-endian bytes:0x000000E0).- Enables
0x20000000(disables Lock Script Hash owner mode for inputs). - Enables
0x40000000(checks Type Script Hashes in outputs). - Enables
0x80000000(checks Type Script Hashes in inputs).
- Enables
- Data:
- The first 16 bytes encode
amount: u128in little-endian order, denominated in Shannon (10^8 Shannon = 1 CKB/CKBC). - Additional extension data may follow. The current protocol neither interprets this data nor includes it in the token amount.
- The first 16 bytes encode
- Capacity: The amount of locked CKB, denominated in Shannon.
- Lock: The
always_successlock script.code_hash:ALWAYS_SUCCESS_CODE_HASHhash_type:ALWAYS_SUCCESS_HASH_TYPEargs: Empty.
- Type: The
ckbc-vault-typescript.code_hash:VAULT_TYPE_CODE_HASHhash_type:VAULT_TYPE_HASH_TYPEargs: Empty.
- Data:
- The first 16 bytes encode
capacity: u128in little-endian order, denominated in Shannon. Its value must equal the cell'scapacityfield. - A Vault Cell with fewer than 16 data bytes is invalid. Extension data after byte 16 is ignored and not validated.
- The first 16 bytes encode
Each ckbc-vault-type Script Group found in the inputs or outputs independently performs the following validations.
For the currently executing ckbc-vault-type Script Group, define and require the following:
current_vault_type_hash: The full Type Script Hash of the current Script Group.matching_vault_cell: A Vault Cell whose Type Script Hash equalscurrent_vault_type_hash.matching_CKBC_cell: ACKBCxUDT Cell that meets all of the following conditions:code_hash == XUDT_CODE_HASHhash_type == XUDT_HASH_TYPEargs == [current_vault_type_hash (32 bytes)] + [flags (4 bytes)]flags == 0xE0000000
- The
argsofckbc-vault-typemust be empty. A Vault Cell with non-emptyargsis always invalid. - Input Vault data is not revalidated. A Vault Cell is immutable after creation, and its data was validated when the cell was created as an output. That result is therefore trusted when the cell is later consumed as an input, even after a contract upgrade. All conservation and transaction constraints use the input cells'
capacityfields and cell counts directly; they do not depend on input data.
The increase in the amount of CKBC tokens in a transaction must not exceed the increase in Vault capacity:
total_output_CKBC - total_input_CKBC <= total_output_vault_capacity - total_input_vault_capacity
total_input_vault_capacity/total_output_vault_capacity: The sum of the input/output cellcapacityfields for allmatching_vault_cellinstances, denominated in Shannon.total_input_CKBC/total_output_CKBC: The sum of theamountvalues encoded in the first 16 data bytes of all input/outputmatching_CKBC_cellinstances, denominated in Shannon. Any extension data is excluded from the calculation.
A transaction must meet one of the following conditions:
- The inputs contain no Vault Cells for the current pool (minting):
count(input.matching_vault_cell) == 0 - The inputs contain Vault Cells for the current pool (partial or full unlock):
- Total output Vault capacity must be strictly less than total input Vault capacity:
output_vault_capacity < input_vault_capacity - The number of output Vaults must not exceed the number of input Vaults:
count(output.matching_vault_cell) <= count(input.matching_vault_cell) - There may be no more than two output Vaults:
count(output.matching_vault_cell) <= 2
- Total output Vault capacity must be strictly less than total input Vault capacity:
This rule minimizes the number of public Vaults an attacker can occupy in a single transaction. It cannot prevent an attacker from creating multiple concurrent transactions that occupy Vaults. The transaction pool policy should handle competition between concurrent transactions.
The capacity of each output Vault Cell, if any, must fall within the following range:
occupied_capacity <= output_vault.capacity <= max_capacity
occupied_capacity: The minimum capacity derived from the physical byte size occupied by the cell structure at the CKB VM level (typically 90 CKB).max_capacity: A protocol-level hard limit embedded in theckbc-vault-typescript code rather than configured dynamically throughargs. It is fixed at 5,000,000 CKB.
- Inputs:
- User CKB funding Cell(s)
- Outputs:
- One or more
CKBC-vaultCells (total capacity: V_out) - One or more
CKBCUDT Cells (total amount: U_out, where U_out <= V_out) - CKB change Cell(s) (optional)
- One or more
- Inputs:
- One or more
CKBC-vaultCells (total capacity: V_in) - User
CKBCUDT Cells (amount: U_in)
- One or more
- Outputs:
- Zero, one, or two
CKBC-vaultCells (total capacity: V_out, where V_out < V_in; the count must not exceed the number of input Vaults) - User CKB funding Cells (capacity: the remainder of V_in - V_out after deducting the transaction fee)
- User
CKBCUDT Cells (amount: U_out, where U_in - U_out >= V_in - V_out)
- Zero, one, or two
- Inputs:
- One or more
CKBC-vaultCells (total capacity: V_in) - User
CKBCUDT Cells (amount: U_in, where U_in >= V_in)
- One or more
- Outputs:
- User CKB funding Cells (capacity: the remainder of V_in after deducting the transaction fee)
- User
CKBCUDT Cells (amount: the remainder of U_in - V_in; omitted when the remainder is zero)
- Inputs:
- User
CKBCUDT Cell(s)
- User
- Outputs:
- Recipient
CKBCUDT Cell(s) - User
CKBCUDT change Cell(s) (optional)
- Recipient
- Note: No
ckbc-vault-typeCell participates in the transaction, so xUDT applies its standard transfer validation.CKBCrepresents a redeemable share of the public CKB reserve pool. Redemption rights follow CKBC ownership rather than the identity of the original depositor.