TITLE: Implementing Unique Type Script Logic in C DESCRIPTION: This C code implements the logic for a unique type script on CKB. It checks that there is exactly one input cell and zero output cells with the current type script. It then verifies if the script's arguments match the OutPoint of the first input cell, ensuring uniqueness based on the transaction input. The script uses CKB syscalls like `ckb_load_cell`, `ckb_load_input`, and `ckb_load_script`, and verifies the script structure using MolReader. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/docs/script-course/intro-to-script-6.md#_snippet_0 LANGUAGE: C CODE: ``` #include "blockchain.h"\n#include "ckb_syscalls.h"\n\n#define INPUT_SIZE 128\n#define SCRIPT_SIZE 32768\n\nint main() {\n uint64_t len = 0;\n int ret = ckb_load_cell(NULL, &len, 0, 1, CKB_SOURCE_GROUP_OUTPUT);\n if (ret != CKB_INDEX_OUT_OF_BOUND) {\n return -1; /* 1 */\n }\n\n len = 0;\n ret = ckb_load_cell(NULL, &len, 0, 0, CKB_SOURCE_GROUP_INPUT);\n if (ret != CKB_INDEX_OUT_OF_BOUND) {\n return 0; /* 2 */\n }\n\n /* 3 */\n unsigned char input[INPUT_SIZE];\n uint64_t input_len = INPUT_SIZE;\n ret = ckb_load_input(input, &input_len, 0, 0, CKB_SOURCE_INPUT);\n if (ret != CKB_SUCCESS) {\n return ret;\n }\n if (input_len > INPUT_SIZE) {\n return -100;\n }\n\n unsigned char script[SCRIPT_SIZE];\n len = SCRIPT_SIZE;\n ret = ckb_load_script(script, &len, 0);\n if (ret != CKB_SUCCESS) {\n return ret;\n }\n if (len > SCRIPT_SIZE) {\n return -101;\n }\n mol_seg_t script_seg;\n script_seg.ptr = (uint8_t *)script;\n script_seg.size = len;\n\n if (MolReader_Script_verify(&script_seg, false) != MOL_OK) {\n return -102;\n }\n\n mol_seg_t args_seg = MolReader_Script_get_args(&script_seg);\n mol_seg_t args_bytes_seg = MolReader_Bytes_raw_bytes(&args_seg);\n\n if ((input_len == args_bytes_seg.size) &&\n (memcmp(args_bytes_seg.ptr, input, input_len) == 0)) {\n /* 4 */\n return 0;\n }\n return -103;\n} ``` ---------------------------------------- TITLE: Building CKB Transaction with Lumos (Data Update) - JavaScript DESCRIPTION: Updates the data field of the first output cell in a Lumos transaction skeleton, pays the fee, prepares signing entries, signs the transaction, and sends it to the RPC. It also calculates the code hash for the data. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/blog/intro-to-script-2.md#_snippet_15 LANGUAGE: JavaScript CODE: ``` txSkeleton.update("outputs", (outputs) => { let cell = outputs.first(); cell.data = "0x" + data.toString("hex"); return outputs; }); txSkeleton = await lumos.commons.common.payFeeByFeeRate(txSkeleton,[wallet.address],1000); txSkeleton = lumos.commons.common.prepareSigningEntries(txSkeleton); const signatures = txSkeleton.get("signingEntries").map((entry) => lumos.hd.key.signRecoverable(entry.message, wallet.privkey)).toArray(); const signedTx = lumos.helpers.sealTransaction(txSkeleton, signatures) const duktapeTxHash = await rpc.sendTransaction(signedTx) const duktapeCodeHash = lumos.utils.ckbHash(bytes.bytify("0x" + data.toString("hex"))); ``` ---------------------------------------- TITLE: Starting the Local CKB Devnet with OffCKB (Bash) DESCRIPTION: Starts a local CKB development network (Devnet) using the offCKB CLI. This command makes the Devnet RPC endpoint available at `localhost:8114` for development and testing. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/docs/getting-started/quick-start.mdx#_snippet_5 LANGUAGE: bash CODE: ``` offckb node ``` ---------------------------------------- TITLE: Starting Local CKB Devnet Node (sh) DESCRIPTION: Command to start a local CKB blockchain node using `offckb` for development and testing. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/docs/script/js-script.mdx#_snippet_11 LANGUAGE: sh CODE: ``` offckb node ``` ---------------------------------------- TITLE: Generating Account from Private Key (TypeScript) DESCRIPTION: This function generates an account's public key and address from a given private key using the CCC SDK. It constructs a CKB standard Lock Script (SECP256K1 + BLAKE160) to derive the address. Requires the CCC SDK client (`cccClient`). SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/docs/dapp/transfer-ckb.mdx#_snippet_1 LANGUAGE: TypeScript CODE: ``` export const generateAccountFromPrivateKey = async ( privKey: string ): Promise => { const signer = new ccc.SignerCkbPrivateKey(cccClient, privKey); const lock = await signer.getAddressObjSecp256k1(); return { lockScript: lock.script, address: lock.toString(), pubKey: signer.publicKey, }; }; ``` ---------------------------------------- TITLE: Finalize and Sign Transaction (JavaScript) DESCRIPTION: Calculates the transaction fee and prepares the signing entries for the transaction skeleton using Lumos common functions. This is a necessary step before signing the transaction, ensuring all parts of the transaction requiring signatures are identified and formatted correctly. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/blog/intro-to-script-2.md#_snippet_10 LANGUAGE: js CODE: ``` > txSkeleton = await lumos.commons.common.payFeeByFeeRate(txSkeleton,[wallet.address],1000); > txSkeleton = lumos.commons.common.prepareSigningEntries(txSkeleton); ``` ---------------------------------------- TITLE: Building and Sending CKB Transaction to Issue xUDT (TypeScript) DESCRIPTION: This code snippet constructs a CKB transaction to issue an xUDT with a Type ID. It defines the transaction structure including inputs and outputs, adds required cell dependencies for relevant scripts (OutputTypeProxyLock, XUdt, UniqueType), completes the transaction by filling inputs based on capacity and calculating the fee, updates the Type ID argument based on the first input and output index, sends the transaction using a signer, and waits for the transaction to be committed on the network. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/docs/sdk-and-devtool/ccc.mdx#_snippet_14 LANGUAGE: TypeScript CODE: ``` ], outputs: [ // Keep the Type ID cell typeIdCell.cellOutput, // Issued xUDT { lock: script, type: await ccc.Script.fromKnownScript( signer.client, ccc.KnownScript.XUdt, outputTypeLock.hash() ), }, // xUDT Info { lock: script, type: await ccc.Script.fromKnownScript( signer.client, ccc.KnownScript.UniqueType, "00".repeat(32) ), }, ], outputsData: [ typeIdCell.outputData, ccc.numLeToBytes(amount, 16), tokenInfoToBytes(decimals, symbol, name), ], }); await mintTx.addCellDepsOfKnownScripts( signer.client, ccc.KnownScript.OutputTypeProxyLock, ccc.KnownScript.XUdt, ccc.KnownScript.UniqueType ); await mintTx.completeInputsByCapacity(signer); if (!mintTx.outputs[2].type) { throw new Error("Unexpected disappeared output"); } mintTx.outputs[2].type!.args = ccc.hexFrom( ccc.bytesFrom(ccc.hashTypeId(mintTx.inputs[0], 2)).slice(0, 20) ); await mintTx.completeFeeBy(signer); const mintTxHash = await signer.sendTransaction(mintTx); log("Transaction sent:", explorerTransaction(mintTxHash)); await signer.client.waitTransaction(mintTxHash); log("Transaction committed:", explorerTransaction(mintTxHash)); }} ``` ---------------------------------------- TITLE: Deploying CKB Script Binary with Lumos (Javascript) DESCRIPTION: Javascript code using the Lumos SDK to deploy a compiled CKB script binary (`carrot_bug`) onto the CKB testnet. Reads the binary file, creates a transaction, sets the binary as cell data, signs, and sends the transaction. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/blog/intro-to-script-5.md#_snippet_2 LANGUAGE: Javascript CODE: ``` const lumos = require("@ckb-lumos/lumos"); const indexer = new lumos.Indexer("https://testnet.ckb.dev/rpc"); const rpc = new lumos.RPC("https://testnet.ckb.dev/rpc"); lumos.config.initializeConfig(lumos.config.TESTNET); const wallet = { address: "ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqvwg2cen8extgq8s5puft8vf40px3f599cytcyd8", privkey: "0x6109170b275a09ad54877b82f7d9930f88cab5717d484fb4741ae9d1dd078cd6", }; const wallet2 = { address: "ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq2prryvze6fhufxkgjx35psh7w70k3hz7c3mtl4d", privkey: "0xace08599f3174f4376ae51fdc30950d4f2d731440382bb0aa1b6b0bd3a9728cd" } const data = fs.readFileSync("carrot_bug"); data.byteLength; let txSkeleton = lumos.helpers.TransactionSkeleton({ cellProvider: indexer }); txSkeleton = await lumos.commons.common.transfer(txSkeleton,[wallet.address],wallet2.address,"19900" + "00000000"); txSkeleton.update("outputs", (outputs) => { let cell = outputs.first(); cell.data = "0x" + data.toString("hex"); return outputs; }); txSkeleton = await lumos.commons.common.payFeeByFeeRate(txSkeleton,[wallet.address],1000); txSkeleton = lumos.commons.common.prepareSigningEntries(txSkeleton); const signatures = txSkeleton.get("signingEntries").map((entry) => lumos.hd.key.signRecoverable(entry.message, wallet.privkey)).toArray(); const signedTx = lumos.helpers.sealTransaction(txSkeleton, signatures); const carrotTxHash = await rpc.sendTransaction(signedTx); ``` ---------------------------------------- TITLE: Validating Unique Type Script Instance in CKB (C) DESCRIPTION: This C code snippet implements a Type Script that enforces uniqueness. It checks if the script is applied to exactly one input cell and verifies that the script's arguments match the OutPoint of the first input cell in the transaction. This mechanism prevents duplicate script instances. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/docs/script/type-id.mdx#_snippet_0 LANGUAGE: c CODE: ``` #include "blockchain.h"\n#include "ckb_syscalls.h"\n\n#define INPUT_SIZE 128\n#define SCRIPT_SIZE 32768\n\nint main() {\n uint64_t len = 0;\n int ret = ckb_load_cell(NULL, &len, 0, 1, CKB_SOURCE_GROUP_OUTPUT);\n if (ret != CKB_INDEX_OUT_OF_BOUND) {\n return -1; /* 1 */\n }\n\n len = 0;\n ret = ckb_load_cell(NULL, &len, 0, 0, CKB_SOURCE_GROUP_INPUT);\n if (ret != CKB_INDEX_OUT_OF_BOUND) {\n return 0; /* 2 */\n }\n\n /* 3 */\n unsigned char input[INPUT_SIZE];\n uint64_t input_len = INPUT_SIZE;\n ret = ckb_load_input(input, &input_len, 0, 0, CKB_SOURCE_INPUT);\n if (ret != CKB_SUCCESS) {\n return ret;\n }\n if (input_len > INPUT_SIZE) {\n return -100;\n }\n\n unsigned char Script[SCRIPT_SIZE];\n len = SCRIPT_SIZE;\n ret = ckb_load_script(Script, &len, 0);\n if (ret != CKB_SUCCESS) {\n return ret;\n }\n if (len > SCRIPT_SIZE) {\n return -101;\n }\n mol_seg_t script_seg;\n script_seg.ptr = (uint8_t *)Script;\n script_seg.size = len;\n\n if (MolReader_Script_verify(&script_seg, false) != MOL_OK) {\n return -102;\n }\n\n mol_seg_t args_seg = MolReader_Script_get_args(&script_seg);\n mol_seg_t args_bytes_seg = MolReader_Bytes_raw_bytes(&args_seg);\n\n if ((input_len == args_bytes_seg.size) &&\n (memcmp(args_bytes_seg.ptr, input, input_len) == 0)) {\n /* 4 */\n return 0;\n }\n return -103;\n} ``` ---------------------------------------- TITLE: Generate HD Wallet and Address - Lumos - TypeScript DESCRIPTION: Demonstrates using Lumos's `hd` module to generate a mnemonic, derive an extended private key, extract the first receiving private key, and then derive the CKB address from that private key using the SECP256K1_BLAKE160 script template for the Aggron4 testnet. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/docs/sdk-and-devtool/lumos.mdx#_snippet_5 LANGUAGE: TypeScript CODE: ``` import { hd, config, helpers } from "@ckb-lumos/lumos"; const { mnemonic, ExtendedPrivateKey, AddressType } = hd; // Use Testnet environment for this example config.initializeConfig(config.predefined.AGGRON4); // Generate a mnemonic and derive a private key export const generateFirstHDPrivateKey = () => { const m = mnemonic.generateMnemonic(); const seed = mnemonic.mnemonicToSeedSync(m); const extendedPrivKey = ExtendedPrivateKey.fromSeed(seed); return extendedPrivKey.privateKeyInfo(AddressType.Receving, 0).privateKey; }; // Derive an address from the private key const getAddressByPrivateKey = (privateKey: string) => { const args = hd.key.privateKeyToBlake160(privateKey); const template = config.predefined.AGGRON4.SCRIPTS["SECP256K1_BLAKE160"]!; const lockScript = { codeHash: template.CODE_HASH, hashType: template.HASH_TYPE, args: args, }; return helpers.encodeToAddress(lockScript); }; const privateKey = generateFirstHDPrivateKey(); const address = getAddressByPrivateKey(privateKey); console.log("privateKey: ", privateKey); console.log("address: ", address); ``` ---------------------------------------- TITLE: Building and Sending CKB Transfer Transaction using Lumos (TypeScript) DESCRIPTION: This snippet shows how to construct and send a CKB transfer transaction using `@ckb-lumos/lumos`. It defines an asynchronous `transfer` function that takes sender (`from`), recipient (`to`), capacity (in Shannons), and the sender's `privateKey`. It reuses the `indexer` and `rpc` instances initialized previously. It uses `commons.common.transfer` to build the base transaction, `payFeeByFeeRate` to handle fees, prepares signing entries, signs the transaction with the private key, seals it, and finally sends it using the RPC client. It assumes `address` and `privateKey` variables are defined elsewhere. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/docs/sdk-and-devtool/lumos.mdx#_snippet_10 LANGUAGE: TypeScript CODE: ``` import { commons, Address, HexString, helpers, hd } from "@ckb-lumos/lumos"; const transfer = async ( from: Address, to: Address, capacity: number, privateKey: HexString ) => { let txSkeleton = helpers.TransactionSkeleton({ cellProvider: indexer }); // Build the base transaction txSkeleton = await commons.common.transfer( txSkeleton, [from], to, BigInt(capacity) ); // Pay the transaction fee txSkeleton = await commons.common.payFeeByFeeRate(txSkeleton, [from], 1000); // Prepare signing entried and sign the transaction txSkeleton = commons.common.prepareSigningEntries(txSkeleton); const message = txSkeleton.get("signingEntries").get(0)?.message; const Sig = hd.key.signRecoverable(message!, privateKey); const tx = helpers.sealTransaction(txSkeleton, [Sig]); // Send the transaction return rpc.sendTransaction(tx, "passthrough"); }; const bobAddress = "ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqgy5rtexzvhk7jt7gla8wlq5lztf79tjhg9fmd4f"; transfer(address, bobAddress, 100 * 10 ** 8, privateKey).then( (txHash: string) => console.log("txHash: ", txHash) ); ``` ---------------------------------------- TITLE: Modifying Transaction Skeleton for Valid UDT Transfer - Lumos/CKB - JavaScript DESCRIPTION: This snippet modifies the previously created transaction skeleton to correct the output UDT amount, making the transfer valid according to the UDT script's rules (input sum equals output sum). It updates the output cell's type and data, recalculates fees, prepares signing entries, signs the modified transaction, and sends it, demonstrating a successful UDT transfer. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/docs/script-course/intro-to-script-3.md#_snippet_10 LANGUAGE: JavaScript CODE: ``` txSkeleton = txSkeleton.update("outputs", (outputs) => { let cell = outputs.first(); cell.cellOutput.type = input.cellOutput.type; cell.data = bytes.hexify(Uint32LE.pack(1000000)); return outputs; }); txSkeleton = await lumos.commons.common.payFeeByFeeRate(txSkeleton, [wallet2.address], 3000); txSkeleton = lumos.commons.common.prepareSigningEntries(txSkeleton); signatures = txSkeleton.get("signingEntries").map((entry) => lumos.hd.key.signRecoverable(entry.message, wallet2.privkey)).toArray(); signedTx = lumos.helpers.sealTransaction(txSkeleton, signatures) let txHash = await rpc.sendTransaction(signedTx) ``` ---------------------------------------- TITLE: Building CKB Transaction with Lumos (Duktape Script) - JavaScript DESCRIPTION: Initializes a Lumos transaction skeleton, adds a transfer output, updates the output cell to include the duktape type script, adds the duktape script code as a cell dependency, pays the fee, prepares signing entries, signs the transaction, and sends it to the RPC. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/blog/intro-to-script-2.md#_snippet_20 LANGUAGE: JavaScript CODE: ``` const duktapeTypeScript = { codeHash: duktapeCodeHash, hashType: "data", args: "0x370000000c00000033000000000000001f000000434b422e6465627567282249276d2072756e6e696e6720696e204a5322290a04000000" }; let txSkeleton = lumos.helpers.TransactionSkeleton({ cellProvider: indexer }); txSkeleton = await lumos.commons.common.transfer(txSkeleton,[wallet.address],wallet2.address,"200" + "00000000"); txSkeleton.update("outputs", (outputs) => { let cell = outputs.first(); cell.cellOutput.type = duktapeTypeScript; ``` ---------------------------------------- TITLE: Checking CKB Address Balance using Lumos (TypeScript) DESCRIPTION: This snippet demonstrates how to check the CKB balance of a given address using the `@ckb-lumos/lumos` library. It initializes RPC and Indexer instances (which are reused later), defines an asynchronous function `getCapacities` that collects cells associated with the provided `address` and sums their capacities, and then logs the result. The balance is returned in Shannons and converted to CKB for display. It assumes the `address` variable is defined elsewhere. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/docs/sdk-and-devtool/lumos.mdx#_snippet_8 LANGUAGE: TypeScript CODE: ``` import { BI, RPC, Indexer, helpers } from "@ckb-lumos/lumos"; // CKB also provides an indexer rpc to help searching easily. const TESTNET_RPC_URL = "https://testnet.ckb.dev/rpc"; const TESTNET_INDEXER_URL = "https://testnet.ckb.dev/indexer"; const rpc = new RPC(TESTNET_RPC_URL); const indexer = new Indexer(TESTNET_INDEXER_URL, TESTNET_RPC_URL); // Check CKB balance async function getCapacities(address: string): Promise { const collector = indexer.collector({ lock: helpers.parseAddress(address) }); let capacities = BI.from(0); for await (const cell of collector.collect()) { capacities = capacities.add(cell.cell_output.capacity); } return capacities; } console.log(`address: ${address}`); getCapacities(address).then((capacities) => console.log(`balance: ${capacities.div(10 ** 8).toString()} CKB`) ); ``` ---------------------------------------- TITLE: Implementing sUDT Script Entry Point and Validation (Rust) DESCRIPTION: This Rust function serves as the main entry point for the sUDT script. It first checks if the script is executing in owner mode, returning success immediately if true. Otherwise, it collects the total UDT amounts from input and output cells and validates that the output amount does not exceed the input amount, returning an error if the validation fails. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/docs/script/sudt-script.mdx#_snippet_6 LANGUAGE: Rust CODE: ``` pub fn program_entry() -> i8 { ckb_std::debug!("This is a sample UDT contract!"); let script = load_script().unwrap(); let args: Bytes = script.args().unpack(); ckb_std::debug!("script args is {:?}", args); // Check if the script is in owner mode if check_owner_mode(&args) { return 0; // Success if in owner mode } // Collect amounts from input and output cells let inputs_amount: u128 = match collect_inputs_amount() { Ok(amount) => amount, Err(err) => return err as i8, }; let outputs_amount = match collect_outputs_amount() { Ok(amount) => amount, Err(err) => return err as i8, }; // Validate that inputs are greater than or equal to outputs if inputs_amount < outputs_amount { return Error::InvalidAmount as i8; // Error if invalid amount } 0 // Success } ``` ---------------------------------------- TITLE: Signing CKB P2PKH Transaction - Python Pseudo Code DESCRIPTION: This pseudo code outlines the process for signing a CKB P2PKH transaction. It involves grouping inputs, preparing the first witness with a placeholder lock, hashing the transaction hash and relevant witnesses using BLAKE2b, signing the resulting hash with the private key, and finally updating the witness with the generated signature. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/docs/how-tos/how-to-sign-a-tx.mdx#_snippet_0 LANGUAGE: Python CODE: ``` def sign_tx(pk, tx): # Group transaction inputs for signing input_groups = compute_input_groups(tx.inputs) # Iterate through each group of inputs for indexes in input_groups: group_index = indexes[0] # Create a placeholder for the lock field in the first witness of the group dummy_lock = [0] * 65 # Placeholder, assuming a 65-byte lock field # Retrieve and deserialize the first witness in the group witness = tx.witnesses[group_index] witness_args = witness.deserialize() # Replace the lock field with the dummy placeholder witness_args.lock = dummy_lock # Initialize a new BLAKE2b hasher for creating the signature hash hasher = new_blake2b() # Hash the transaction hash hasher.update(tx.hash()) # Hash the first witness witness_len_bytes = len(serialize(witness_args)).to_le() assert(len(witness_len_bytes), 8) # Hash the length of witness hasher.update(witness_len_bytes) hasher.update(serialize(witness_args)) # Hash the remaining witnesses in the group for i in indexes[1:]: witness = tx.witnesses[i] witness_len_bytes = len(witness).to_le() assert(len(witness_len_bytes), 8) hasher.update(witness_len_bytes) hasher.update(witness) # Hash additional witnesses not in any input group for witness in tx.witnesses[len(tx.inputs):] witness_len_bytes = len(witness).to_le() assert(len(witness_len_bytes), 8) hasher.update(witness_len_bytes) hasher.update(witness) # Finalize the hasher to get the signature hash sig_hash = hasher.finalize() # Sign the transaction with private key signature = pk.sign(sig_hash) # Replace the dummy lock field with the actual signature in the first witness witness_args.lock = signature # Serialize the updated witness_args and update the transaction's witnesses list tx.witnesses[group_index] = serialize(witness_args) ``` ---------------------------------------- TITLE: Generating New CKB Address (Go) DESCRIPTION: Shows how to generate a new random private key and derive a secp256k1_blake160_signhash_all lock script from it. This script is then used to create and encode a new CKB address for the test network. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/docs/sdk-and-devtool/go.mdx#_snippet_8 LANGUAGE: Go CODE: ``` // Generate a new address randomly key, err := secp256k1.RandomNew() if err != nil { // handle error } script := systemscript.Secp256K1Blake160SignhashAll(key) addr := &address.Address{Script: script, Network: types.NetworkTest} encodedAddr, err := addr.Encode() ``` ---------------------------------------- TITLE: Example CKB Transaction JSON DESCRIPTION: Provides a complete JSON example illustrating the structure and fields of a CKB transaction, including version, cell dependencies, header dependencies, inputs, outputs, output data, and witnesses. This example demonstrates the format and typical values for each field. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/docs/tech-explanation/transaction.md#_snippet_0 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: Reading Message from CKB Cell (TypeScript) DESCRIPTION: This asynchronous function retrieves a specific CKB Live Cell using its transaction hash and output index, extracts the raw data, decodes it from hexadecimal to UTF-8, and displays it via an alert. It requires a CKB client instance (`cccClient`) and a hex-to-UTF8 decoding utility (`hexToUtf8`). SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/docs/dapp/write-message.mdx#_snippet_5 LANGUAGE: TypeScript CODE: ``` export async function readOnChainMessage(txHash: string, index = "0x0") {\n const cell = await cccClient.getCellLive({ txHash, index }, true);\n if (cell == null) {\n return alert("Cell not found, please retry later");\n }\n const data = cell.outputData;\n const msg = hexToUtf8(data);\n alert("read msg: " + msg);\n return msg;\n} ``` ---------------------------------------- TITLE: Loading Cell Data with CKB Syscalls C DESCRIPTION: This CKB script demonstrates how to use syscalls, specifically `ckb_load_cell_data`, to read data from output cells. It iterates through output cells, loading the first 6 bytes of data into a buffer. If any cell's data starts with the string "carrot", the script returns -1, indicating failure; otherwise, it returns 0 upon checking all output cells. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/docs/script-course/intro-to-script-2.md#_snippet_2 LANGUAGE: C CODE: ``` #include #include "ckb_syscalls.h" int main(int argc, char* argv[]) { int ret; size_t index = 0; uint64_t len = 0; /* (1) */ unsigned char buffer[6]; while (1) { len = 6; memset(buffer, 0, 6); ret = ckb_load_cell_data(buffer, &len, 0, index, CKB_SOURCE_OUTPUT); /* (2) */ if (ret == CKB_INDEX_OUT_OF_BOUND) { /* (3) */ break; } if (memcmp(buffer, "carrot", 6) == 0) { return -1; } index++; } return 0; } ``` ---------------------------------------- TITLE: Creating Transaction Using Deployed Script - Node.js DESCRIPTION: This Node.js snippet, using @ckb-lumos/lumos, demonstrates how to create a transaction that utilizes the previously deployed duktape REPL script. It defines the script using the code hash of the deployed binary and the arguments generated by `native_args_assembler`. It then creates a transaction skeleton, transfers funds, sets the type script of an output cell to the duktape script, and adds the cell containing the deployed binary as a cell dependency. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/docs/script-course/intro-to-script-5.md#_snippet_13 LANGUAGE: javascript CODE: ``` > const duktapeReplCodeHash = lumos.utils.ckbHash(bytes.bytify("0x" + data.toString("hex"))); > const duktapeTypeScript = { codeHash: duktapeReplCodeHash, hashType: "data", args: "0x370000000c00000033000000000000001f000000434b422e6465627567282249276d2072756e6e696e6720696e204a5322290a04000000", }; > let txSkeleton = lumos.helpers.TransactionSkeleton({ cellProvider: indexer }); > txSkeleton = await lumos.commons.common.transfer(txSkeleton,[wallet.address],wallet2.address,"150" + "00000000"); > txSkeleton.update("outputs", (outputs) => { let cell = outputs.first(); cell.cellOutput.type = duktapeTypeScript; return outputs; }); > txSkeleton = lumos.helpers.addCellDep(txSkeleton, { outPoint: { txHash: duktapeReplTxHash, index: "0x0", }, depType: "code", }); ``` ---------------------------------------- TITLE: Transfer CKB Tokens using Lumos and CKB-CCC (React/TypeScript) DESCRIPTION: This React component handles state for transfer inputs, validates the recipient address using CKB-CCC, composes a CKB transfer transaction using Lumos common scripts (transfer, payFeeByFeeRate), converts the Lumos skeleton to a CKB-CCC transaction, adds optional output data, and finally signs and sends the transaction using the CKB-CCC signer. It depends on @ckb-ccc/connector-react, @ckb-lumos/common-scripts, @ckb-lumos/ckb-indexer, and React hooks. SOURCE: https://github.com/nervosnetwork/docs.nervos.org/blob/develop/website/docs/sdk-and-devtool/ccc.mdx#_snippet_10 LANGUAGE: TypeScript CODE: ``` "use client"; import React, { useState } from "react"; import { TextInput } from "@/src/components/Input"; import { Button } from "@/src/components/Button"; import { ccc } from "@ckb-ccc/connector-react"; import common, { registerCustomLockScriptInfos, } from "@ckb-lumos/common-scripts/lib/common"; import { generateDefaultScriptInfos } from "@ckb-ccc/lumos-patches"; import { Indexer } from "@ckb-lumos/ckb-indexer"; import { TransactionSkeleton } from "@ckb-lumos/helpers"; import { predefined } from "@ckb-lumos/config-manager"; import { Textarea } from "@/src/components/Textarea"; import { useGetExplorerLink } from "@/src/utils"; import { useApp } from "@/src/context"; import { ButtonsPanel } from "@/src/components/ButtonsPanel"; export default function TransferLumos() { const { signer, createSender } = useApp(); const { log, error } = createSender("Transfer with Lumos"); const { explorerTransaction } = useGetExplorerLink(); const [transferTo, setTransferTo] = useState(""); const [amount, setAmount] = useState(""); const [data, setData] = useState(""); return (