Git Product home page Git Product logo

ckb-std's Introduction

ckb-std

Crates.io

This library contains several modules that help you write CKB contract with Rust.

Usage

Documentation

Modules

  • syscalls module: defines CKB syscalls
  • high_level module: defines high level APIs
  • dynamic_loading module: dynamic loading primitives
  • debug! macro: a println! like macro helps debugging
  • entry! macro: defines contract entry point
  • default_alloc! macro: defines global allocator for no-std rust

Memory allocator

Default allocator uses a mixed allocation strategy:

  • Fixed block heap, only allocate fixed size(64B) memory block
  • Dynamic memory heap, allocate any size memory block

User can invoke macro with arguments to customize the heap size. The default heap size arguments are:

(fixed heap size 4KB, dynamic heap size 516KB, dynamic heap min memory block 64B)

Use the macro with arguments to change it:

default_alloc!(4 * 1024, 516 * 1024, 64)

Beware, use difference heap size or memory block size may affect the verification result of the contract, some runtime errors such as out of memory may occur; you should always test the contract after customizing.

Examples

Check examples and tests to learn how to use.

See also ckb-tool which helps you write tests.

ckb-std's People

Contributors

aimeedeer avatar blckngm avatar cupnfish avatar doitian avatar ethanyuan avatar jjyr avatar joii2020 avatar mohanson avatar quake avatar thewawar avatar xujiandong avatar xxuejie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ckb-std's Issues

Allow to load partial data by syscall

This logic will forbid user to load partial data by syscall.

ckb-std/src/error.rs

Lines 26 to 28 in 98985a2

if actual_data_len > load_len {
return Err(LengthNotEnough(actual_data_len));
}

Consider a case we just want load the code_hash from a script and check the value, with underlying syscall we just call it by:

let offset = 16;
let mut buf = [0u8; 32]
let ret = syscall(&mut buf, offset, ....);

[Bug] VM Internal Error: MemWriteOnExecutablePage

When I upgrade the version of ckb-std from 0.14.0 to 0.15.1 for https://github.com/xcshuan/ecdsa-lock, I can't test the script with env CAPSULE_TEST_ENV=release bacause issue below:

thread 'tests::test_ecverify' panicked at 'pass verification: Error { kind: Script, inner: TransactionScriptError { source: Inputs[0].Lock, cause: VM Internal Error: MemWriteOnExecutablePage } }', src/tests.rs:79:10

Debug mode is ok.

Suggestion: More documentation on SysError.

It would be very beneficial if these error messages had more detail in the documentation. As it is right now, there is not enough detail to give any meaningful hints to the developer on how to fix the problem.

https://github.com/nervosnetwork/ckb-std/blob/master/src/error.rs#L3-L14
https://nervosnetwork.github.io/ckb-std/riscv64imac-unknown-none-elf/doc/ckb_std/error/enum.SysError.html

An example of this is SysError::ItemMissing, which was encountered today by phroi, the developer working on iCKB. He received this error while sending a transaction. He was unable to find the proper documentation for the error. After several hours he figured out it was due to the header deps not being added to the transaction properly.

A helpful error description for each of these would explain it enough that a developer should be able to make a reasonable determination of what could be tried next.

  • Where is this error generated from?
  • What does the error mean?
  • What are common developer mistakes that could lead to this error?

Is there an easier way to get the absolute index of the CellInput load by Source::GroupInput

In the contract I'm implementing, I need to find an output that matches the absolute index of the input in the group.

let input = load_input(index, Source::GroupInput)?;
let input_absolute_index = calculate_input_absolute_index(&input)?;
let output = load_cell(input_absolute_index, Source::Output)?;
fn calculate_input_absolute_index(input: &CellInput) -> Result<usize, Error> {
    load_transaction()?
        .raw()
        .inputs()
        .into_iter()
        .position(|i| i.as_bytes() == input.as_bytes())
        .ok_or(Error::ItemMissing)
}

However, the method I'm using is quite inefficient.

[Question] How to extract `accumulated_rate`?

Hey Cryptape, iCKB here ๐Ÿ‘‹ I was updating iCKB Logic implementation to use ckb-std 0.15.3 and I stumbled upon an apparent issue:

  • I'm unable to unpack the result of load_header(index, source)?.raw().dao()
  • The only implementation to obtain accumulated_rate that works is:
    let d = load_header(index, source)?.raw().dao();
    let accumulated_rate = u64::from_le_bytes([
        u8::from(d.nth8()),
        u8::from(d.nth9()),
        u8::from(d.nth10()),
        u8::from(d.nth11()),
        u8::from(d.nth12()),
        u8::from(d.nth13()),
        u8::from(d.nth14()),
        u8::from(d.nth15()),
    ]);

So my questions are:

  1. What's the best way to extract accumulated_rate?
  2. Can you double check that the unpack of Byte32 is working as expected?

As when I try to unpack dao_data I get the following error:

Compiling ickb_logic v1.2.0 (/home/user/ickb/ickb_logic/contracts/ickb_logic)
error[E0599]: no method named `unpack` found for struct `Byte32` in the current scope
  --> contracts/ickb_logic/src/utils.rs:57:14
   |
57 |     dao_data.unpack();
   |              ^^^^^^ method not found in `Byte32`

warning: unused import: `ckb_types::prelude::Unpack`
 --> contracts/ickb_logic/src/utils.rs:5:5
  |
5 |     ckb_types::prelude::Unpack,
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

Keep up the Great Work,
Phroi

Support for load_inputs

In the partial sign scenario, it is necessary to get all the inputs in the group, but at the moment I can only rely on the error definition๏ผš

   let mut i = 0;
    loop {
        match load_input(i, Source::GroupInput) {
            Ok(_) => {
                ...
                i += 1;
            }
            Err(SysError::IndexOutOfBound) => break,
            Err(_) => return Err(Error::LoopGroupInputs),
        }
    }

It would be very convenient if load_inputs were provided.

Stable rust

Now that the default alloc error handler is stabilized, it's possible to build no_std + alloc programs with stable rust.

A drawback is that the default alloc error handler pulls in fmt, so it might increase binary size.

Disable `debug_assertions` won't ingore function calls in `debug!(..)` statements.

Issue

I have the following code:

#[cfg(debug_assertions)]
use ckb_std::ckb_types::prelude::*;

debug!("script hash = {:#x}", script_hash.pack());

When set debug_assertions = false, the above could NOT be compiled.

Description

When users don't want to print the debug messages, all functions in debug!(..), such as script_hash.pack() in above code, should be ignored and they should never be executed.

ckb-std/src/debug.rs

Lines 38 to 44 in 6764555

($fmt:literal, $($args:expr),+) => {
#[cfg(debug_assertions)]
$crate::syscalls::debug(alloc::format!($fmt, $($args), +));
// Avoid unused warnings.
#[cfg(not(debug_assertions))]
core::mem::drop(($(&$args),+));
};

[feature request] Please support loading dynamic library through type ID

I found that the codes below hardcode let hash_type: u8 = 0; which means loading dynamic library through the hash of outputs_data ๐Ÿ˜“:

let hash_type: u8 = 0;
let mut library = Library::new();
let aligned_size = size;
let aligned_addr = (&mut self.0 as *mut T).cast::<u8>().add(offset);
let code = ckb_dlopen2(
dep_cell_data_hash.as_ptr(),
hash_type,

But loading a dynamic library through type ID is the best practice. So, could you please change it to an argument which can be chosen by the crate users?

THX for any help. ๐Ÿ˜„

Any plans to integrate molecule?

Syscall results are currently raw bytes.
Are there any plans to deserialize syscall results into structs using nostd molecule?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.