CKB Syscalls for Script
A collection of CKB-VM syscalls. Also include relevant constant, such as return codes, sources, Cell fields, header fields, and input fields.
CKB-VM Syscalls
VM Ver. | Syscall ID | C Function Name | Rust Function Name | Description |
---|---|---|---|---|
1 | 93 | ckb_exit | exit | Immediately terminate the execution of the currently running Script and exit with the specified return code. |
1 | 2061 | ckb_load_tx_hash | load_tx_hash | Calculate the hash of the current transaction and copy it using partial loading. |
1 | 2051 | ckb_load_transaction | load_transaction | Serialize the full transaction of the running Script using the Molecule Encoding 1 format and copy it using partial loading. |
1 | 2062 | ckb_load_script_hash | load_script_hash | Calculate the hash of currently running Script and copy it using partial loading. |
1 | 2052 | ckb_load_script | load_script | Serialize the currently running Script using the Molecule Encoding 1 format and copy it using partial loading. |
1 | 2071 | ckb_load_cell | load_cell | Serialize the specified Cell in the current transaction using the Molecule Encoding 1 format and copy it using partial loading. |
1 | 2081 | ckb_load_cell_by_field | load_cell_by_field | Load a single field from the specified Cell in the current transaction and copy it using partial loading. |
1 | 2092 | ckb_load_cell_data | load_cell_data | Load the data from the Cell data field in the specified Cell from the current transaction and copy it using partial loading. |
1 | 2091 | ckb_load_cell_data_as_code | load_cell_code | Load the data from the Cell data field in the specified Cell from the current transaction, mark the loaded memory page as executable, and copy it using partial loading. The loaded code can then be executed by CKB-VM at a later time. |
1 | 2073 | ckb_load_input | load_input | Serialize the specified input Cell in the current transaction using the Molecule Encoding 1 format and copy it using partial loading. |
1 | 2083 | ckb_load_input_by_field | load_input_by_field | Load a single field from the specified input Cell in the current transaction and copy it using partial loading. |
1 | 2072 | ckb_load_header | load_header | Serialize the specified header associated with an input Cell, dep Cell, or header dep using the Molecule Encoding 1 format and copy it using partial loading. |
1 | 2082 | ckb_load_header_by_field | load_header_by_field | Load a single field from the specified header associated with an input Cell, dep Cell, or header dep and copy it using partial loading. |
1 | 2074 | ckb_load_witness | load_witness | Load the specified witness in the current transaction and copy it using partial loading. |
1 | 2177 | ckb_debug | debug | Print the specified message in CKB's terminal output for the purposes of debugging. |
2 | 2041 | ckb_vm_version | vm_version | Return the version of CKB-VM being used to execute the current Script. |
2 | 2042 | ckb_current_cycles | current_cycles | Return the number of cycles consumed by the currently running Script immediately before executing this syscall. This syscall will consume an additional 500 cycles. |
2 | 2043 | ckb_exec | exec | Run a Script executable from the specified Cell using the current VM context. This replaces the original calling running Script executable with the new specified Script executable. This is similar to the exec call found in several operating systems. |
2 | 2101 | ckb_spawn | spawn | Run a Script executable from the specified Cell using the current VM context, but return to the original calling Script executable upon termination. This is similar to the spawn function found in several operating systems and programming languages. |
2 | 2104 | ckb_load_extension | load_block_extension | Load the extension field data and copy it using partial loading. |
2 | 2602 | ckb_wait | Pause until the execution of a process specified by pid has ended. | |
2 | 2603 | ckb_process_id | Get the current process id. | |
2 | 2604 | ckb_pipe | Create a pipe with read-write pair of file descriptions. | |
2 | 2605 | ckb_write | Write data to a pipe via a file descriptor. | |
2 | 2606 | ckb_read | Read data from a pipe via a file descriptor. | |
2 | 2607 | ckb_inherited_file_descriptors | Retrieve the file descriptors available to the current process, which are passed in from the parent process. | |
2 | 2608 | ckb_close | Manually close a file descriptor. |
Constants
Return Codes
These are the return codes used by the CKB-VM syscalls.
Const No. | C Example | Description |
---|---|---|
0 | CKB_SUCCESS | No error. |
1 | CKB_INDEX_OUT_OF_BOUND | Index out of bounds (e.g., no such input Cell). |
2 | CKB_ITEM_MISSING | The requested resource does not exist. |
3 | CKB_LENGTH_NOT_ENOUGH | The supplied memory buffer is too small. |
4 | CKB_INVALID_DATA | The data provided is invalid. |
5 | CKB_WAIT_FAILURE | The file descriptor is invalid during syscall Wait. |
6 | CKB_INVALID_FD | The file descriptor is not owned by this process. |
7 | CKB_OTHER_END_CLOSED | The other end of the pipe is closed. |
8 | CKB_MAX_VMS_SPAWNED | The maximum count of spawned processes has been reached. |
9 | CKB_MAX_FDS_CREATED | The maximum count of created pipes has been reached. |
Source
These are the sources for syscalls that query the transaction for input Cells, output Cells, dep Cells, and header deps.
Const No. | C Example | Description |
---|---|---|
0x1 | CKB_SOURCE_INPUT | All input Cells in the transaction. |
0x0100000000000001 | CKB_SOURCE_GROUP_INPUT | Only the input Cells in the transaction using the same Script as currently running Script. |
2 | CKB_SOURCE_OUTPUT | All output Cells in the transaction. |
0x0100000000000002 | CKB_SOURCE_GROUP_OUTPUT | Only the output Cells in the transaction using the same Script as currently running Script. |
3 | CKB_SOURCE_CELL_DEP | All dep Cells in the transaction. |
4 | CKB_SOURCE_HEADER_DEP | All header deps in the transaction. |
Cell Fields
These are the field specifiers for syscalls that request a specific field of a cell.
Const No. | C Example | Description |
---|---|---|
0 | CKB_CELL_FIELD_CAPACITY | The capacity (CKB) contained in the Cell. |
1 | CKB_CELL_FIELD_DATA_HASH | The hash of the data within the data field of the Cell. |
2 | CKB_CELL_FIELD_LOCK | The Lock Script of the Cell. |
3 | CKB_CELL_FIELD_LOCK_HASH | The hash of the Lock Script of the Cell. |
4 | CKB_CELL_FIELD_TYPE | The Type Script of the Cell. |
5 | CKB_CELL_FIELD_TYPE_HASH | The hash of the Type Script of the Cell. |
6 | CKB_CELL_FIELD_OCCUPIED_CAPACITY | The amount of capacity (CKB) that is currently being used by the Cell. |
Header Fields
These are the field specifiers for syscalls that request a specific field of a header dep.
Const No. | C Example | Description |
---|---|---|
0 | CKB_HEADER_FIELD_EPOCH_NUMBER | The epoch number for the header dep. |
1 | CKB_HEADER_FIELD_EPOCH_START_BLOCK_NUMBER | The block number of first block in the epoch for the header dep. |
2 | CKB_HEADER_FIELD_EPOCH_LENGTH | The length of the epoch for the header dep. |
Input Fields
These are the field specifiers for syscalls that request a specific field of an input Cell.
Const No. | C Example | Description | |
---|---|---|---|
0 | CKB_INPUT_FIELD_OUT_POINT | The out point of the specified input Cell. | |
1 | CKB_INPUT_FIELD_SINCE | The since value of the specified input Cell. |
Spawn Example
Consider the creation of a dependency library with a straightforward function that receives strings, concatenates them, and subsequently returns the resulting string to the caller (a.k.a, echo).
- Caller
- Callee
#include <stdint.h>
#include <string.h>
#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;
}
#include <stdint.h>
#include <string.h>
#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;
}