secp256k1_blake160_multisig_all(lock)约束secp256k1_blake160_multisig_all (lock) Constraints
来源:ckb-system-scripts / c/secp256k1_blake160_multisig_all.c + c/common.h · 这是 lock script:只在解锁(消耗 cell)时运行Source: ckb-system-scripts / c/secp256k1_blake160_multisig_all.c + c/common.h · This is a lock script: it runs only when the cell is unlocked (consumed)
1 → N解锁花费 multisig cellUnlock & spend a multisig cell
Inputs 输入Inputs
input(同一 lock 的 script group,可多个)input (script group of the same lock; may be several)Cell{
capacity: …,
lock: { codeHash: MULTISIG,
args: blake160(multisig_script) 20B [+ since u64 LE 8B] },
since: 满足 args 中的 since(若有)
}Cell{
capacity: …,
lock: { codeHash: MULTISIG,
args: blake160(multisig_script) 20B [+ since u64 LE 8B] },
since: satisfies the since in args (if any)
}
witness[group 第 1 个 input 的位置]witness[at the group's first input index]WitnessArgs{
lock: multisig_script ‖ signature[0..M-1]
}
长度必须 = 4 + 20·N + 65·MWitnessArgs{
lock: multisig_script ‖ signature[0..M-1]
}
length must = 4 + 20·N + 65·M
➜
Outputs 输出Outputs
outputs:任意 celloutputs: any cellsCell{
capacity: …,
lock: 任意,
type: 任意
}Cell{
capacity: …,
lock: any,
type: any
}
witness.lock 字节布局(multisig_script ‖ signatures)witness.lock byte layout (multisig_script ‖ signatures)
S1B
R1B
M1B
N1B
pubkey_hash[0..N-1]20B × N20B × N
signature[0..M-1]65B × M
- S 1B 保留字段(lock[0])reserved field (lock[0]) 必须为 0must be 0 (-41)
- R 1B require_first_n(lock[1]):pubkey_hash[0..R-1] 必须全部签名require_first_n (lock[1]): pubkey_hash[0..R-1] must all sign R ≤ M ([object Object])
- M 1B threshold(lock[2]):需要的签名个数threshold (lock[2]): number of required signatures 0 < M ≤ N (-43)
- N 1B pubkeys_cnt(lock[3]):公钥总数pubkeys_cnt (lock[3]): total number of pubkeys N > 0 (-42)
- pubkey_hash[0..N-1] 20B × N20B × N blake160(33 字节压缩公钥),顺序有意义(R 引用前 R 个)blake160(33-byte compressed pubkey); order matters (R refers to the first R) 每个签名恢复出的公钥哈希须匹配其中一个尚未使用的each signature's recovered pubkey hash must match a not-yet-used entry (-52)
- signature[0..M-1] 65B × M 可恢复 secp256k1 签名:r‖s(64B) + recid(1B);签名时这部分置 0 参与消息哈希recoverable secp256k1 signature: r‖s (64B) + recid (1B); zero-filled when computing the signing message 可解析 / 可恢复公钥 / 可序列化parsable / pubkey recoverable / serializable (-14 / -11 / -15)
multisig_script = 前 4+20·N 字节(S|R|M|N|pubkey_hashes);lock 总长 ≠ 4+20·N+65·M → (-22);lock < 4 字节 → (-22)multisig_script = first 4+20·N bytes (S|R|M|N|pubkey_hashes); lock length ≠ 4+20·N+65·M → (-22); lock < 4 bytes → (-22)
lock.args 推导Deriving lock.args
blake160(multisig_script)20B
since(可选)since (optional)8B u64 LE
- blake160(multisig_script) 20B blake2b-256(personal="ckb-default-hash")(multisig_script) 取前 20 字节first 20 bytes of blake2b-256(personal="ckb-default-hash")(multisig_script) 必须等于 args[0..20]must equal args[0..20] (-51)
- since(可选)since (optional) 8B u64 LE 时间锁:本 group 所有 input 的 since flags 必须相同,值 ≥ 此值time lock: every input in the group must have identical since flags and a value ≥ this args 长度只能 20 或 28args length must be 20 or 28 ([object Object])
例:2-of-3,R=0(pubkey_hash 为示例值)Example: 2-of-3, R=0 (pubkey hashes are placeholders)
S=001B
R=001B
M=021B
N=031B
11…11 / 22…22 / 33…333 × 20B
multisig_script0x00000203111111111111111111111111111111111111111122222222222222222222222222222222222222223333333333333333333333333333333333333333 (64B)
args (20B)0xbf96e998f1616a35247a9ab89bfd3f485af397fe
args + since (28B)0xbf96e998f1616a35247a9ab89bfd3f485af397fe6400000000010020 ← since=0x2000010000000064(绝对 epoch 100)LE0xbf96e998f1616a35247a9ab89bfd3f485af397fe6400000000010020 ← since=0x2000010000000064 (absolute epoch 100), LE
witness.lock 长度witness.lock length4 + 20×3 + 65×2 = 194 字节(签名时后 130 字节为 0)4 + 20×3 + 65×2 = 194 bytes (last 130 bytes zeroed while signing)
任意 2 个不同成员签名即可;若 R=1,则 pubkey_hash[0] 必须是签名者之一any 2 distinct members can sign; if R=1, pubkey_hash[0] must be one of the signers
限制Constraints
- args:: 长度为 20 或 28 字节length is 20 or 28 bytes (-1)
- args 中的 sincesince in args:: 本 group 每个 input 的 since flags 必须与之完全相同every input in this group must have exactly the same since flags (-23)
- input.since 值input.since value ≥ args 中的 since 值(epoch 按分数比较)≥ the since value in args (epochs compared as fractions) (-24)
- witness:: WitnessArgs 合法且 lock 不为空valid WitnessArgs with non-empty lock (-2)
- witness 大小witness size ≤ 32KB;lock ≥ 4 字节;且 lock 长度 = 4 + 20·N + 65·M≤ 32KB; lock ≥ 4 bytes; and lock length = 4 + 20·N + 65·M (-22)
- blake160(multisig_script):: 等于 args 前 20 字节equals the first 20 bytes of args (-51)
- 签名signatures:: M 个签名各自恢复出 N 个公钥中不同的一个;前 R 个公钥必须都签名the M signatures each recover a distinct one of the N pubkeys; the first R pubkeys must all sign (-52)
- 签名格式signature format:: 无法解析 / 无法恢复公钥 / 无法序列化cannot parse / cannot recover pubkey / cannot serialize (-14 / -11 / -15)
部署与来源Deployments & source 未核验unverified
源码source nervosnetwork/ckb-system-scripts@72eb92fc · c/secp256k1_blake160_multisig_all.c · c/common.h (default-branch HEAD recorded at backfill 2026-10-21; spec/plugin were written from the default branch shortly before (exact read commit not recorded))
二进制核验binary check 未核验unverified no binary or checksum at the recorded commit matched the deployed data hash (reproducible build not attempted)
| 网络network | code_hash | cell_dep | type_id args | 数据哈希data hash | 部署交易deploy tx |
|---|---|---|---|---|---|
| mainnet | 0x5c5069eb0857efc65e1bca0c07df34c31663b3622fd3876c876320fc9634e2a8 type | 0x71a7ba8fc9…8172e46c:1 dep_group | 0xd813c1b15b…68ea9758 | 0x43400de165…8db63bfb | 0xe2fb199810…6d73ff5c #0 |
| testnet | 0x5c5069eb0857efc65e1bca0c07df34c31663b3622fd3876c876320fc9634e2a8 type | 0xf8de3bb47d…4aee5d37:1 dep_group | 0xd813c1b15b…68ea9758 | 0x43400de165…8db63bfb | 0x8f8c79eb66…42635c9f #0 |
链上数据核对于 on-chain data checked 2026-10-20
签名消息 = blake2b(tx_hash ‖ len(w0) ‖ w0(签名部分置 0) ‖ 本 group 其余 witness 的 len‖内容 ‖ 超出 inputs 数量部分的 witness 的 len‖内容);len 为 u64 LEsigning message = blake2b(tx_hash ‖ len(w0) ‖ w0 (signatures zeroed) ‖ len‖content of the group's other witnesses ‖ len‖content of witnesses beyond the inputs count); len is u64 LE
blake160 = blake2b-256(CKB personalization)取前 20 字节;其他错误码:-3 ERROR_SYSCALL,-21 ERROR_SCRIPT_TOO_LONGblake160 = first 20 bytes of blake2b-256 (CKB personalization); other error codes: -3 ERROR_SYSCALL, -21 ERROR_SCRIPT_TOO_LONG
blake160 = blake2b-256(CKB personalization)取前 20 字节;其他错误码:-3 ERROR_SYSCALL,-21 ERROR_SCRIPT_TOO_LONGblake160 = first 20 bytes of blake2b-256 (CKB personalization); other error codes: -3 ERROR_SYSCALL, -21 ERROR_SCRIPT_TOO_LONG