TITLE: Representing CKB Transaction Structure (JSON) DESCRIPTION: This JSON snippet demonstrates the complex CKB `Transaction` structure. It includes fields for version, dependencies (`cell_deps`, `header_deps`), inputs (referencing previous outputs with optional `since` values), newly created outputs (`outputs` and their associated `outputs_data`), and `witnesses` providing data for script execution. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0019-data-structures/0019-data-structures.md#_snippet_2 LANGUAGE: json CODE: ``` { "version": "0x0", "cell_deps": [ { "out_point": { "tx_hash": "0xbd864a269201d7052d4eb3f753f49f7c68b8edc386afc8bb6ef3e15a05facca2", "index": "0x0" }, "dep_type": "dep_group" } ], "header_deps": [ "0xaa1124da6a230435298d83a12dd6c13f7d58caf7853f39cea8aad992ef88a422" ], "inputs": [ { "previous_output": { "tx_hash": "0x8389eba3ae414fb6a3019aa47583e9be36d096c55ab2e00ec49bdb012c24844d", "index": "0x1" }, "since": "0x0" } ], "outputs": [ { "capacity": "0x746a528800", "lock": { "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", "args": "0x56008385085341a6ed68decfabb3ba1f3eea7b68", "hash_type": "type" }, "type": null }, { "capacity": "0x1561d9307e88", "lock": { "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", "args": "0x886d23a7858f12ebf924baaacd774a5e2cf81132", "hash_type": "type" }, "type": null } ], "outputs_data": [ "0x", "0x" ], "witnesses": [ "0x55000000100000005500000055000000410000004a975e08ff99fa000142ff3b86a836b43884b5b46f91b149f7cc5300e8607e633b7a29c94dc01c6616a12f62e74a1415f57fcc5a00e41ac2d7034e90edf4fdf800" ] } ``` ---------------------------------------- TITLE: Generating Merkle Proof for CKB CBMT (C++) DESCRIPTION: This algorithm generates a Merkle proof for a given set of item indexes within a Complete Binary Merkle Tree (CBMT) represented as an array. It uses a queue to traverse the tree nodes corresponding to the items, collecting the necessary sibling nodes that are not on the path, and sorts the collected nodes and item indexes according to the specified proof structure. Dependencies include helper functions for calculating sibling and parent indexes (calculate_sibling, calculate_parent). SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0006-merkle-tree/0006-merkle-tree.md#_snippet_0 LANGUAGE: C++ CODE: ``` Proof gen_proof(Hash tree[], U32 indexes[]) { Hash nodes[]; U32 tree_indexes[]; Queue queue; int size = len(tree) >> 1 + 1; indexes.desending_sort(); for index in indexes { queue.push_back(index + size - 1); } while(queue is not empty) { int index = queue.pop_front(); int sibling = calculate_sibling(index); if(sibling == queue.front()) { queue.pop_front(); } else { nodes.push_back(tree[sibling]); } int parent = calculate_parent(index); if(parent != 0) { queue.push_back(parent); } } add (size-1) for every index in indexes; sort indexes in ascending order by corresponding hash; return Proof::new(indexes, nodes); } ``` ---------------------------------------- TITLE: Referencing Secp256k1 Data (Mainnet CKB OutPoint) DESCRIPTION: Specifies the transaction hash and index for the secp256k1_data cell dependency on the Nervos CKB Mainnet. This output point is used when referencing the secp256k1 lock script data in transactions. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0039-cheque/0039-cheque.md#_snippet_6 LANGUAGE: CKB Cell OutPoint CODE: ``` { tx_hash: 0xe2fb199810d49a4d8beec56718ba2593b665db9d52299a0f9e6e75416d73ff5c, index: 0x3 } ``` ---------------------------------------- TITLE: Defining Secp256k1 Data Dependency (Lina) - CKB Structure DESCRIPTION: Specifies the `out_point` details, including the transaction hash and output index, for the `secp256k1_data` cell dependency used by the deployed Anyone-Can-Pay lock on the Nervos CKB Lina mainnet. This cell provides the cryptographic verification primitive. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0026-anyone-can-pay/0026-anyone-can-pay.md#_snippet_2 LANGUAGE: CKB Structure CODE: ``` { tx_hash: 0xe2fb199810d49a4d8beec56718ba2593b665db9d52299a0f9e6e75416d73ff5c, index: 0x3 } ``` ---------------------------------------- TITLE: Nervos CKB Block JSON Structure DESCRIPTION: Provides the JSON structure representing a finalized CKB block, including the header (with timestamp, nonce, roots), uncles, transactions, proposals, and extension. This structure is typically used for representing blocks after they are added to the chain. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0031-variable-length-header-field/0031-variable-length-header-field.md#_snippet_1 LANGUAGE: json CODE: ``` { "header": { "version": "0x0", "compact_target": "0x20010000", "timestamp": "0x17af3f66555", "number": "0x3", "epoch": "0x3e80003000000", "parent_hash": "0xebf229020f333100942279dc33303ae0dfcbe720d8d11818687e6654c157294c", "transactions_root": "0x0bbf9d8946932c9c33a46c8d13b9ecfcf850ccc1728fc9c9c5d14710ad9428ad", "proposals_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "extra_hash": "0xfbbfbaaa0afac7730f4a6102b376986f1f288f3eccb18e0d16d58422aab28aad", "dao": "0x105cabf31c1fa12eacfa6990f2862300bdaf44b932000000008d5fff03fbfe06", "nonce": "0x6e43a02f3ed8bb00dea7f78c12fe94f5" }, "uncles": [], "transactions": [ { "version": "0x0", "cell_deps": [], "header_deps": [], "inputs": [ { "since": "0x3", "previous_output": { "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "index": "0xffffffff" } } ], "outputs": [], "outputs_data": [], "witnesses": [ "0x590000000c00000055000000490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce80114000000c8328aabcd9b9e8e64fbc566c4385c3bdeb219d700000000" ] }, { "version": "0x0", "cell_deps": [ { "out_point": { "tx_hash": "0xace5ea83c478bb866edf122ff862085789158f5cbff155b7bb5f13058555b708", "index": "0x0" }, "dep_type": "dep_group" } ], "header_deps": [], "inputs": [ { "since": "0x0", "previous_output": { "tx_hash": "0xa563884b3686078ec7e7677a5f86449b15cf2693f3c1241766c6996f206cc541", "index": "0x7" } } ], "outputs": [ { "capacity": "0x2540be400", "lock": { "code_hash": "0x709f3fda12f561cfacf92273c57a98fede188a3f1a59b1f888d113f9cce08649", "hash_type": "data", "args": "0xc8328aabcd9b9e8e64fbc566c4385c3bdeb219d7" }, "type": null }, { "capacity": "0x2540be400", "lock": { "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", "hash_type": "type", "args": "0xc8328aabcd9b9e8e64fbc566c4385c3bdeb219d7" }, "type": null }, { "capacity": "0x2540be400", "lock": { "code_hash": "0x709f3fda12f561cfacf92273c57a98fede188a3f1a59b1f888d113f9cce08649", "hash_type": "data1", "args": "0xc8328aabcd9b9e8e64fbc566c4385c3bdeb219d7" }, "type": null } ], "outputs_data": [ "0x", "0x", "0x" ], "witnesses": [ "0x550000001000000055000000550000004100000070b823564f7d1f814cc135ddd56fd8e8931b3a7040eaf1fb828adae29736a3cb0bc7f65021135b293d10a22da61fcc64f7cb660bf2c3276ad63630dad0b6099001" ] } ], "proposals": [], "extension": "0x626c6f636b202333" } ``` ---------------------------------------- TITLE: Structuring Simple UDT Transfer Transaction - CKB Structure DESCRIPTION: Illustrates the structure of a CKB transaction designed for transferring SUDTs. It shows multiple SUDT cells being consumed as inputs and new SUDT cells being produced as outputs, adhering to the rule that output amounts must be less than or equal to input amounts. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0025-simple-udt/0025-simple-udt.md#_snippet_1 LANGUAGE: CKB Structure CODE: ``` // Transfer Inputs: SUDT_Cell Data: amount: uint128 Type: code_hash: simple_udt type script args: owner lock script hash (...) Lock: <...> Outputs: SUDT_Cell Data: amount: uint128 Type: code_hash: simple_udt type script args: owner lock script hash (...) Lock: <...> ``` ---------------------------------------- TITLE: Representing CKB Cell Structure (JSON) DESCRIPTION: This JSON snippet provides an example representation of the CKB `Cell` structure. It includes fields for `capacity` (cell size/CKB amount), `lock` (defines ownership via a script), and `type` (defines cell behavior via an optional script), showing a typical locked cell without a type script. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0019-data-structures/0019-data-structures.md#_snippet_0 LANGUAGE: json CODE: ``` { "capacity": "0x19995d0ccf", "lock": { "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", "args": "0x0a486fb8f6fe60f76f001d6372da41be91172259", "hash_type": "type" }, "type": null } ``` ---------------------------------------- TITLE: Calling Load Transaction Hash Syscall C DESCRIPTION: This C function `ckb_load_tx_hash` wraps the 'Load Transaction Hash' syscall (ID 2061). It facilitates loading the hash of the current transaction into a buffer in VM memory. It utilizes the partial loading mechanism, requiring pointers for the buffer (`addr`), its length (`len`), and an `offset` for the data source. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#_snippet_4 LANGUAGE: C CODE: ``` int ckb_load_tx_hash(void* addr, uint64_t* len, size_t offset) { return syscall(2061, addr, len, offset, 0, 0, 0); } ``` ---------------------------------------- TITLE: Defining Nervos DAO Script | CKB JSON DESCRIPTION: JSON structure representing the script deployed on CKB mainnet for the Nervos DAO. It includes the code_hash, empty args, and hash_type set to "type". This object is used to identify and reference the DAO script. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0023-dao-deposit-withdraw/0023-dao-deposit-withdraw.md#_snippet_0 LANGUAGE: JSON CODE: ``` { "code_hash": "0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e", "args": "0x", "hash_type": "type" } ``` ---------------------------------------- TITLE: Block Containing Nervos DAO Deposit | CKB JSON DESCRIPTION: JSON structure representing a CKB block header. The text indicates this specific block contains the previously shown transaction that deposits CKB into the Nervos DAO. It includes standard block header fields and the 'dao' field containing the Accumulated Rate (AR) and other state information for the DAO at this block height. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0023-dao-deposit-withdraw/0023-dao-deposit-withdraw.md#_snippet_3 LANGUAGE: JSON CODE: ``` { "compact_target": "0x1a2158d9", "hash": "0x37ef8cf2407044d74a71f927a7e3dcd3be7fc5e7af0925c0b685ae3bedeec3bc", "number": "0x105f", "parent_hash": "0x36990fe91a0ee3755fd6faaa2563349425b56319f06aa70d2846af47e3132262", "nonce": "0x19759fb43000000000000000b28a9573", "timestamp": "0x16e80172dbf", "transactions_root": "0x66866dcfd5426b2bfeecb3cf4ff829d353364b847126b2e8d2ce8f8aecd28fb8", "proposals_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "uncles_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "version": "0x0", "epoch": "0x68d0288000002", "dao": "0x8268d571c743a32ee1e547ea57872300989ceafa3e710000005d6a650b53ff06" } ``` ---------------------------------------- TITLE: Representing CKB Script Structure (JSON) DESCRIPTION: This JSON snippet illustrates the CKB `Script` structure used for both lock and type scripts. It specifies the `code_hash` referencing the script's RISC-V binary (typically in a cell dependency), `args` passed to the script VM, and `hash_type` to define how the `code_hash` references the dependency cell. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0019-data-structures/0019-data-structures.md#_snippet_1 LANGUAGE: json CODE: ``` { "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", "args": "0x0a486fb8f6fe60f76f001d6372da41be91172259", "hash_type": "type" } ``` ---------------------------------------- TITLE: CKB Syscall: Load Witness (C) DESCRIPTION: This CKB syscall is used by a script to read witness data from the transaction. The example shown loads the witness at index `0` from the transaction's inputs (`CKB_SOURCE_INPUT`). Other sources like `CKB_SOURCE_GROUP_INPUT` can also be used, along with an index relative to the script group's inputs. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0022-transaction-structure/0022-transaction-structure.md#_snippet_2 LANGUAGE: C CODE: ``` ckb_load_witness(addr, len, offset, 0, CKB_SOURCE_INPUT); ``` ---------------------------------------- TITLE: Defining Full Payload Format CKB Address C DESCRIPTION: Specifies the structure of the full payload format used for generating CKB addresses. It consists of a format type byte (0x00), the 32-byte code hash, the 1-byte hash type (0 or 1), and the arbitrary-length args. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0021-ckb-address-format/0021-ckb-address-format.md#_snippet_0 LANGUAGE: c CODE: ``` payload = 0x00 | code_hash | hash_type | args ``` ---------------------------------------- TITLE: Loading Cell Field (CKB VM Syscall) in C DESCRIPTION: This C function provides an interface to the `ckb_load_cell_by_field` syscall. It loads a specific field (defined by the `field` parameter) from a cell specified by `index` and `source` using the partial loading mechanism (`addr`, `len`, `offset`). It returns 0 on success, 1 if the index is out of bounds, 2 if the field is missing, or triggers a VM error for invalid source/field. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#_snippet_9 LANGUAGE: C CODE: ``` int ckb_load_cell_by_field(void* addr, uint64_t* len, size_t offset, size_t index, size_t source, size_t field) { return syscall(2081, addr, len, offset, index, source, field); } ``` ---------------------------------------- TITLE: Structuring Simple UDT Mint Transaction - CKB Structure DESCRIPTION: Shows the conceptual structure for a transaction used to issue or mint new SUDTs. It requires at least one input cell to be controlled by the designated owner lock script and defines the structure of the resulting output SUDT cell. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0025-simple-udt/0025-simple-udt.md#_snippet_2 LANGUAGE: CKB Structure CODE: ``` // Issue new SUDT Inputs: <... one of the input cell must have owner lock script as lock> Outputs: SUDT_Cell: Data: amount: uint128 Type: code_hash: simple_udt type script args: owner lock script hash (...) Lock: ``` ---------------------------------------- TITLE: Executing UDT Operations via Dynamic Linking and Argument Dispatch - CKB Script DESCRIPTION: Demonstrates a CKB script's `main` function that uses dynamic linking to call UDT functions based on command-line arguments (`argv`). It reads the input and output cell data, then uses `strcmp` on `argv[4]` to determine which UDT function (e.g., `udt_initialize`, `udt_transfer`) to call. This approach allows a single minimal script to support multiple UDT operations by linking to a shared library containing all implementations. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0003-ckb-vm/0003-ckb-vm.md#_snippet_10 LANGUAGE: C CODE: ``` int main(int argc, char* argv[]) { data_t *input_data = NULL; ret = ckb_read_cell(0, CKB_SOURCE_INPUT, (void **) &input_data, NULL); if (ret != 0) { return ret; } data_t *output_data = NULL; ret = ckb_read_cell(0, CKB_SOURCE_OUTPUT, (void **) &output_data, NULL); if (ret != 0) { return ret; } if (strcmp(argv[4], "initialize") == 0) { // processing initialize arguments ret = udt_initialize(...); if (ret != 0) { return ret; }lse if (strcmp(argv[4], "transfer") == 0) { // processing transfer arguments ret = udt_transfer(input_data, ...); if (ret != 0) { return ret; } } else if (strcmp(argv[4], "approve") == 0) { // processing approve arguments ret = udt_approve(input_data, ...); if (ret != 0) { return ret; } } // more commands here if (memcmp(input_data, output_data, sizeof(data_t)) != 0) { return -1; } return 0; } ``` ---------------------------------------- TITLE: Calling Load Cell Syscall C DESCRIPTION: This C function `ckb_load_cell` wraps the 'Load Cell' syscall (ID 2071). It locates and loads a specific cell from inputs, outputs, or dependencies into VM memory. It uses the partial loading mechanism (`addr`, `len`, `offset`) along with `index` and `source` parameters to identify the cell. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#_snippet_8 LANGUAGE: C CODE: ``` int ckb_load_cell(void* addr, uint64_t* len, size_t offset, size_t index, size_t source) { return syscall(2071, addr, len, offset, index, source, 0); } ``` ---------------------------------------- TITLE: Calling Load Transaction Syscall C DESCRIPTION: This C function `ckb_load_transaction` wraps the 'Load Transaction' syscall (ID 2051). It loads the full transaction containing the running script, serialized in Molecule Encoding format, into VM memory. It uses the partial loading mechanism via `addr`, `len`, and `offset` parameters. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#_snippet_5 LANGUAGE: C CODE: ``` int ckb_load_transaction(void* addr, uint64_t* len, size_t offset) { return syscall(2051, addr, len, offset, 0, 0, 0); } ``` ---------------------------------------- TITLE: Loading Cell Data (CKB VM Syscall) in C DESCRIPTION: This C function wraps the `ckb_load_cell_data` syscall, facilitating the loading of the data section of a specific cell identified by `index` and `source`. It utilizes the partial loading mechanism via `addr`, `len`, and `offset` to copy the data into VM memory. The syscall returns 0 on success, 1 if the index is out of bounds, or triggers a VM error for an invalid source. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#_snippet_10 LANGUAGE: C CODE: ``` int ckb_load_cell_data(void* addr, uint64_t* len, size_t offset, size_t index, size_t source) { return syscall(2092, addr, len, offset, index, source, 0); } ``` ---------------------------------------- TITLE: Defining Simple UDT Cell Structure - CKB Structure DESCRIPTION: Specifies the required structure for a cell representing a Simple UDT asset on CKB. It details the segments (data, type, lock) and their contents, emphasizing the storage of the token amount and the owner lock script hash. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0025-simple-udt/0025-simple-udt.md#_snippet_0 LANGUAGE: CKB Structure CODE: ``` data: amount: uint128 type: code_hash: simple_udt type script args: owner lock script hash (...) lock: ``` ---------------------------------------- TITLE: Defining Cheque Lock Cell Structure - CKB Cell Structure DESCRIPTION: Specifies the structure of a cell that uses the Cheque Lock. It includes the Cheque lock script with receiver and sender hashes in the args, an optional type script for the asset (like SUDT), and the data field containing the asset amount. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0039-cheque/0039-cheque.md#_snippet_0 LANGUAGE: CKB Cell Structure CODE: ``` lock: code_hash: args: <20-byte_receiver_lock_hash> <20-byte_sender_lock_hash> type: data: ``` ---------------------------------------- TITLE: Loading Specific CKB Header Field (C) DESCRIPTION: Implements the `ckb_load_header_by_field` syscall in C. This function loads a specific `field` (like epoch number, epoch start block, or epoch length) from a transaction header identified by `index` and `source`. The data is written to memory at `addr`, controlled by `len` and `offset`. Returns 0 on success, 1 for index out of bound, 2 for missing header hash, or triggers a VM error for invalid source or field. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#_snippet_15 LANGUAGE: C CODE: ``` int ckb_load_header_by_field(void* addr, uint64_t* len, size_t offset, size_t index, size_t source, size_t field) { return syscall(2082, addr, len, offset, index, source, field); } ``` ---------------------------------------- TITLE: Loading CKB Cells with Syscalls - C DESCRIPTION: This C code snippet illustrates a basic CKB contract. It shows the standard `main` entry point for a CKB script and demonstrates how to use the `ckb_load_cell` syscall to load data from input and output cells into dynamically allocated memory buffers. The contract is considered successful if `main` returns 0. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0003-ckb-vm/0003-ckb-vm.md#_snippet_0 LANGUAGE: C CODE: ``` int main(int argc, char* argv[]) { uint64_t input_cell_length = 10000; void *input_cell = malloc(input_cell_length); ckb_load_cell(input_cell, &input_cell_length, 0, 0, CKB_SOURCE_INPUT); uint64_t output_cell_length = 10000; void *output_cell = malloc(output_cell_length); ckb_load_cell(output_cell, &output_cell_length, 0, 0, CKB_SOURCE_OUTPUT); // Consume input & output cell return 0; } ``` ---------------------------------------- TITLE: Nervos CKB Script: Loading Headers via Syscall (C) DESCRIPTION: These C code examples demonstrate how to use the `ckb_load_header` syscall within a CKB script. It shows loading block headers specified in the transaction's `header_deps` by index, and loading headers of blocks where input cells were created by specifying the input index and `CKB_SOURCE_INPUT`. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0022-transaction-structure/0022-transaction-structure.md#_snippet_4 LANGUAGE: C CODE: ``` // Load the first block in header_deps, the block Hi load_header(..., 0, CKB_SOURCE_HEADER_DEP); // Load the second block in header_deps, the block Hj load_header(..., 1, CKB_SOURCE_HEADER_DEP); // Load the block in which the first input is created, the block Hi load_header(..., 0, CKB_SOURCE_INPUT); // Load the block in which the second input is created. // Since the block creating cell2 is not in header_deps, this call loads nothing. load_header(..., 1, CKB_SOURCE_INPUT); ``` ---------------------------------------- TITLE: Simple CKB Lock Script Example (C) DESCRIPTION: This is a minimal C example of a CKB lock script. It demonstrates the basic structure of a CKB script's entry point (`main`) and always exits normally by returning 0. A cell using this script as its lock can be spent by anyone, as the script imposes no restrictions. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0022-transaction-structure/0022-transaction-structure.md#_snippet_0 LANGUAGE: C CODE: ``` int main(int argc, char *argv[]) { return 0; } ``` ---------------------------------------- TITLE: Calling ckb_spawn and IPC Setup (C) DESCRIPTION: This C code implements the parent process ('Caller') using the CKB VM environment. It demonstrates how to set up piped file descriptors (mimicking standard input/output) using `ckb_pipe` and the helper `create_std_fds` function. It then utilizes `ckb_spawn` to launch a child process, passing the configured file descriptors for inheritance. The parent writes a message to the child's input pipe and reads the echoed response from the child's output pipe to verify the communication. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0050-vm-syscalls-3/0050-vm-syscalls-3.md#_snippet_10 LANGUAGE: c CODE: ``` #include #include #include "ckb_syscalls.h" #define CKB_STDIN (0) #define CKB_STDOUT (1) // Function read_all reads from fd until an error or EOF and returns the data it read. int ckb_read_all(uint64_t fd, void* buffer, size_t* length) { int err = 0; size_t read_length = 0; size_t full_length = *length; uint8_t* b = buffer; while (true) { size_t n = full_length - read_length; err = ckb_read(fd, b, &n); if (err == CKB_OTHER_END_CLOSED) { err = 0; *length = read_length; break; } else { if (err != 0) { goto exit; } } if (full_length - read_length == 0) { err = CKB_LENGTH_NOT_ENOUGH; if (err != 0) { goto exit; } } b += n; read_length += n; *length = read_length; } exit: return err; } // Mimic stdio fds on linux int create_std_fds(uint64_t* fds, uint64_t* inherited_fds) { int err = 0; uint64_t to_child[2] = {0}; uint64_t to_parent[2] = {0}; err = ckb_pipe(to_child); if (err != 0) { goto exit; } err = ckb_pipe(to_parent); if (err != 0) { goto exit; } inherited_fds[0] = to_child[0]; inherited_fds[1] = to_parent[1]; inherited_fds[2] = 0; fds[CKB_STDIN] = to_parent[0]; fds[CKB_STDOUT] = to_child[1]; exit: return err; } int main() { int err = 0; const char* argv[] = {}; uint64_t pid = 0; uint64_t fds[2] = {0}; // it must be end with zero uint64_t inherited_fds[3] = {0}; err = create_std_fds(fds, inherited_fds); if (err != 0) { goto exit; } spawn_args_t spgs = { .argc = 0, .argv = argv, .process_id = &pid, .inherited_fds = inherited_fds, }; err = ckb_spawn(0, 3, 0, 0, &spgs); if (err != 0) { goto exit; } size_t length = 0; length = 12; err = ckb_write(fds[CKB_STDOUT], "Hello World!", &length); if (err != 0) { goto exit; } err = ckb_close(fds[CKB_STDOUT]); if (err != 0) { goto exit; } uint8_t buffer[1024] = {0}; length = 1024; err = ckb_read_all(fds[CKB_STDIN], buffer, &length); if (err != 0) { goto exit; } err = memcmp("Hello World!", buffer, length); if (err != 0) { goto exit; } exit: return err; } ``` ---------------------------------------- TITLE: Withdrawing UDT via Sender Lock Script (CKB Transaction) DESCRIPTION: Details a CKB transaction where the sender withdraws UDT and capacity from a Cheque cell without a signature specific to the Cheque cell (witnesses[0] is empty). The withdrawal, which is subject to a time lock (since: 0xA000000000000006), is authorized because the sender's lock script (sender_secp256k1_blake2b_lock_script) is present in another input cell (inputs[1]) which is unlocked by witnesses[1]. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0039-cheque/0039-cheque.md#_snippet_5 LANGUAGE: CKB Transaction Definition CODE: ``` inputs: cheque_cell: capacity: 165 CKBytes lock: code_hash: args: <20-byte_receiver_lock_hash> <20-byte_sender_lock_hash> type: data: sudt_amount: 100 UDT since: 0xA000000000000006 basic_cell: capacity: 200 CKBytes lock: outputs: sudt_cell: capacity: 165 CKBytes lock: type: data: sudt_amount: 100 UDT basic_cell: capacity: 199.99 CKBytes lock: witnesses: <0x> ``` ---------------------------------------- TITLE: Declaring CKB Cell Data Read API - C DESCRIPTION: Provides the C function signature for reading data from a CKB cell. This API allows a script running in the CKB VM to access the binary content of a cell, specified by its index and source (e.g., input or output cells). It returns a pointer to the data and its size. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0003-ckb-vm/0003-ckb-vm.md#_snippet_3 LANGUAGE: C CODE: ``` int ckb_read_cell_data(size_t index, size_t source, void** buffer, size_t* size); ``` ---------------------------------------- TITLE: Implementing UDT Token Transfer - C DESCRIPTION: Provides the C implementation for the `udt_transfer` function. This function handles the logic for transferring UDT tokens between two addresses within the `data_t` structure. It utilizes an internal helper `_udt_find_balance` to locate or create balance entries, checks for sufficient funds and potential overflow, and updates the token balances for the sender and receiver. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0003-ckb-vm/0003-ckb-vm.md#_snippet_6 LANGUAGE: C CODE: ``` int udt_transfer(data_t *data, const char from[ADDRESS_LENGTH], const char to[ADDRESS_LENGTH], int64_t tokens) { balance_t *from_balance = NULL, *to_balance = NULL; int ret = _udt_find_balance(data, from, 1, &from_balance); if (ret != 0) { return ret; } ret = _udt_find_balance(data, to, 1, &to_balance); if (ret != 0) { return ret; } if (from_balance->tokens < tokens) { return ERROR_NOT_SUFFICIENT_BALANCE; } int target = to_balance->tokens + tokens; if (target < to_balance->tokens) { return ERROR_OVERFLOW; } from_balance->tokens -= tokens; to_balance->tokens = target; return 0; } ``` ---------------------------------------- TITLE: Depositing CKB into Nervos DAO | CKB JSON DESCRIPTION: JSON structure representing a CKB transaction that deposits 200 CKB into the Nervos DAO. It includes 'cell_deps' for the DAO script and lock script, 'inputs' referencing the source cell, and 'outputs' with one for the DAO deposit and another for the change. The DAO output includes the DAO script as its 'type' script. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0023-dao-deposit-withdraw/0023-dao-deposit-withdraw.md#_snippet_2 LANGUAGE: JSON CODE: ``` { "version": "0x0", "cell_deps": [ { "out_point": { "tx_hash": "0x71a7ba8fc96349fea0ed3a5c47992e3b4084b031a42264a018e0072e8172e46c", "index": "0x0" }, "dep_type": "dep_group" }, { "out_point": { "tx_hash": "0xe2fb199810d49a4d8beec56718ba2593b665db9d52299a0f9e6e75416d73ff5c", "index": "0x2" }, "dep_type": "code" } ], "header_deps": [], "inputs": [ { "previous_output": { "tx_hash": "0xeb4644164c4dc64f195bb3b0c6e4f417e11519b1931e5f7177ff8008d96dbe83", "index": "0x1" }, "since": "0x0" } ], "outputs": [ { "capacity": "0x2e90edd000", "lock": { "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", "args": "0xe5f99902495d04d9dcb013aefc96093d365b77dc", "hash_type": "type" }, "type": { "code_hash": "0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e", "args": "0x", "hash_type": "type" } }, { "capacity": "0x101db898cb1", "lock": { "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", "args": "0x9776eaa16af9cd8b6a2d169ae95671b0bcb8b0c4", "hash_type": "type" }, "type": null } ], "outputs_data": [ "0x0000000000000000", "0x" ], "witnesses": [ "0x5500000010000000550000005500000041000000c22c72efb85da607ac48b220ad5b7132dc7abe50c3337c9a51e75102e8efaa5557e8b0567f9e0d9753016ebd52be3091bd55d4b87d7d4845f0d56ccf06e6ffe400" ], "hash": "0x81c400a761b0b5f1d8b00d8939e5a729d21d25a08e14e54f0661cb4f6fc6fb81" } ``` ---------------------------------------- TITLE: Loading Cell Input Field (CKB VM Syscall) in C DESCRIPTION: This C function wraps the `ckb_load_input_by_field` syscall to retrieve a specific field (`field`) from a transaction input identified by `index` and `source`. It only supports input cell sources. The retrieved data is loaded into VM memory using the partial loading parameters `addr`, `len`, and `offset`. The syscall returns 0 on success, 1 for an out-of-bounds index, 2 for a non-input source, or triggers a VM error for invalid source or field values. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#_snippet_13 LANGUAGE: C CODE: ``` int ckb_load_input_by_field(void* addr, uint64_t* len, size_t offset, size_t index, size_t source, size_t field) { return syscall(2083, addr, len, offset, index, source, field); } ``` ---------------------------------------- TITLE: Executing New Program (C) DESCRIPTION: This C function wraps the CKB VM syscall 2043, which loads and executes a new program from specified cell data or witness within the existing VM context. It replaces the current code, registers, and memory but keeps the cycle count. It requires parameters for source index, type (input, output, dep, same script), location (data/witness), bounds (offset/length), argument count, and arguments. Cycle cost is fixed (500) plus initial loading cycles. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0034-vm-syscalls-2/0034-vm-syscalls-2.md#_snippet_2 LANGUAGE: C CODE: ``` int ckb_exec(size_t index, size_t source, size_t place, size_t bounds, int argc, char* argv[]) { return syscall(2043, index, source, place, bounds, argc, argv); } ``` ---------------------------------------- TITLE: Loading Cell Data as Executable Code (CKB VM Syscall) in C DESCRIPTION: This C function interfaces with the `ckb_load_cell_data_as_code` syscall, designed for dynamic code loading. It loads a specified section (`content_offset`, `content_size`) of a cell's data into a VM memory buffer (`addr`, `memory_size`) and marks the memory page as executable. Unlike other load syscalls, it doesn't use partial loading but requires `addr` and `memory_size` to be 4KB aligned/multiples, returning 0 on success or triggering VM errors on various failures including invalid source, index out of bounds, or incorrect memory parameters. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#_snippet_11 LANGUAGE: C CODE: ``` int ckb_load_cell_data_as_code(void* addr, size_t memory_size, size_t content_offset, size_t content_size, size_t index, size_t source) { return syscall(2091, addr, memory_size, content_offset, content_size, index, source); } ``` ---------------------------------------- TITLE: Calling UDT Function via ckb_mmap_cell - CKB Script DESCRIPTION: Illustrates a CKB script's `main` function that executes a UDT function (like `udt_transfer`) by mapping an external cell's content into executable memory using `ckb_mmap_cell`. It reads input and output cell data, casts the mapped memory to a function pointer type, calls the function, and finally validates the state change by comparing the input and output data structures. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0003-ckb-vm/0003-ckb-vm.md#_snippet_8 LANGUAGE: C CODE: ``` typedef int *transfer(data_t *, const char*, const char*, int64_t); int main(int argc, char* argv[]) { data_t *input_data = NULL; ret = ckb_read_cell(0, CKB_SOURCE_INPUT, (void **) &input_data, NULL); if (ret != 0) { return ret; } data_t *output_data = NULL; ret = ckb_read_cell(1, CKB_SOURCE_OUTPUT, (void **) &output_data, NULL); if (ret != 0) { return ret; } transfer *f = (transfer *) ckb_mmap_cell(function_cell_id, 0, -1, PROT_EXEC); ret = f(input_data, from, to, 100); if (ret != 0) { return ret; } if (memcmp(input_data, output_data, sizeof(data_t)) != 0) { return -1; } return 0; } ``` ---------------------------------------- TITLE: Declaring CKB UDT API Functions - C DESCRIPTION: Lists the C function signatures for the standard User Defined Token (UDT) operations. These functions are designed to operate on the `data_t` structure, managing token balances, transfers, allowances, and providing information like total supply and account balances. SOURCE: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0003-ckb-vm/0003-ckb-vm.md#_snippet_2 LANGUAGE: C CODE: ``` int udt_initialize(data_t *data, char owner[ADDRESS_LENGTH], int64_t total_supply); int udt_total_supply(const data_t *data); int64_t udt_balance_of(data_t *data, const char address[ADDRESS_LENGTH]); int udt_transfer(data_t *data, const char from[ADDRESS_LENGTH], const char to[ADDRESS_LENGTH], int64_t tokens); int udt_approve(data_t *data, const char from[ADDRESS_LENGTH], const char spender[ADDRESS_LENGTH], int64_t tokens); int udt_transfer_from(data_t *data, const char from[ADDRESS_LENGTH], const char spender[ADDRESS_LENGTH], const char to[ADDRESS_LENGTH], int64_t tokens); ```