### Transitioning State from Defined to Started in CKB Rust Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0043-ckb-softfork-activation/0043-ckb-softfork-activation.md This Rust snippet handles the state transition for a softfork deployment. If the current state is DEFINED and the current epoch number is greater than or equal to the configured start epoch, the deployment state transitions to STARTED, marking the beginning of the signaling period. ```Rust match state { ThresholdState::DEFINED => { if epoch.number() >= start { next_state = ThresholdState::STARTED; } } ``` -------------------------------- ### Simple CKB Lock Script Example (C) Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0022-transaction-structure/0022-transaction-structure.md 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. ```C int main(int argc, char *argv[]) { return 0; } ``` -------------------------------- ### Example CKB Address Generation Tests YAML Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0021-ckb-address-format/0021-ckb-address-format.md Contains a series of test cases demonstrating the generation of CKB addresses using different payload formats (full, deprecated short, deprecated full). Shows input parameters like code hash, hash type, args, and the expected address output. ```yaml == full address test == code_hash to encode: 9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8 hash_type to encode: 01 with args to encode: b39bbc0b3673c7d36450bc14cfcdad2d559c6c64 full address generated: ckb1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqdnnw7qkdnnclfkg59uzn8umtfd2kwxceqxwquc4 == deprecated short address (code_hash_index = 0x00) test == args to encode: b39bbc0b3673c7d36450bc14cfcdad2d559c6c64 address generated: ckb1qyqt8xaupvm8837nv3gtc9x0ekkj64vud3jqfwyw5v == deprecated short address (code_hash_index = 0x01) test == multi sign script: 00 | 01 | 02 | 03 | bd07d9f32bce34d27152a6a0391d324f79aab854 | 094ee28566dff02a012a66505822a2fd67d668fb | 4643c241e59e81b7876527ebff23dfb24cf16482 args to encode: 4fb2be2e5d0c1a3b8694f832350a33c1685d477a address generated: ckb1qyq5lv479ewscx3ms620sv34pgeuz6zagaaqklhtgg == deprecated full address test == code_hash to encode: 9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8 with args to encode: b39bbc0b3673c7d36450bc14cfcdad2d559c6c64 full address generated: ckb1qjda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xw3vumhs9nvu786dj9p0q5elx66t24n3kxgj53qks ``` -------------------------------- ### Handling State Transitions from Started in CKB Rust Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0043-ckb-softfork-activation/0043-ckb-softfork-activation.md This Rust snippet manages state transitions from the STARTED state. It counts blocks in the past period that have the softfork's version bit set and meet the top 3 bits constraint. If the count meets the threshold, it transitions to LOCKED_IN. If the timeout epoch is reached before the threshold, it transitions to FAILED. ```Rust match state { ThresholdState::STARTED => { let mut count = 0; for block in (0..period_blocks) { if (block.version() & 0xE0000000 == 0x00000000 && (block.version() >> bit) & 1 == 1) { ++count; } } let threshold_number = threshold_number(period_blocks, threshold); if count >= threshold_number { next_state = ThresholdState::LOCKED_IN; } else if epoch_ext.number() >= timeout { next_state = ThresholdState::FAILED; } } ``` -------------------------------- ### Calling ckb_spawn and IPC Setup (C) Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0050-vm-syscalls-3/0050-vm-syscalls-3.md 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. ```c #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; } ``` -------------------------------- ### Example Multisig Script Bytes CKB Address C Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0021-ckb-address-format/0021-ckb-address-format.md Provides a concrete example of a multisig script byte sequence for a specific scenario (any two of three, Cipher required). Illustrates the structure defined for the deprecated short format multisig args. ```c 0 | 1 | 2 | 3 | Pk_Cipher_h | Pk_Alice_h | Pk_Bob_h ``` -------------------------------- ### Example Transaction JSON with Multiple Hash Types Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0032-ckb-vm-version-selection/0032-ckb-vm-version-selection.md This JSON object provides a test vector demonstrating a CKB transaction structure. It showcases how the `hash_type` field in output scripts ('data', 'type', 'data1') indicates both the code matching method and the intended CKB VM version (v0 or v1) for script execution. ```json { "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" ] } ``` -------------------------------- ### Implementing Echo via Inherited FDs (C) Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0050-vm-syscalls-3/0050-vm-syscalls-3.md This C code serves as the child process ('Callee') in the CKB VM spawn example. It begins by retrieving the file descriptors inherited from the parent process using the `ckb_inherited_file_descriptors` syscall. It then reads data from the file descriptor designated as standard input (which is a pipe connected to the parent) using the `ckb_read_all` helper function and immediately writes the same data back to the file descriptor designated as standard output (a pipe connected back to the parent) using `ckb_write`, effectively acting as an echo server. ```c #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; } int main() { int err = 0; uint64_t fds[2] = {0}; uint64_t fds_len = 2; err = ckb_inherited_file_descriptors(fds, &fds_len); if (err != 0) { goto exit; } uint8_t buffer[1024] = {0}; size_t length; length = 1024; err = ckb_read_all(fds[CKB_STDIN], buffer, &length); if (err != 0) { goto exit; } err = ckb_write(fds[CKB_STDOUT], buffer, &length); if (err != 0) { goto exit; } err = ckb_close(fds[CKB_STDOUT]); if (err != 0) { goto exit; } exit: return err; } ``` -------------------------------- ### Checking for Initial Defined State in CKB Rust Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0043-ckb-softfork-activation/0043-ckb-softfork-activation.md This Rust snippet checks if the current epoch number is zero. According to the specification, softfork deployments are in the DEFINED state by definition for epoch 0 blocks, serving as the initial state before reaching the start epoch for potential transition. ```Rust if epoch.number().is_zero() { return ThresholdState::DEFINED; } ``` -------------------------------- ### Getting VM Version (C) Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0034-vm-syscalls-2/0034-vm-syscalls-2.md This C function provides a wrapper for the CKB VM syscall 2041 to retrieve the current running VM version. It returns an integer indicating the VM version (1 for the new hardfork version, or an error for the old Lina version) and consumes 500 cycles. The arguments to the underlying syscall are ignored. ```C int ckb_vm_version() { return syscall(2041, 0, 0, 0, 0, 0, 0); } ``` -------------------------------- ### Getting Current Cycles (C) Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0034-vm-syscalls-2/0034-vm-syscalls-2.md This C function wraps the CKB VM syscall 2042 to get the total cycle consumption accumulated just before this syscall is executed. It returns an unsigned 64-bit integer representing the cycle count and consumes 500 cycles itself. The arguments to the underlying syscall are not used. ```C uint64_t ckb_current_cycles() { return syscall(2042, 0, 0, 0, 0, 0, 0); } ``` -------------------------------- ### Nervos CKB Script: Loading Headers via Syscall (C) Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0022-transaction-structure/0022-transaction-structure.md 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`. ```C // 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); ``` -------------------------------- ### Loading CKB Transaction Header (C) Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md Implements the `ckb_load_header` syscall in C. This function loads a transaction header from the specified source (`inputs`, `deps`, or `header deps`) at the given `index`. The serialized header data is written to the memory address `addr`, with `len` controlling the maximum size and `offset` specifying the start byte. Returns 0 on success, 1 for index out of bound, 2 for missing header hash, or triggers a VM error for invalid source. ```C int ckb_load_header(void* addr, uint64_t* len, size_t offset, size_t index, size_t source) { return syscall(2072, addr, len, offset, index, source, 0); } ``` -------------------------------- ### Getting Current Process ID in CKB VM (C) Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0050-vm-syscalls-3/0050-vm-syscalls-3.md Returns the unique identifier (Process ID) of the currently executing process. The root process, which is the initial script execution context before any children are spawned, is assigned a process ID of 0. ```C uint64_t ckb_process_id(); ``` -------------------------------- ### CKB Syscall: Load Script (C) Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0022-transaction-structure/0022-transaction-structure.md This CKB syscall allows a running script to read its own code or data. The parameters `addr`, `len`, and `offset` control where the data is written in memory, how many bytes are read, and the starting position within the script data, respectively. ```C ckb_load_script(addr, len, offset) ``` -------------------------------- ### Loading Specific CKB Header Field (C) Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md 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. ```C 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); } ``` -------------------------------- ### Converting CKB Compact Target in Python Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0027-block-structure/0027-block-structure.md This Python snippet provides functions (`compact_to_target`, `target_to_compact`) to convert the CKB difficulty `compact_target` field between its compact 32-bit integer representation and the actual target threshold big integer. It also includes unit tests with example values to verify the conversion logic. Required dependencies are standard Python libraries (`unittest`). ```Python import unittest def compact_to_target(compact): exponent = compact >> 24 mantissa = compact & 0x00ffffff rtn = 0 if (exponent <= 3): mantissa >>= (8 * (3 - exponent)) rtn = mantissa else: rtn = mantissa rtn <<= (8 * (exponent - 3)) overflow = mantissa != 0 and (exponent > 32) return rtn, overflow def target_to_compact(target): bits = (target).bit_length() exponent = ((bits + 7) // 8) compact = target << ( 8 * (3 - exponent)) if exponent <= 3 else (target >> (8 * (exponent - 3))) compact = (compact | (exponent << 24)) return compact class TestCompactTarget(unittest.TestCase): def test_compact_target1(self): compact = target_to_compact(0x2) self.assertEqual('0x1020000', hex(compact)) target, overflow = compact_to_target(0x1020000) self.assertTupleEqual((2, False), (target, overflow)) def test_compact_target2(self): compact = target_to_compact(0xfe) self.assertEqual('0x1fe0000', hex(compact)) target, overflow = compact_to_target(0x1fedcba) self.assertTupleEqual((0xfe, False), (target, overflow)) if __name__ == '__main__': unittest.main() ``` -------------------------------- ### Loading CKB Cells with Syscalls - C Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0003-ckb-vm/0003-ckb-vm.md 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. ```C 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; } ``` -------------------------------- ### Implementing UDT Initialization - C Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0003-ckb-vm/0003-ckb-vm.md Presents the C implementation of the `udt_initialize` function. This function sets up the initial state of the `data_t` structure for a new UDT instance, setting the owner, distributing the total supply to the owner's balance, and initializing internal counters. It assumes the structure pointed to by `data` is provided and will be modified in place. ```C int udt_initialize(data_t *data, char owner[ADDRESS_LENGTH], int64_t total_supply) { memset(&data, 0, sizeof(data_t)); memcpy(data->owner, owner, ADDRESS_LENGTH); memcpy(data->balances[0].address, owner, ADDRESS_LENGTH); data->balances[0].tokens = total_supply; data->used_balance = 1; data->used_allowed = 0; data->total_supply = total_supply; return 0; } ``` -------------------------------- ### Running Eaglesong Reference Implementation Python with I/O Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0010-eaglesong/0010-eaglesong.md This shell session demonstrates executing the Python Eaglesong hash script hash.py. It shows providing "Hello, world!" as input via standard input (terminated by Ctrl-D) and the resulting 256-bit Eaglesong hash output. ```Bash $> python hash.py > Hello, world! > [Ctrl-D] > 64867e2441d162615dc2430b6bcb4d3f4b95e4d0db529fca1eece73c077d72d6 ``` -------------------------------- ### Running Eaglesong Reference Implementation C Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0010-eaglesong/0010-eaglesong.md This shell session demonstrates executing the compiled C Eaglesong hash program. It shows providing "Hello, world!" as input via standard input (terminated by Ctrl-D) and the resulting 256-bit Eaglesong hash output. ```Bash $> ./hash > Hello, world! > [Ctrl-D] > 64867e2441d162615dc2430b6bcb4d3f4b95e4d0db529fca1eece73c077d72d6 ``` -------------------------------- ### Example CKB Block Structure JSON Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0019-data-structures/0019-data-structures.md This JSON snippet illustrates the structure of a Nervos CKB block. It includes the main block header, an array of committed transactions, an array of proposed transaction short IDs, and an array of uncle blocks, serving as a reference for developers. ```json { "uncles": [ { "proposals": [ ], "header": { "compact_target": "0x1a9c7b1a", "hash": "0x87764caf4a0e99302f1382421da1fe2f18382a49eac2d611220056b0854868e3", "number": "0x129d3", "parent_hash": "0x815ecf2140169b9d283332c7550ce8b6405a120d5c21a7aa99d8a75eb9e77ead", "nonce": "0x78b105de64fc38a200000004139b0200", "timestamp": "0x16e62df76ed", "transactions_root": "0x66ab0046436f97aefefe0549772bf36d96502d14ad736f7f4b1be8274420ca0f", "proposals_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "uncles_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "version": "0x0", "epoch": "0x7080291000049", "dao": "0x7088b3ee3e738900a9c257048aa129002cd43cd745100e000066ac8bd8850d00" } } ], "proposals": [ "0x5b2c8121455362cf70ff" ], "transactions": [ { "version": "0x0", "cell_deps": [ ], "header_deps": [ ], "inputs": [ { "previous_output": { "tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "index": "0xffffffff" }, "since": "0x129d5" } ], "outputs": [ { "capacity": "0x1996822511", "lock": { "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", "args": "0x2ec3a5fb4098b14f4887555fe58d966cab2c6a63", "hash_type": "type" }, "type": null } ], "outputs_data": [ "0x" ], "witnesses": [ "0x590000000c00000055000000490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce801140000002ec3a5fb4098b14f4887555fe58d966cab2c6a6300000000" ], "hash": "0x84395bf085f48de9f8813df8181e33d5a43ab9d92df5c0e77d711e1d47e4746d" } ], "header": { "compact_target": "0x1a9c7b1a", "hash": "0xf355b7bbb50627aa26839b9f4d65e83648b80c0a65354d78a782744ee7b0d12d", "number": "0x129d5", "parent_hash": "0x4dd7ae439977f1b01a8c9af7cd4be2d7bccce19fcc65b47559fe34b8f32917bf", "nonce": "0x91c4b4746ffb69fe000000809a170200", "timestamp": "0x16e62dfdb19", "transactions_root": "0x03c72b4c2138309eb46342d4ab7b882271ac4a9a12d2dcd7238095c2d131caa6", "proposals_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "uncles_hash": "0x90eb89b87b4af4c391f3f25d0d9f59b8ef946d9627b7e86283c68476fee7328b", "version": "0x0", "epoch": "0x7080293000049", "dao": "0xae6c356c8073890051f05bd38ea12900939dbc2754100e0000a0d962db850d00" } } ``` -------------------------------- ### Defining Nervos DAO Script | CKB JSON Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0023-dao-deposit-withdraw/0023-dao-deposit-withdraw.md 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. ```JSON { "code_hash": "0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e", "args": "0x", "hash_type": "type" } ``` -------------------------------- ### Building Simple UDT Reference Script - Bash Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0025-simple-udt/0025-simple-udt.md Provides the bash commands necessary to clone the repository, checkout the specific version of the Simple UDT reference C implementation, initialize submodules, and build the script using Docker, allowing for verification of deployed script hashes. ```bash git clone https://github.com/nervosnetwork/ckb-production-scripts cd ckb-production-scripts git checkout e570c11aff3eca12a47237c21598429088c610d5 git submodule update --init --recursive make all-via-docker ``` -------------------------------- ### Executing New Program (C) Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0034-vm-syscalls-2/0034-vm-syscalls-2.md 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. ```C 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); } ``` -------------------------------- ### Executing and Validating UDT Initialization - CKB Script Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0003-ckb-vm/0003-ckb-vm.md Shows a CKB script's `main` function that demonstrates calling the compiled-in `udt_initialize` function. It initializes a local `data_t` structure and then attempts to read the output cell's data using `ckb_read_cell`. The script validates the transaction by comparing the initialized data with the data present in the first output cell. ```C int main(int argc, char* argv[]) { data_t data; ret = udt_initialize(&data, "", 10000000); 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 (memcmp(&data, output_data, sizeof(data_t)) != 0) { return -1; } return 0; } ``` -------------------------------- ### Referencing Nervos DAO Script Cell | CKB JSON Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0023-dao-deposit-withdraw/0023-dao-deposit-withdraw.md JSON structure representing an OutPoint used to reference a specific cell on the CKB blockchain. This particular OutPoint points to a cell containing the Nervos DAO script ('dep_type: "code"'). It includes the 'tx_hash' and 'index' of the referenced transaction output. ```JSON { "out_point": { "tx_hash": "0xe2fb199810d49a4d8beec56718ba2593b665db9d52299a0f9e6e75416d73ff5c", "index": "0x2" }, "dep_type": "code" } ``` -------------------------------- ### Executing UDT Operations via Dynamic Linking and Argument Dispatch - CKB Script Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0003-ckb-vm/0003-ckb-vm.md 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. ```C 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; } ``` -------------------------------- ### Spawning Child Process in CKB VM (C) Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0050-vm-syscalls-3/0050-vm-syscalls-3.md Creates a new, independent child process (CKB VM instance) based on a binary located in a cell or witness. The parent process is not blocked by this syscall. It requires arguments specifying the source, location, bounds, and spawn arguments including command-line parameters, a pointer to receive the child's process ID, and an array of file descriptors to be inherited. ```C typedef struct spawn_args_t { size_t argc; const char** argv; /* Spawned VM process ID */ uint64_t* process_id; /* A list of file descriptor, 0 indicates end of array */ const uint64_t* inherited_fds; } spawn_args_t; int ckb_spawn(size_t index, size_t source, size_t place, size_t bounds, spawn_args_t* spawn_args); ``` -------------------------------- ### CKB Syscall: Load Witness (C) Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0022-transaction-structure/0022-transaction-structure.md 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. ```C ckb_load_witness(addr, len, offset, 0, CKB_SOURCE_INPUT); ``` -------------------------------- ### Representing CKB Cell Structure (JSON) Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0019-data-structures/0019-data-structures.md 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. ```json { "capacity": "0x19995d0ccf", "lock": { "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", "args": "0x0a486fb8f6fe60f76f001d6372da41be91172259", "hash_type": "type" }, "type": null } ``` -------------------------------- ### Reproducible Build Steps for xUDT Script (Shell) Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0052-extensible-udt/0052-extensible-udt.md This snippet provides the command-line steps necessary to perform a reproducible build of the xUDT RCE script. It instructs the user to clone the 'ckb-production-scripts' repository, checkout a specific Git commit hash, update its submodules recursively, and then execute the 'make all-via-docker' command to build the project within a Docker environment. This ensures the built script matches the deployed versions. ```Shell $ git clone https://github.com/nervosnetwork/ckb-production-scripts $ cd ckb-production-scripts $ git checkout abdcb117b512e35910fa8e30241a7a354e5cacf0 $ git submodule update --init --recursive $ make all-via-docker ``` -------------------------------- ### Block Containing Nervos DAO Withdrawal (Phase 1) | CKB JSON Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0023-dao-deposit-withdraw/0023-dao-deposit-withdraw.md JSON structure representing a CKB block header. This block includes the transaction that initiated phase 1 of the Nervos DAO withdrawal. It contains standard block header fields and the 'dao' field reflecting the Accumulated Rate (AR) at this later block height. ```JSON { "compact_target": "0x1a2dfb48", "hash": "0xba6eaa7e0acd0dc78072c5597ed464812391161f0560c35992ae0c96cd1d6073", "number": "0x11ea4", "parent_hash": "0x36f16c9a1abea1cb44bc1d923feb9f62ff45b9327188dca954968dfdecc03bd0", "nonce": "0x74e39f370400000000000000bb4b3299", "timestamp": "0x16ea78c300f", "transactions_root": "0x4efccc5beeeae3847aa65f2e987957957d68f13687af069f52be361d0648feb8", "proposals_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "uncles_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "version": "0x0", "epoch": "0x645017e00002f", "dao": "0x77a7c6ea619acb2e4b841a96c88e2300b6b274a096c1080000ea07db0efaff06" } ``` -------------------------------- ### Loading CKB Transaction Witness (C) Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md Implements the `ckb_load_witness` syscall in C. This function loads a transaction witness from the transaction's witness list based on `index`. The `source` parameter serves as a hint (inputs or outputs). The serialized witness data is written to memory at `addr`, controlled by `len` and `offset`. Returns 0 on success, 1 for index out of bound, or triggers a VM error for invalid source. ```C int ckb_load_witness(void* addr, uint64_t* len, size_t offset, size_t index, size_t source) { return syscall(2074, addr, len, offset, index, source, 0); } ``` -------------------------------- ### Building Anyone-Can-Pay Lock Script (Reproducible Build) - bash Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0026-anyone-can-pay/0026-anyone-can-pay.md Provides a series of bash commands utilizing Docker to clone the official CKB production scripts repository at a specific commit, update necessary submodules, and execute the build process. This allows developers to reproduce the exact binary of the deployed Anyone-Can-Pay lock script for verification. ```bash $ git clone https://github.com/nervosnetwork/ckb-production-scripts $ cd ckb-production-scripts $ git checkout e570c11aff3eca12a47237c21598429088c610d5 $ git submodule update --init $ make all-via-docker ``` -------------------------------- ### Implementing Sponge Construction (Pseudocode) Source: https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0010-eaglesong/0010-eaglesong.md This pseudocode implements the generic sponge construction algorithm. It appends a delimiter, pads the input, splits it into chunks, absorbs the chunks by XORing into the state and applying a permutation `F`, and then squeezes the desired output length by repeatedly applying `F` and reading the top `r` bits. ```Pseudocode function sponge( input, output_length ): // append delimiter and pad as necessary input = input || d while length(input) % r =/= 0 do: input = input || 0 // split for i in [0, length(input) / r] do: chunks[i] = input[i*r : (i+1)*r] // initialize state state = zeros(r+c) // absorb for chunk in chunks do: state[0:r] = state[0:r] xor chunk state = F(state) // squeeze output = "" while length(output) <= output_length do: output = output || state[0:r] state = F(state) return output[0:output_length] ```