nervosnetwork / capsule

Capsule is an out-of-box development framework for creating smart contract on Nervos' CKB.
MIT License
60 stars 34 forks source link

[Question] How to calculate script hash from a Script instance? #111

Closed phroi closed 1 year ago

phroi commented 1 year ago

As per title, I'm wondering: within a Rust L1 script, what's the most idiomatic way to calculate script hash from a Script instance?

I'm asking here since GitHub issues are SEO friendly and very likely in the future there will be other L1 developers wondering the same :wink:

Phroi

blckngm commented 1 year ago

Generally, just use a blake2b crate that supports no_std and calculate blake2b(script.as_slice()) (with ckb output length and personalization).

It's also possible that you can load the script hash with a syscall, if the script is the type/lock script of a cell referenced/created by the current tx, see

phroi commented 1 year ago

It's also possible that you can load the script hash with a syscall,

If it was possible to load the hash, of course that would be the preferred choice :wink:

Generally, just use a blake2b crate that supports no_std and calculate blake2b(script.as_slice()) (with ckb output length and personalization).

A valid no_std blake2b crate is blake2b-ref and from the Transaction Structure RFC the blake2b parameters are:

  • output digest size: 32
  • personalization: ckb-default-hash

@sopium would you agree on the following implementation?

use blake2b_ref::Blake2bBuilder;

fn script_hash(script: &Script) -> [u8; 32] {
    let mut output = [0u8; 32];
    let mut blake2b = Blake2bBuilder::new(32).personal(b"ckb-default-hash").build();
    blake2b.update(script.as_slice());
    blake2b.finalize(&mut output);
    output
}
blckngm commented 1 year ago

Yes, that's right.

phroi commented 1 year ago

Perfect, thanks a lot!! :pray: