### CKB VM Simulator Setup Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt This section outlines how to set up and compile CKB scripts for the CKB VM simulator. It shows conditional includes for simulator-specific syscalls and provides example compilation and execution commands. ```c // In your script source, guard CKB code with the macro: #ifdef CKB_SIMULATOR #include "ckb_syscall_simulator.h" #else #include "ckb_syscalls.h" #endif // Compile for simulator: // gcc -D CKB_SIMULATOR -I . -I simulator script.c simulator/ckb_syscall_sim.c \ // simulator/blake2b_imp.c -L simulator/build.simulator -lckb_simulator -o script_sim // data.json (root descriptor): // { // "is_lock_script": true, // "script_index": 0, // "main": "0xa98c212cf055...", // "0xa98c212cf055...": "original_tx.json" // } // Run: // ./script_sim data.json // Returns 0 on success, non-zero on script failure ``` -------------------------------- ### Execute and Spawn Scripts (VM v1 & v2) Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt Replace the current VM with another script using `ckb_exec` or launch a new process with `ckb_spawn`. Ensure correct arguments and source parameters are provided. ```c // exec: replace current VM with another script const char *exec_argv[] = {"arg0", "arg1", NULL}; ret = ckb_exec(0, CKB_SOURCE_CELL_DEP, 0, 0, 2, exec_argv); ``` ```c /* --- VM v2: spawn / IPC --- */ uint64_t pid = 0; uint64_t inherited[3] = {0}; // no inherited fds spawn_args_t sargs = { .argc = 0, .argv = NULL, .process_id = &pid, .inherited_fds = inherited, }; ret = ckb_spawn(0, CKB_SOURCE_CELL_DEP, 0, 0, &sargs); // pid now holds child process id ``` -------------------------------- ### Running Simulator Executables Source: https://github.com/nervosnetwork/ckb-c-stdlib/blob/master/simulator/README.md These commands demonstrate how to run the simulator executables with a provided JSON configuration file. The first argument is the name of the JSON file containing the simulation data. ```bash ../build.simulator/sighash_all data.json ../build.simulator/sighash_all data2.json ../build.simulator/sighash_all data3.json ../build.simulator/sudt sudt_data.json ``` -------------------------------- ### Load Block Extension (VM v2) Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt Load block extension data into a buffer. Specify the buffer, its size, and the source of the extension data. ```c // Load block extension uint8_t ext[4096]; len = sizeof(ext); ret = ckb_load_block_extension(ext, &len, 0, 0, CKB_SOURCE_HEADER_DEP); ``` -------------------------------- ### BLAKE2b Hashing with blake2b.h Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt Provides a CKB-flavored BLAKE2b implementation. Use ckb_blake2b_init for on-chain compatibility. Supports streaming, one-shot, and keyed hashing. ```c #include "blake2b.h" /* --- Streaming API --- */ blake2b_state S; cbk_blake2b_init(&S, 32); // 32-byte digest, CKB personalization uint8_t data[] = "hello ckb"; blake2b_update(&S, data, sizeof(data) - 1); uint8_t digest[32]; blake2b_final(&S, digest, 32); // digest holds the 32-byte CKB hash /* --- One-shot API --- */ uint8_t out[32]; blake2b(out, 32, data, sizeof(data) - 1, NULL, 0); /* --- Keyed hashing --- */ uint8_t key[32] = { /* 32-byte key */ }; blake2b_state Sk; blake2b_init_key(&Sk, 32, key, 32); blake2b_update(&Sk, data, sizeof(data) - 1); blake2b_final(&Sk, digest, 32); ``` -------------------------------- ### Load Transaction Data (VM v0) Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt Use these functions to load various transaction-related data into buffers. Ensure sufficient buffer size; otherwise, the operation might be truncated or fail. ```c #include "ckb_syscalls.h" // includes ckb_raw_syscalls.h + ckb_syscall_utils.h /* --- VM v0: Load transaction data --- */ // Load current transaction hash into buf uint8_t tx_hash[32]; uint64_t len = 32; int ret = ckb_load_tx_hash(tx_hash, &len, 0); // ret == CKB_SUCCESS, len == 32 // Load current script uint8_t script_buf[4096]; len = sizeof(script_buf); ret = ckb_load_script(script_buf, &len, 0); // Load full transaction (serialized Molecule) uint8_t tx_buf[32768]; len = sizeof(tx_buf); ret = ckb_load_transaction(tx_buf, &len, 0); // Load a cell from inputs uint8_t cell_buf[512]; len = sizeof(cell_buf); ret = ckb_load_cell(cell_buf, &len, 0, 0, CKB_SOURCE_INPUT); // index=0, source=CKB_SOURCE_INPUT // Load a witness uint8_t witness[32768]; len = sizeof(witness); ret = ckb_load_witness(witness, &len, 0, 0, CKB_SOURCE_INPUT); // Load a specific field from a cell (e.g., capacity) uint8_t capacity_buf[8]; len = 8; ret = ckb_load_cell_by_field(capacity_buf, &len, 0, 0, CKB_SOURCE_INPUT, CKB_CELL_FIELD_CAPACITY); // Load raw cell data uint8_t data[4096]; len = sizeof(data); ret = ckb_load_cell_data(data, &len, 0, 0, CKB_SOURCE_CELL_DEP); // Load cell data as executable code into memory uint8_t code_region[0x100000]; ret = ckb_load_cell_data_as_code(code_region, sizeof(code_region), 0, 0xFFFF, 0, CKB_SOURCE_CELL_DEP); // Debug output ckb_debug("entering lock script validation"); ``` -------------------------------- ### Streaming Hash Utilities with ckb_streaming.h Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt Batch-loads CKB data items into a BLAKE2b context for hashing large data without large stack buffers. Requires including ckb_streaming.h and blake2b.h. ```c #include "ckb_streaming.h" #include "blake2b.h" blake2b_state ctx; ckb_blake2b_init(&ctx, 32); // Hash all data for cell at index 0 in CELL_DEP int ret = ckb_hash_cell(&ctx, 0, CKB_SOURCE_CELL_DEP); if (ret != CKB_SUCCESS) { ckb_exit(ret); } // Hash input at index 0 in GROUP_INPUT ret = ckb_hash_input(&ctx, 0, CKB_SOURCE_GROUP_INPUT); if (ret != CKB_SUCCESS) { ckb_exit(ret); } // Finalize uint8_t digest[32]; blake2b_final(&ctx, digest, 32); // Or use ckb_load_and_hash with a custom load function: ret = ckb_load_and_hash(&ctx, /*start_offset=*/0, 0, CKB_SOURCE_INPUT, ckb_load_witness); blake2b_final(&ctx, digest, 32); ``` -------------------------------- ### Keccak-256 Hashing with ckb_keccak256.h Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt Implements Keccak-256 hashing, compatible with Ethereum's keccak256. Requires including ckb_keccak256.h. ```c #include "ckb_keccak256.h" SHA3_CTX ctx; keccak_init(&ctx); uint8_t msg[] = "Ethereum compatible message"; keccak_update(&ctx, msg, (uint16_t)(sizeof(msg) - 1)); uint8_t hash[32]; keccak_final(&ctx, hash); // hash holds 32-byte Keccak-256 digest (compatible with Ethereum keccak256) ``` -------------------------------- ### Raw Syscall API - VM v2 Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt Functions for process spawning, inter-process communication (IPC), and exiting the script. ```APIDOC ## ckb_spawn ### Description Spawns a new process. ### Method `int ckb_spawn(uint64_t index, uint64_t source, uint64_t offset, uint64_t length, spawn_args_t *sargs) ### Parameters #### Path Parameters - `index` (uint64_t) - The index of the script to spawn. - `source` (uint64_t) - The source of the script (e.g., CKB_SOURCE_CELL_DEP). - `offset` (uint64_t) - Offset into the script data. - `length` (uint64_t) - Length of the script data. - `sargs` (spawn_args_t *) - Structure containing arguments for the new process. ### Request Example ```c uint64_t pid = 0; uint64_t inherited[3] = {0}; spawn_args_t sargs = { .argc = 0, .argv = NULL, .process_id = &pid, .inherited_fds = inherited, }; ret = ckb_spawn(0, CKB_SOURCE_CELL_DEP, 0, 0, &sargs); ``` ``` ```APIDOC ## ckb_wait ### Description Waits for a child process to finish. ### Method `int ckb_wait(uint64_t pid, int8_t *exit_code) ### Parameters #### Path Parameters - `pid` (uint64_t) - The process ID of the child to wait for. - `exit_code` (int8_t *) - Pointer to store the exit code of the child process. ### Request Example ```c int8_t exit_code = 0; ret = ckb_wait(pid, &exit_code); ``` ``` ```APIDOC ## ckb_pipe ### Description Creates a pipe for inter-process communication. ### Method `int ckb_pipe(uint64_t fds[2]) ### Parameters #### Path Parameters - `fds` (uint64_t[2]) - An array to store the file descriptors for the pipe ends. ### Response #### Success Response - `fds[0]` is the read end, `fds[1]` is the write end. ### Request Example ```c uint64_t fds[2]; ckb_pipe(fds); ``` ``` ```APIDOC ## ckb_write ### Description Writes data to a pipe. ### Method `int ckb_write(uint64_t fd, const void *buf, size_t *len) ### Parameters #### Path Parameters - `fd` (uint64_t) - The file descriptor of the write end of the pipe. - `buf` (const void *) - The data to write. - `len` (size_t *) - Pointer to the number of bytes to write. Will be updated with the number of bytes actually written. ### Request Example ```c size_t wlen = 5; ckb_write(fds[1], "hello", &wlen); ``` ``` ```APIDOC ## ckb_read ### Description Reads data from a pipe. ### Method `int ckb_read(uint64_t fd, void *buf, size_t *len) ### Parameters #### Path Parameters - `fd` (uint64_t) - The file descriptor of the read end of the pipe. - `buf` (void *) - Buffer to store the read data. - `len` (size_t *) - Pointer to the number of bytes to read. Will be updated with the number of bytes actually read. ### Request Example ```c uint8_t rbuf[16]; size_t rlen = sizeof(rbuf); ckb_read(fds[0], rbuf, &rlen); ``` ``` ```APIDOC ## ckb_close ### Description Closes a file descriptor. ### Method `int ckb_close(uint64_t fd) ### Parameters #### Path Parameters - `fd` (uint64_t) - The file descriptor to close. ### Request Example ```c ckb_close(fds[0]); ckb_close(fds[1]); ``` ``` ```APIDOC ## ckb_process_id ### Description Returns the current process ID. ### Method `uint64_t ckb_process_id(void) ### Response #### Success Response - Returns the current process ID. ### Request Example ```c uint64_t my_pid = ckb_process_id(); ``` ``` ```APIDOC ## ckb_load_block_extension ### Description Loads the block extension data into a buffer. ### Method `int ckb_load_block_extension(uint8_t *buf, uint64_t *len, uint64_t offset, uint64_t index, uint64_t source) ### Parameters #### Path Parameters - `buf` (uint8_t *) - Buffer to store the block extension data. - `len` (uint64_t *) - Pointer to the length of the buffer. Will be updated with the actual length of the block extension data. - `offset` (uint64_t) - Offset into the data to load. - `index` (uint64_t) - The index of the block extension. - `source` (uint64_t) - The source of the block extension (e.g., CKB_SOURCE_HEADER_DEP). ### Request Example ```c uint8_t ext[4096]; len = sizeof(ext); ret = ckb_load_block_extension(ext, &len, 0, 0, CKB_SOURCE_HEADER_DEP); ``` ``` ```APIDOC ## ckb_exit ### Description Exits the current script with a status code. ### Method `void ckb_exit(int8_t code) ### Parameters #### Path Parameters - `code` (int8_t) - The exit status code. ### Request Example ```c ckb_exit(0); // success ckb_exit(1); // failure ``` ``` -------------------------------- ### Checked Load Utilities Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt Safer wrappers around raw load syscalls that return CKB_LENGTH_NOT_ENOUGH if the buffer is too small. ```APIDOC ## ckb_checked_load_tx_hash ### Description Safely loads the current transaction hash into a buffer, returning an error if the buffer is too small. ### Method `int ckb_checked_load_tx_hash(uint8_t *buf, uint64_t *len, uint64_t offset) ### Parameters #### Path Parameters - `buf` (uint8_t *) - Buffer to store the transaction hash. - `len` (uint64_t *) - Pointer to the length of the buffer. Will be updated with the actual length of the hash, or the required size if `CKB_LENGTH_NOT_ENOUGH` is returned. - `offset` (uint64_t) - Offset into the data to load. ### Response #### Error Response (CKB_LENGTH_NOT_ENOUGH) - `len` will hold the required buffer size. ### Request Example ```c uint8_t hash[32]; uint64_t len = 32; int ret = ckb_checked_load_tx_hash(hash, &len, 0); if (ret == CKB_LENGTH_NOT_ENOUGH) { // buffer was too small; len now holds required size } ``` ``` ```APIDOC ## ckb_checked_load_cell ### Description Safely loads data from a cell into a buffer, returning an error if the buffer is too small. ### Method `int ckb_checked_load_cell(uint8_t *buf, uint64_t *len, uint64_t offset, uint64_t index, uint64_t source) ### Parameters #### Path Parameters - `buf` (uint8_t *) - Buffer to store the cell data. - `len` (uint64_t *) - Pointer to the length of the buffer. Will be updated with the actual length of the cell data, or the required size if `CKB_LENGTH_NOT_ENOUGH` is returned. - `offset` (uint64_t) - Offset into the data to load. - `index` (uint64_t) - The index of the cell. - `source` (uint64_t) - The source of the cell (e.g., CKB_SOURCE_GROUP_INPUT). ### Response #### Error Response (CKB_LENGTH_NOT_ENOUGH) - `len` will hold the required buffer size. ### Request Example ```c uint8_t cell[256]; len = sizeof(cell); ret = ckb_checked_load_cell(cell, &len, 0, 0, CKB_SOURCE_GROUP_INPUT); ``` ``` ```APIDOC ## ckb_load_actual_type_witness ### Description Loads the actual type witness for the current type script group, automatically determining the source (input or output). ### Method `int ckb_load_actual_type_witness(uint8_t *buf, uint64_t *len, uint64_t offset, uint64_t *type_source) ### Parameters #### Path Parameters - `buf` (uint8_t *) - Buffer to store the witness. - `len` (uint64_t *) - Pointer to the length of the buffer. Will be updated with the actual length of the witness. - `offset` (uint64_t) - Offset into the data to load. - `type_source` (uint64_t *) - Pointer to store the source of the witness (CKB_SOURCE_GROUP_INPUT or CKB_SOURCE_GROUP_OUTPUT). ### Request Example ```c uint8_t witness[32768]; len = sizeof(witness); size_t type_source; ret = ckb_load_actual_type_witness(witness, &len, 0, &type_source); ``` ``` ```APIDOC ## ckb_calculate_inputs_len ### Description Calculates the total number of inputs using binary search. ### Method `int ckb_calculate_inputs_len(void) ### Response #### Success Response - Returns the total number of inputs. ### Request Example ```c int input_count = ckb_calculate_inputs_len(); ``` ``` ```APIDOC ## ckb_look_for_dep_with_hash2 ### Description Finds a dependency cell by its code hash and hash type. ### Method `int ckb_look_for_dep_with_hash2(const uint8_t *code_hash, uint8_t hash_type, uint64_t *dep_index) ### Parameters #### Path Parameters - `code_hash` (const uint8_t *) - The 32-byte code hash of the dependency. - `hash_type` (uint8_t) - The hash type (0 for data, 1 for type). - `dep_index` (uint64_t *) - Pointer to store the index of the dependency cell in CKB_SOURCE_CELL_DEP. ### Request Example ```c uint8_t code_hash[32] = { /* 32-byte hash */ }; size_t dep_index; ret = ckb_look_for_dep_with_hash2(code_hash, /*hash_type=*/0, &dep_index); if (ret == CKB_SUCCESS) { // dep_index is valid index in CKB_SOURCE_CELL_DEP } ``` ``` ```APIDOC ## ckb_exec_cell ### Description Executes a cell found by its code hash. This replaces the current VM. ### Method `int ckb_exec_cell(const uint8_t *code_hash, uint8_t hash_type, uint64_t offset, uint64_t length, uint64_t argc, const char *argv[]) ### Parameters #### Path Parameters - `code_hash` (const uint8_t *) - The 32-byte code hash of the cell to execute. - `hash_type` (uint8_t) - The hash type (0 for data, 1 for type). - `offset` (uint64_t) - Offset into the cell data. - `length` (uint64_t) - Length of the cell data. - `argc` (uint64_t) - The number of arguments. - `argv` (const char *[]) - An array of arguments for the new script. ### Request Example ```c const char *argv[] = {"param1"}; ret = ckb_exec_cell(code_hash, /*hash_type=*/1, 0, 0, 1, argv); ``` ``` ```APIDOC ## ckb_spawn_cell ### Description Spawns a cell found by its code hash. ### Method `int ckb_spawn_cell(const uint8_t *code_hash, uint8_t hash_type, uint64_t offset, uint64_t length, spawn_args_t *sargs) ### Parameters #### Path Parameters - `code_hash` (const uint8_t *) - The 32-byte code hash of the cell to spawn. - `hash_type` (uint8_t) - The hash type (0 for data, 1 for type). - `offset` (uint64_t) - Offset into the cell data. - `length` (uint64_t) - Length of the cell data. - `sargs` (spawn_args_t *) - Structure containing arguments for the new process. ### Request Example ```c uint64_t child_pid = 0; const uint64_t no_fds[] = {0}; spawn_args_t sa = { .argc=1, .argv=argv, .process_id=&child_pid, .inherited_fds=no_fds }; ret = ckb_spawn_cell(code_hash, 1, 0, 0, &sa); ``` ``` -------------------------------- ### Spawn Dependency Cell Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt Launch a new process by spawning a dependency cell identified by its code hash and hash type. Configure arguments and inherited file descriptors. ```c // Spawn a cell found by code_hash uint64_t child_pid = 0; const uint64_t no_fds[] = {0}; spawn_args_t sa = { .argc=1, .argv=argv, .process_id=&child_pid, .inherited_fds=no_fds }; ret = ckb_spawn_cell(code_hash, 1, 0, 0, &sa); ``` -------------------------------- ### VM Version and Cycle Information (VM v1) Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt Retrieve the current CKB VM version and the number of cycles consumed. These are useful for understanding the execution environment and resource usage. ```c /* --- VM v1 --- */ int version = ckb_vm_version(); // returns 1 or 2 uint64_t cycles = ckb_current_cycles(); ``` -------------------------------- ### Raw Syscall API - VM v1 Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt Functions for checking VM version and current cycles, and for executing other scripts. ```APIDOC ## ckb_vm_version ### Description Returns the current CKB VM version. ### Method `int ckb_vm_version(void) ### Response #### Success Response - Returns 1 or 2, indicating the VM version. ### Request Example ```c int version = ckb_vm_version(); ``` ``` ```APIDOC ## ckb_current_cycles ### Description Returns the number of cycles consumed by the VM so far. ### Method `uint64_t ckb_current_cycles(void) ### Response #### Success Response - Returns the current cycle count. ### Request Example ```c uint64_t cycles = ckb_current_cycles(); ``` ``` ```APIDOC ## ckb_exec ### Description Replaces the current VM with another script. ### Method `int ckb_exec(uint64_t index, uint64_t source, uint64_t offset, uint64_t length, uint64_t argc, const char *argv[]) ### Parameters #### Path Parameters - `index` (uint64_t) - The index of the script to execute. - `source` (uint64_t) - The source of the script (e.g., CKB_SOURCE_CELL_DEP). - `offset` (uint64_t) - Offset into the script data. - `length` (uint64_t) - Length of the script data. - `argc` (uint64_t) - The number of arguments. - `argv` (const char *[]) - An array of arguments for the new script. ### Request Example ```c const char *exec_argv[] = {"arg0", "arg1", NULL}; ret = ckb_exec(0, CKB_SOURCE_CELL_DEP, 0, 0, 2, exec_argv); ``` ``` -------------------------------- ### Epoch and Since Comparison Utilities Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt This snippet shows how to use `ckb_utils.h` to compare CKB 'since' values, which can represent block numbers, timestamps, or epoch fractions. It loads an input 'since' value and compares it against a required 'since' value, handling different 'since' types. ```c #include "ckb_utils.h" #include "ckb_syscalls.h" // Load input since value uint8_t since_buf[8]; uint64_t len = 8; cbk_load_input_by_field(since_buf, &len, 0, 0, CKB_SOURCE_INPUT, CKB_INPUT_FIELD_SINCE); uint64_t input_since; memcpy(&input_since, since_buf, 8); // Minimum required since (epoch fraction encoded: length=1800, index=0, number=100) // Encoding: bits[0..23]=epoch_number, bits[24..39]=index, bits[40..55]=length, bits[56..63]=flags uint64_t required_since = 0x20000000001000064ULL; // example epoch-fraction since int comparable = 0; int cmp = ckb_since_cmp(input_since, required_since, &comparable); if (!comparable) { // Different flag types (e.g., one is block-number, other is epoch) — reject return 1; } if (cmp < 0) { // input_since is earlier than required — time lock not satisfied return 1; } // Time lock satisfied // Compare raw epoch fractions directly uint64_t epoch_a = 0x000000000001000064ULL; // epoch 100, index 0/1800 uint64_t epoch_b = 0x000000000001000065ULL; // epoch 101, index 0/1800 int res = ckb_epoch_number_with_fraction_cmp(epoch_a, epoch_b); // res == -1: a < b ``` -------------------------------- ### Raw Syscall API - VM v0 Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt Functions for loading transaction data, scripts, cells, and witnesses within VM version 0. ```APIDOC ## ckb_load_tx_hash ### Description Loads the current transaction hash into a buffer. ### Method `ckb_load_tx_hash(uint8_t *buf, uint64_t *len, uint64_t offset) ### Parameters #### Path Parameters - `buf` (uint8_t *) - Buffer to store the transaction hash. - `len` (uint64_t *) - Pointer to the length of the buffer. Will be updated with the actual length of the hash. - `offset` (uint64_t) - Offset into the data to load. ### Response #### Success Response (CKB_SUCCESS) - `len` will be updated to 32. ### Request Example ```c uint8_t tx_hash[32]; uint64_t len = 32; int ret = ckb_load_tx_hash(tx_hash, &len, 0); ``` ``` ```APIDOC ## ckb_load_script ### Description Loads the current script into a buffer. ### Method `ckb_load_script(uint8_t *buf, uint64_t *len, uint64_t offset) ### Parameters #### Path Parameters - `buf` (uint8_t *) - Buffer to store the script. - `len` (uint64_t *) - Pointer to the length of the buffer. Will be updated with the actual length of the script. - `offset` (uint64_t) - Offset into the data to load. ### Request Example ```c uint8_t script_buf[4096]; len = sizeof(script_buf); ret = ckb_load_script(script_buf, &len, 0); ``` ``` ```APIDOC ## ckb_load_transaction ### Description Loads the full transaction (serialized Molecule) into a buffer. ### Method `ckb_load_transaction(uint8_t *buf, uint64_t *len, uint64_t offset) ### Parameters #### Path Parameters - `buf` (uint8_t *) - Buffer to store the transaction. - `len` (uint64_t *) - Pointer to the length of the buffer. Will be updated with the actual length of the transaction. - `offset` (uint64_t) - Offset into the data to load. ### Request Example ```c uint8_t tx_buf[32768]; len = sizeof(tx_buf); ret = ckb_load_transaction(tx_buf, &len, 0); ``` ``` ```APIDOC ## ckb_load_cell ### Description Loads data from a cell (inputs, outputs, dep) into a buffer. ### Method `ckb_load_cell(uint8_t *buf, uint64_t *len, uint64_t offset, uint64_t index, uint64_t source) ### Parameters #### Path Parameters - `buf` (uint8_t *) - Buffer to store the cell data. - `len` (uint64_t *) - Pointer to the length of the buffer. Will be updated with the actual length of the cell data. - `offset` (uint64_t) - Offset into the data to load. - `index` (uint64_t) - The index of the cell to load. - `source` (uint64_t) - The source of the cell (e.g., CKB_SOURCE_INPUT). ### Request Example ```c uint8_t cell_buf[512]; len = sizeof(cell_buf); ret = ckb_load_cell(cell_buf, &len, 0, 0, CKB_SOURCE_INPUT); ``` ``` ```APIDOC ## ckb_load_witness ### Description Loads a witness into a buffer. ### Method `ckb_load_witness(uint8_t *buf, uint64_t *len, uint64_t offset, uint64_t index, uint64_t source) ### Parameters #### Path Parameters - `buf` (uint8_t *) - Buffer to store the witness. - `len` (uint64_t *) - Pointer to the length of the buffer. Will be updated with the actual length of the witness. - `offset` (uint64_t) - Offset into the data to load. - `index` (uint64_t) - The index of the witness. - `source` (uint64_t) - The source of the witness (e.g., CKB_SOURCE_INPUT). ### Request Example ```c uint8_t witness[32768]; len = sizeof(witness); ret = ckb_load_witness(witness, &len, 0, 0, CKB_SOURCE_INPUT); ``` ``` ```APIDOC ## ckb_load_cell_by_field ### Description Loads a specific field from a cell into a buffer. ### Method `ckb_load_cell_by_field(uint8_t *buf, uint64_t *len, uint64_t offset, uint64_t index, uint64_t source, uint64_t field) ### Parameters #### Path Parameters - `buf` (uint8_t *) - Buffer to store the field data. - `len` (uint64_t *) - Pointer to the length of the buffer. Will be updated with the actual length of the field data. - `offset` (uint64_t) - Offset into the data to load. - `index` (uint64_t) - The index of the cell. - `source` (uint64_t) - The source of the cell. - `field` (uint64_t) - The field to load (e.g., CKB_CELL_FIELD_CAPACITY). ### Request Example ```c uint8_t capacity_buf[8]; len = 8; ret = ckb_load_cell_by_field(capacity_buf, &len, 0, 0, CKB_SOURCE_INPUT, CKB_CELL_FIELD_CAPACITY); ``` ``` ```APIDOC ## ckb_load_cell_data ### Description Loads the raw data of a cell into a buffer. ### Method `ckb_load_cell_data(uint8_t *buf, uint64_t *len, uint64_t offset, uint64_t index, uint64_t source) ### Parameters #### Path Parameters - `buf` (uint8_t *) - Buffer to store the cell data. - `len` (uint64_t *) - Pointer to the length of the buffer. Will be updated with the actual length of the cell data. - `offset` (uint64_t) - Offset into the data to load. - `index` (uint64_t) - The index of the cell. - `source` (uint64_t) - The source of the cell. ### Request Example ```c uint8_t data[4096]; len = sizeof(data); ret = ckb_load_cell_data(data, &len, 0, 0, CKB_SOURCE_CELL_DEP); ``` ``` ```APIDOC ## ckb_load_cell_data_as_code ### Description Loads cell data into memory as executable code. ### Method `ckb_load_cell_data_as_code(uint8_t *buf, uint64_t size, uint64_t offset, uint64_t index, uint64_t source) ### Parameters #### Path Parameters - `buf` (uint8_t *) - Buffer to store the executable code. - `size` (uint64_t) - The maximum size of the buffer. - `offset` (uint64_t) - Offset into the data to load. - `index` (uint64_t) - The index of the cell. - `source` (uint64_t) - The source of the cell. ### Request Example ```c uint8_t code_region[0x100000]; ret = ckb_load_cell_data_as_code(code_region, sizeof(code_region), 0, 0xFFFF, 0, CKB_SOURCE_CELL_DEP); ``` ``` ```APIDOC ## ckb_debug ### Description Outputs a debug message. ### Method `ckb_debug(const char *msg) ### Parameters #### Path Parameters - `msg` (const char *) - The debug message string. ### Request Example ```c ckb_debug("entering lock script validation"); ``` ``` -------------------------------- ### Swappable Signature Verification - ckb_swappable_signatures.h Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt Provides a convention for dynamically loading any signature algorithm from a dep cell, as long as it exports `load_prefilled_data` and `validate_signature`. ```APIDOC ## ckb_initialize_swappable_signature ### Description Initializes a `CkbSwappableSignatureInstance` by loading a signature algorithm from a dep cell. ### Method `int ckb_initialize_swappable_signature(const uint8_t *algo_code_hash, uint32_t hash_type, CkbSwappableSignatureInstance *sig_instance)` ### Parameters #### Path Parameters - `algo_code_hash` (const uint8_t *) - Hash of the algorithm's code cell. - `hash_type` (uint32_t) - Type of hash (0 for data hash, 1 for type hash). - `sig_instance` (CkbSwappableSignatureInstance *) - Pointer to the signature instance to initialize. ### Response #### Success Response (CKB_SUCCESS) Returns `CKB_SUCCESS` on successful initialization. #### Error Response Returns a non-zero error code on failure. ## verify_func (within CkbSwappableSignatureInstance) ### Description This function pointer, once resolved, is used to validate a signature against a message using the loaded algorithm. ### Method `int verify_func(const uint8_t *prefilled_data, const uint8_t *sig, size_t sig_len, const uint8_t *msg, size_t msg_len, uint8_t *out, size_t *out_len)` ### Parameters #### Path Parameters - `prefilled_data` (const uint8_t *) - Prefilled data buffer from the signature instance. - `sig` (const uint8_t *) - The signature to verify. - `sig_len` (size_t) - The length of the signature. - `msg` (const uint8_t *) - The message hash to verify against. - `msg_len` (size_t) - The length of the message hash. - `out` (uint8_t *) - Buffer to store output data (e.g., public key). - `out_len` (size_t *) - Pointer to the size of the output buffer, updated with the actual size of the output data. ### Response #### Success Response (0) Returns 0 on successful signature validation. #### Error Response Returns a non-zero error code on failure. ``` -------------------------------- ### Minimal libc Shim for CKB Scripts Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt This snippet demonstrates the usage of the minimal libc implementation provided by ckb-c-stdlib. It includes memory management, string operations, and I/O via ckb_debug. Ensure correct compile flags and link options are used. ```c // Compile flags: -I libc -I . // For printf support: -D CKB_C_STDLIB_PRINTF -fno-builtin-printf // Link: -nostdlib -nostartfiles #include // defines _start, pulls in libc/src/impl.c #include // memset, memcpy, memmove, memcmp, strlen, strcmp, strcpy, strstr #include // malloc, free, calloc, realloc, qsort, bsearch #include // printf, ckb_printf (both output via ckb_debug syscall) #include // uint8_t, uint32_t, uint64_t, int8_t, ... #include // bool, true, false #include // size_t, NULL int main(int argc, const char *argv[]) { // Stack-pointer alignment patch (for ckb-vm < 0.20) // CKB_SP_ALIGN; uint8_t *buf = (uint8_t *)malloc(256); if (!buf) return 1; memset(buf, 0xAB, 256); memcpy(buf, "CKB Script", 10); size_t slen = strlen((char *)buf); // 10 #ifdef CKB_C_STDLIB_PRINTF printf("buf starts with: %.*s, len=%zu\n", 10, buf, slen); // Output via ckb_debug syscall (visible in CKB node logs) #endif free(buf); return 0; // _start will ecall exit with this return value } ``` -------------------------------- ### Checked Load Utilities - Safe Data Loading Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt These utilities provide safer alternatives to raw load syscalls by returning `CKB_LENGTH_NOT_ENOUGH` if the buffer is too small, preventing silent truncation. ```c #include "ckb_syscalls.h" // Safe load — errors if actual data > buffer uint8_t hash[32]; uint64_t len = 32; int ret = ckb_checked_load_tx_hash(hash, &len, 0); if (ret == CKB_LENGTH_NOT_ENOUGH) { // buffer was too small; len now holds required size } // Safe cell load uint8_t cell[256]; len = sizeof(cell); ret = ckb_checked_load_cell(cell, &len, 0, 0, CKB_SOURCE_GROUP_INPUT); ``` -------------------------------- ### Exec Argument Encoding/Decoding - ckb_exec.h Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt Utilities for packing binary data into hex-encoded `argv` strings for passing across `ckb_exec` / `ckb_spawn` boundaries, and unpacking them on the receiving side. ```APIDOC ## ckb_exec_reset ### Description Resets the `CkbBinaryArgsType` structure to prepare for appending arguments. ### Method `void ckb_exec_reset(CkbBinaryArgsType *bin_args)` ### Parameters #### Path Parameters - `bin_args` (CkbBinaryArgsType *) - Pointer to the binary arguments structure. ## ckb_exec_append ### Description Appends a binary argument to the `CkbBinaryArgsType` structure. ### Method `int ckb_exec_append(CkbBinaryArgsType *bin_args, const uint8_t *data, uint32_t len)` ### Parameters #### Path Parameters - `bin_args` (CkbBinaryArgsType *) - Pointer to the binary arguments structure. - `data` (const uint8_t *) - Pointer to the binary data to append. - `len` (uint32_t) - The length of the binary data. ### Response #### Success Response (0) Returns 0 on successful appending. #### Error Response Returns a non-zero error code on failure. ## ckb_exec_encode_params ### Description Encodes the appended binary arguments into a hex-encoded string suitable for `ckb_exec` or `ckb_spawn`. ### Method `int ckb_exec_encode_params(const CkbBinaryArgsType *bin_args, CkbHexArgsType *hex_args)` ### Parameters #### Path Parameters - `bin_args` (const CkbBinaryArgsType *) - Pointer to the binary arguments structure. - `hex_args` (CkbHexArgsType *) - Pointer to the structure to store the hex-encoded arguments. ### Response #### Success Response (0) Returns 0 on successful encoding. #### Error Response Returns a non-zero error code on failure. ## ckb_exec_decode_params ### Description Decodes a hex-encoded argument string received from `ckb_exec` or `ckb_spawn` back into binary data. ### Method `int ckb_exec_decode_params(char *iter, uint8_t **param_ptr, uint32_t *param_len, char **next)` ### Parameters #### Path Parameters - `iter` (char *) - Pointer to the start of the hex-encoded argument string. - `param_ptr` (uint8_t **) - Pointer to store the pointer to the decoded binary data. - `param_len` (uint32_t *) - Pointer to store the length of the decoded binary data. - `next` (char **) - Pointer to store the pointer to the start of the next argument in the string. ### Response #### Success Response (0) Returns 0 on successful decoding. #### Error Response Returns a non-zero error code on failure. ``` -------------------------------- ### Inter-Process Communication (IPC) with Pipes (VM v2) Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt Utilize pipes for communication between processes. This involves creating a pipe, writing data to one end, reading from the other, and closing the file descriptors. ```c // Pipe-based IPC uint64_t fds[2]; ckb_pipe(fds); // fds[0]=read end, fds[1]=write end size_t wlen = 5; ckb_write(fds[1], "hello", &wlen); uint8_t rbuf[16]; size_t rlen = sizeof(rbuf); ckb_read(fds[0], rbuf, &rlen); ckb_close(fds[0]); ckb_close(fds[1]); ``` -------------------------------- ### Simulator Configuration JSON Source: https://github.com/nervosnetwork/ckb-c-stdlib/blob/master/simulator/README.md This JSON file configures the simulator for running scripts. It specifies whether to run a lock or type script, the index of the script in the input, the transaction hash, and the filename of the dumped transaction data. ```json { "is_lock_script": true, "script_index": 0, "main": "0xa98c212cf055cedbbb665d475c0561b56c68ea735c8aa830c493264effaf18bd", "0xa98c212cf055cedbbb665d475c0561b56c68ea735c8aa830c493264effaf18bd": "original.json" } ``` -------------------------------- ### Process Management and Exit (VM v2) Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt Manage child processes by waiting for their completion using `ckb_wait` and retrieve the current process ID with `ckb_process_id`. Scripts can terminate using `ckb_exit`. ```c int8_t exit_code = 0; ret = ckb_wait(pid, &exit_code); // wait for child to finish // Get this process's ID uint64_t my_pid = ckb_process_id(); // Exit script with status code ckb_exit(0); // success ckb_exit(1); // failure ``` -------------------------------- ### Initialize Swappable Signature Verification Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt Dynamically loads a signature algorithm from a dep cell, provided it exports `load_prefilled_data` and `validate_signature`. The `CkbSwappableSignatureInstance` struct holds buffers and the verification function pointer. ```c #include "ckb_swappable_signatures.h" static uint8_t code_buf[0x100000] __attribute__((aligned(4096))); static uint8_t prefilled_buf[0x100000]; CkbSwappableSignatureInstance sig_instance = { .code_buffer = code_buf, .code_buffer_size = sizeof(code_buf), .prefilled_data_buffer = prefilled_buf, .prefilled_buffer_size = sizeof(prefilled_buf), .verify_func = NULL, }; uint8_t algo_code_hash[32] = { /* hash of secp256k1, ed25519, etc. */ }; int ret = ckb_initialize_swappable_signature(algo_code_hash, /*hash_type=*/0, &sig_instance); if (ret != CKB_SUCCESS) { ckb_exit(ret); } // Now call the loaded verify function: // verify_func(prefilled_data, sig, sig_len, msg, msg_len, out, &out_len) uint8_t sig[65], msg[32], pub[33]; size_t pub_len = sizeof(pub); ret = sig_instance.verify_func(sig_instance.prefilled_data_buffer, sig, 65, msg, 32, pub, &pub_len); ``` -------------------------------- ### Encode Binary Arguments for ckb_exec Source: https://context7.com/nervosnetwork/ckb-c-stdlib/llms.txt Encodes binary data into hex-encoded, colon-separated strings for passing as arguments via `ckb_exec` or `ckb_spawn`. Use `ckb_exec_reset` to initialize, `ckb_exec_append` to add arguments, and `ckb_exec_encode_params` to finalize. ```c #include "ckb_exec.h" /* --- Sender side: encode binary args --- */ CkbBinaryArgsType bin_args; ckb_exec_reset(&bin_args); uint8_t pubkey[33] = { /* compressed pubkey */ }; uint8_t sig[65] = { /* DER signature */ }; ckb_exec_append(&bin_args, pubkey, 33); ckb_exec_append(&bin_args, sig, 65); CkbHexArgsType hex_args; int ret = ckb_exec_encode_params(&bin_args, &hex_args); // hex_args.buff now contains e.g. "02aabb...cc:3045..." const char *argv[] = { hex_args.buff }; // pass to ckb_exec_cell / ckb_spawn_cell ```