ckb-std syscalls
CKB VM syscalls are used to implement communications between the RISC-V based CKB VM, and the main CKB process, allowing scripts running in the VM to read current transaction information as well as general blockchain information from CKB. Leveraging syscalls instead of custom instructions allow us to maintain a standard compliant RISC-V implementation which can embrace the broadest industrial support.
Quoted from CKB RFC vm-syscalls.
When developing script, you will inevitably use these assembly instructions. If you call them directly in Rust, it looks like this:
let c_str = b"hello world\0";
core::arch::asm!(
"ecall",
inout("a0") _a0,
in("a1") 0,
in("a2") 0,
in("a3") 0,
in("a4") 0,
in("a5") 0,
in("a6") 0,
in("a7") 2177, // const SYS_DEBUG: u64 = 2177;
);
Fortunately, ckb-std already wraps these instructions:
syscallsmod: Wraps raw assembly instructions into basic Rust-style functions.high_levelmod: Further wraps thesyscallsto provide more developer-friendly interfaces.
Syscalls (Native)
In native.rs, ckb-std provides simple, Rust-style syscall wrappers. Each wrapper corresponds to a syscall defined in the RFC, so we won’t repeat the details here (generally not used) .
high_level::load_tx_hash
Load Transaction Hash.
Syntax
pub fn load_tx_hash() -> Result<[u8; 32], SysError>
Parameters
None
Return
If the function succeeds, returns a 32-byte transaction hash.
If the function fails, return SysError.
Remarks
Loads the hash of the current transaction (excluding the Witnesses field).
Since some transaction components are consumed upon execution (e.g., cells in Inputs), the transaction hash is unique.
This uniqueness can be leveraged in certain cases. For example, CKB’s default lock script, Secp256k1, includes the tx_hash in the message when verifying a signature during unlocking.
Example
See the example in ckb-rust-script/tx-hash. It demonstrates how to get the tx_hash, pass it through the witness, and verify it.
In testing, you can manually modify the tx_hash to simulate extreme situations.
Normally, this is only used in tests.
high_level::load_script_hash
Load script hash
Syntax
pub fn load_script_hash() -> Result<[u8; 32], SysError>
Parameters
None