Cells 名字(account-cell-type)约束Cells name (account-cell-type) Constraints
来源:LusoCryptoLabs/cells-contracts @34dad3c / contracts/account-cell-type/src/main.rs + crates/cells-core · 主网 0xd96c…fe54 / 测试网 0xe070…d1d9(type,cellula-sdk)Source: LusoCryptoLabs/cells-contracts @34dad3c / contracts/account-cell-type/src/main.rs + crates/cells-core · mainnet 0xd96c…fe54 / testnet 0xe070…d1d9 (type, cellula-sdk)
Cells / Cellula (.cell names)
- 官网Websitecellula.id
- 文档Docscellula.id/developers
- GitHubGitHubgithub.com/LusoCryptoLabs/cells-contracts
- XXx.com/lusocryptolabs
来源:Source: cells-contracts repo homepage + README; X from the LusoCryptoLabs GitHub profile
0 → 1创世 genesisGenesis
Inputs 输入Inputs
input[*] genesis tokeninput[*] genesis tokenCell{
capacity: any,
lock: any,
type: type-id cell: type hash[0..20] = namespace,
data: any
}
➜
Outputs 输出Outputs
output[0] 根哨兵output[0] root sentinelCell{
capacity: any,
lock: account-lock (not checked at genesis),
type: { codeHash: ACCOUNT_TYPE, hashType: type, args: namespace 20B },
data: AccountData{ version 0x03, witness_hash, next = 0, expires,
owner = 0, manager = 0, label empty (98B) }
}
witnesses(WitnessArgs)witnesses (WitnessArgs)
witnesses[0]witnesses[0]{ output_type: records of output[0] }
// no action is read when there are no AccountCell inputs
data:AccountData v3(98 字节头 + label)data: AccountData v3 (98-byte header + label)
version1B
witness_hash32B
next20B
expires5B LE
owner20B
manager20B
label1–40B
- version 1B 布局版本layout version = 0x03 (20)
- witness_hash 32B blake2b(记录 payload),记录在 witnesses[i].output_typeblake2b(records payload); records live in witnesses[i].output_type = blake2b(witness) (21)
- next 20B 环中后继名字的 id(id = blake2b(label)[0..20],不存储)id of the successor in the ring (id = blake2b(label)[0..20], not stored) 重链规则relink rules (24 / 25)
- expires 5B LE 到期 unix 秒expiry, unix seconds 注册 1–10 年1–10 years at register (39 / 43)
- owner 20B owner lock hash 前 20 字节(同意 = 花费该 lock 下的输入)first 20 bytes of the owner lock hash (consent = spending an input under it) ≠ 0,≠ account-lock≠ 0, ≠ account-lock (38 / 44)
- manager 20B 受托人 lock hash 前 20 字节,可改记录;无委托时 = ownerdelegate lock hash prefix; may edit records; = owner when none ≠ 0,≠ account-lock≠ 0, ≠ account-lock (38 / 44)
- label 1–40B 名字(不含 .cell),a-z 0-9 -,最多一个点(子名)the name without .cell; a-z 0-9 -, at most one dot (sub-name) 字符集 / 长度 / 深度charset / length / depth (30 / 31 / 45)
version0x03
witness_hash0x5f0c…(32B)
next0x9a1e…(20B)
expires0x80b7c96e00 ← 0x6ec9b780 = 1858713472 (2028-11-24 UTC)
owner0x3c4b…(20B)
manager0x3c4b…(20B, = owner)
label0x616c696365 ← "alice"
type.args(20 字节)type.args (20 bytes)
namespace20B
- namespace 20B genesis token 的 type hash 前 20 字节;也是 commitment 的一部分first 20 bytes of the genesis token type hash; also part of the commitment ≥ 20B (4)
args0x1a2b…(20B)
源码中 34 GenesisSeedMissing 仍可触发(SPEC.md 说 34 不可达,与代码不符)Code 34 GenesisSeedMissing is still reachable in code (SPEC.md says 34 is unreachable — doc/code discrepancy)
限制Constraints
- genesis token:: 消耗 type hash 前 20 字节 = args 的输入consume an input whose type hash[0..20] = args (34)
- 输出数outputs:: 恰好 1 个 AccountCell 输出exactly 1 AccountCell output (25)
- id / next:: id = next = 0id = next = 0 (25)
- data:: 长度恰为 98(空 label),owner = manager = 0exactly 98 bytes (empty label), owner = manager = 0 (20)
- witness:: blake2b(witnesses[0].output_type) = witness_hashblake2b(witnesses[0].output_type) = witness_hash (21)
1 → 2注册 registerRegister
Inputs 输入Inputs
input[0] 前驱 AccountCell pinput[0] predecessor AccountCell pCell{
capacity: P,
lock: { codeHash: ACCOUNT_LOCK, hashType: type, args: 0x },
type: { codeHash: ACCOUNT_TYPE, hashType: type, args: namespace 20B },
data: AccountData{ version 0x03, witness_hash, next, expires,
owner, manager, label,
next: N // x.id ∈ (p.id, N) }
}
input[1] CommitCell(注册者自己的)input[1] CommitCell (registrant’s own)Cell{
since: 0xC0… relative timestamp ≥ 60 s,
capacity: any,
lock: registrant lock: hash[0..20] = x.owner, not anyone-can-pay,
type: null // not checked,
data: blake2b(namespace ‖ label ‖ owner20 ‖ secret32) // exactly 32B
}
// any input position; found by data match
input[2] 付款 cell(注册者)input[2] payment cell (registrant)Cell{
capacity: fee + rent + tx fee,
lock: registrant lock,
type: null,
data: 0x
}
// not checked by the script; just funds the outputs
➜
Outputs 输出Outputs
output[0] p′output[0] p′Cell{
capacity: ≥ P,
lock: { codeHash: ACCOUNT_LOCK, hashType: type, args: 0x },
type: { codeHash: ACCOUNT_TYPE, hashType: type, args: namespace 20B },
data: AccountData{ version 0x03, witness_hash, next, expires,
owner, manager, label,
next = x.id // every other field = p }
}
output[1] 新名字 xoutput[1] new name xCell{
capacity: ≥ 240 CKB,
lock: { codeHash: ACCOUNT_LOCK, hashType: type, args: 0x },
type: { codeHash: ACCOUNT_TYPE, hashType: type, args: namespace 20B },
data: AccountData{ version 0x03, witness_hash,
next: p.next, expires: now + 1–10 y,
owner: ≠0, ≠ account-lock, manager: = owner,
label: a-z0-9-, 1–40B, ≤1 dot }
}
output[2] treasuryoutput[2] treasuryCell{
capacity: Σ pure ≥ fee×factor − referral + sale fees owed,
lock: lock hash == TREASURY_LOCK_HASH (mainnet 0x57d9…742d),
type: null // typed outputs do not count,
data: 0x
}
output[3] 找零(可选)output[3] change (optional)Cell{
capacity: rest,
lock: registrant lock,
type: null,
data: 0x
}
cell_depscell_deps
cell_dep:ACCOUNT_TYPE 代码cell_dep: ACCOUNT_TYPE codecode cell (mainnet 0x3072…bf0b:0)
// needed by CKB to run the type; not read by the script
cell_dep:ACCOUNT_LOCK 代码cell_dep: ACCOUNT_LOCK codecode cell (mainnet 0x522c…9268:1)
// needed by CKB to run the lock; not read by the script
cell_dep:付款 / 授权 lock 的代码cell_dep: code of the payer / owner lockse.g. secp256k1 dep_group — for the other inputs’ locks
cell_dep:价格 cell(可选)cell_dep: price cell (optional)Cell{ type: hash == PRICE_CELL_TYPE_HASH (mainnet 0x3f1c…7586),
data: 0x01 ‖ bps u32 LE }
// price_factor(): found by type hash; missing/malformed → full price
cell_dep:推荐人名字(可选)cell_dep: inviter name (optional)Cell{ type: same ACCOUNT_TYPE script, data: AccountData{ owner: I } }
// referral_discount(): every cell dep with this type is a candidate;
// pays only if I ≠ treasury, no input under I, and pure outputs to I ≥ cut
header_depsheader_deps
header_deps:CommitCell 所在区块header_deps: the CommitCell’s blockblock hash of input[1]’s creating block
// header_time_seconds(): load_header(commit input) → now = timestamp/1000
// term = x.expires − now must be 1–10 years
witnesses(WitnessArgs)witnesses (WitnessArgs)
witnesses[0]witnesses[0]{ lock: (input[0] is account-lock: unused),
input_type: "register" // action, ASCII
output_type: records of output[0] p′ // blake2b = p′.witness_hash }
witnesses[1]witnesses[1]{ lock: signature for input[1]’s lock group,
input_type: secret 32B // witnesses[x index].input_type
output_type: records of output[1] x // blake2b = x.witness_hash }
witnesses[2…]witnesses[2…]other inputs’ lock witnesses (may be empty in the same lock group)
子名时额外需要 / sub-name only(label 含一个点,如 shop.alice)sub-name only (label has one dot, e.g. shop.alice)
额外 cell_dep:父名 AccountCellextra cell_dep: parent AccountCellCell{ type: same ACCOUNT_TYPE script,
data: AccountData{ label: = parent ("alice"), owner: PO, expires: PE } }
// require_parent(): missing → 40
额外 input:父 owner 的 cellextra input: a cell of the parent ownerCell{ lock: hash[0..20] = PO, consenting lock }
// require_owner(PO) → 29; and x.expires ≤ PE → 41
// fee = parent length line / 5
data:AccountData v3(98 字节头 + label)data: AccountData v3 (98-byte header + label)
version1B
witness_hash32B
next20B
expires5B LE
owner20B
manager20B
label1–40B
- version 1B 布局版本layout version = 0x03 (20)
- witness_hash 32B blake2b(记录 payload),记录在 witnesses[i].output_typeblake2b(records payload); records live in witnesses[i].output_type = blake2b(witness) (21)
- next 20B 环中后继名字的 id(id = blake2b(label)[0..20],不存储)id of the successor in the ring (id = blake2b(label)[0..20], not stored) 重链规则relink rules (24 / 25)
- expires 5B LE 到期 unix 秒expiry, unix seconds 注册 1–10 年1–10 years at register (39 / 43)
- owner 20B owner lock hash 前 20 字节(同意 = 花费该 lock 下的输入)first 20 bytes of the owner lock hash (consent = spending an input under it) ≠ 0,≠ account-lock≠ 0, ≠ account-lock (38 / 44)
- manager 20B 受托人 lock hash 前 20 字节,可改记录;无委托时 = ownerdelegate lock hash prefix; may edit records; = owner when none ≠ 0,≠ account-lock≠ 0, ≠ account-lock (38 / 44)
- label 1–40B 名字(不含 .cell),a-z 0-9 -,最多一个点(子名)the name without .cell; a-z 0-9 -, at most one dot (sub-name) 字符集 / 长度 / 深度charset / length / depth (30 / 31 / 45)
version0x03
witness_hash0x5f0c…(32B)
next0x9a1e…(20B)
expires0x80b7c96e00 ← 0x6ec9b780 = 1858713472 (2028-11-24 UTC)
owner0x3c4b…(20B)
manager0x3c4b…(20B, = owner)
label0x616c696365 ← "alice"
witnesses[i](WitnessArgs,i = 该 AccountCell 的输出序号)witnesses[i] (WitnessArgs, i = output index of the AccountCell)
witnesses[0].input_typeASCII
witnesses[i].output_typerecords
witnesses[x].input_type32B
- witnesses[0].input_type ASCII 动作名:register / renew / edit_records / edit_manager / transfer / recycleaction name: register / renew / edit_records / edit_manager / transfer / recycle 必须可识别must be known (23)
- witnesses[i].output_type records 记录集:u16 LE 条数,每条 key(u8 len) ‖ label(u8 len) ‖ value(u16 len) ‖ ttl(u32)records: u16 LE count; each key(u8 len) ‖ label(u8 len) ‖ value(u16 len) ‖ ttl(u32) blake2b = witness_hash (21)
- witnesses[x].input_type 32B register 时新名字 x 的 commit secretcommit secret of the new name x (register only) = 32 字节= 32 bytes (36)
witnesses[0].input_type0x7265676973746572 ← "register"
output_type0x0100 0b 616464726573732e333039 00 2a00 636b62317179… 00000000 ← 1 record: address.309
费用表(每年):≥5 字符 5,000;4:20,000;3:80,000;2:200,000;1:500,000 CKB;子名 = 父档 / 5;每 5 年免 1 年;价格 cell(cell dep)只能打折;推荐人(cell dep 中的名字)拿 10%。Fee per year: ≥5 chars 5,000; 4: 20,000; 3: 80,000; 2: 200,000; 1: 500,000 CKB; sub-name = parent line / 5; one year in five free; the price cell (cell dep) can only discount; an inviter (a name in cell deps) gets 10%.
限制Constraints
- 数量arity:: 1 个 AccountCell 进,2 个出1 AccountCell in, 2 out (25)
- x.id:: ≠ 0(根)≠ 0 (root) (46)
- x.owner:: 非全 0not all-zero (38)
- x.owner / manager:: ≠ account-lock hash 前 20 字节≠ account-lock hash[0..20] (44)
- x.manager = x.owner= x.owner (27)
- x.id:: 严格位于 (p.id, p.next)(环绕)strictly inside (p.id, p.next) (wrap-around) (24)
- relink:: p′.id = p.id,p′.next = x.id,x.next = p.nextp′.id = p.id, p′.next = x.id, x.next = p.next (25)
- p′:: witness_hash / expires / owner / manager / label / lock 不变,capacity 不减witness_hash / expires / owner / manager / label / lock unchanged, capacity not reduced (27)
- x.capacity ≥ 240 CKB≥ 240 CKB (35)
- lock:: 输出 AccountCell lock = 输入的 account-lockoutput AccountCell lock = the input account-lock (48)
- label:: 1–40 字节 / 字符集 / 最多一个点1–40 bytes / charset / at most one dot (31 / 30 / 45)
- secret:: witnesses[x].input_type 为 32 字节且有匹配 CommitCellwitnesses[x].input_type is 32 bytes and a matching CommitCell exists (36)
- CommitCell:: holder = x.owner 且 consentsholder = x.owner and consents (47)
- CommitCell since:: 相对时间戳 ≥ 60 srelative timestamp ≥ 60 s (37)
- expires:: 期限 ≥ 1 年(以 CommitCell 区块时间为 now)term ≥ 1 year (now = CommitCell block time) (39)
- expires ≤ 10 年≤ 10 years (43)
- 子名sub-name:: 父名 cell dep 存在;父 owner 同意;不晚于父到期parent cell dep exists; parent owner consents; not outliving the parent (40 / 29 / 41)
- treasury:: 纯输出足额pure outputs paid in full (42)
1 → 1续期 renewRenew
Inputs 输入Inputs
input[0] 名字 AccountCellinput[0] name AccountCellCell{
capacity: P,
lock: { codeHash: ACCOUNT_LOCK, hashType: type, args: 0x },
type: { codeHash: ACCOUNT_TYPE, hashType: type, args: namespace 20B },
data: AccountData{ version 0x03, witness_hash, next, expires,
owner, manager, label }
}
➜
Outputs 输出Outputs
output[0] 名字′output[0] name′Cell{
capacity: ≥ P,
lock: { codeHash: ACCOUNT_LOCK, hashType: type, args: 0x },
type: { codeHash: ACCOUNT_TYPE, hashType: type, args: namespace 20B },
data: AccountData{ expires: E′ > E (≤ +10 y); all else unchanged }
}
output[1] treasuryoutput[1] treasuryCell{
capacity: Σ pure ≥ fee(label, years)×factor + sale fees owed,
lock: lock hash == TREASURY_LOCK_HASH,
type: null,
data: 0x
}
cell_depscell_deps
cell_dep:ACCOUNT_TYPE 代码cell_dep: ACCOUNT_TYPE codecode cell (mainnet 0x3072…bf0b:0)
// needed by CKB to run the type; not read by the script
cell_dep:ACCOUNT_LOCK 代码cell_dep: ACCOUNT_LOCK codecode cell (mainnet 0x522c…9268:1)
// needed by CKB to run the lock; not read by the script
cell_dep:付款 / 授权 lock 的代码cell_dep: code of the payer / owner lockse.g. secp256k1 dep_group — for the other inputs’ locks
cell_dep:价格 cell(可选)cell_dep: price cell (optional)Cell{ type: hash == PRICE_CELL_TYPE_HASH (mainnet 0x3f1c…7586),
data: 0x01 ‖ bps u32 LE }
// price_factor(): found by type hash; missing/malformed → full price
witnesses(WitnessArgs)witnesses (WitnessArgs)
witnesses[0]witnesses[0]{ input_type: "renew",
output_type: records of output[0] // blake2b = witness_hash }
子名时额外需要 / sub-name onlysub-name only
额外 cell_dep:父名 AccountCellextra cell_dep: parent AccountCellCell{ type: same ACCOUNT_TYPE, data: { label: = parent, owner: PO, expires: ≥ E′ } } // 40 / 41
额外 input:父 owner 的 cellextra input: a cell of the parent ownerCell{ lock: hash[0..20] = PO } // 29
普通名字任何人可续期;子名只有父 owner 能续。Anyone may renew a plain name; only the parent owner can renew a sub-name.
限制Constraints
- 数量arity:: 1 进 1 出1 in 1 out (27)
- data:: 只允许 expires 增大;id/next/label/owner/manager/witness_hash 不变only expires grows; id/next/label/owner/manager/witness_hash unchanged (27)
- lock / capacity:: lock 不变,capacity 不减lock unchanged, capacity not reduced (27)
- expires:: 延长 ≤ 10 年extension ≤ 10 years (43)
- treasury:: 纯输出足额pure outputs paid in full (42)
- 子名sub-name:: 父名 cell dep;不晚于父;父 owner 同意parent cell dep; not outliving it; parent owner consents (40 / 41 / 29)
1 → 1改记录 edit_recordsEdit records
Inputs 输入Inputs
input[0] 名字 AccountCellinput[0] name AccountCellCell{
capacity: P,
lock: { codeHash: ACCOUNT_LOCK, hashType: type, args: 0x },
type: { codeHash: ACCOUNT_TYPE, hashType: type, args: namespace 20B },
data: AccountData{ version 0x03, witness_hash, next, expires,
owner, manager, label }
}
input[1] owner 或 manager 授权 cellinput[1] owner / manager authorization cellCell{
capacity: any,
lock: lock hash[0..20] = owner / manager, a consenting lock,
type: any,
data: any
}
// any position; spending it is the consent (no signature read by the type)
➜
Outputs 输出Outputs
output[0] 名字′output[0] name′Cell{
capacity: ≥ P,
lock: { codeHash: ACCOUNT_LOCK, hashType: type, args: 0x },
type: { codeHash: ACCOUNT_TYPE, hashType: type, args: namespace 20B },
data: AccountData{ witness_hash may change; all else unchanged }
}
cell_depscell_deps
cell_dep:ACCOUNT_TYPE 代码cell_dep: ACCOUNT_TYPE codecode cell (mainnet 0x3072…bf0b:0)
// needed by CKB to run the type; not read by the script
cell_dep:ACCOUNT_LOCK 代码cell_dep: ACCOUNT_LOCK codecode cell (mainnet 0x522c…9268:1)
// needed by CKB to run the lock; not read by the script
cell_dep:付款 / 授权 lock 的代码cell_dep: code of the payer / owner lockse.g. secp256k1 dep_group — for the other inputs’ locks
witnesses(WitnessArgs)witnesses (WitnessArgs)
witnesses[0]witnesses[0]{ input_type: "edit_records",
output_type: records of output[0] // blake2b = witness_hash }
witnesses[i](WitnessArgs,i = 该 AccountCell 的输出序号)witnesses[i] (WitnessArgs, i = output index of the AccountCell)
witnesses[0].input_typeASCII
witnesses[i].output_typerecords
witnesses[x].input_type32B
- witnesses[0].input_type ASCII 动作名:register / renew / edit_records / edit_manager / transfer / recycleaction name: register / renew / edit_records / edit_manager / transfer / recycle 必须可识别must be known (23)
- witnesses[i].output_type records 记录集:u16 LE 条数,每条 key(u8 len) ‖ label(u8 len) ‖ value(u16 len) ‖ ttl(u32)records: u16 LE count; each key(u8 len) ‖ label(u8 len) ‖ value(u16 len) ‖ ttl(u32) blake2b = witness_hash (21)
- witnesses[x].input_type 32B register 时新名字 x 的 commit secretcommit secret of the new name x (register only) = 32 字节= 32 bytes (36)
witnesses[0].input_type0x7265676973746572 ← "register"
output_type0x0100 0b 616464726573732e333039 00 2a00 636b62317179… 00000000 ← 1 record: address.309
限制Constraints
- 数量arity:: 1 进 1 出1 in 1 out (27)
- data:: 只允许 witness_hash 变化only witness_hash may change (27)
- lock / capacity:: lock 不变,capacity 不减lock unchanged, capacity not reduced (27)
- 授权auth:: owner 或 manager 同意owner or manager consents (29)
1 → 1改受托人 edit_managerEdit manager
Inputs 输入Inputs
input[0] 名字 AccountCellinput[0] name AccountCellCell{
capacity: P,
lock: { codeHash: ACCOUNT_LOCK, hashType: type, args: 0x },
type: { codeHash: ACCOUNT_TYPE, hashType: type, args: namespace 20B },
data: AccountData{ version 0x03, witness_hash, next, expires,
owner, manager, label }
}
input[1] owner 授权 cellinput[1] owner authorization cellCell{
capacity: any,
lock: lock hash[0..20] = owner, a consenting lock,
type: any,
data: any
}
// any position; spending it is the consent (no signature read by the type)
➜
Outputs 输出Outputs
output[0] 名字′output[0] name′Cell{
capacity: ≥ P,
lock: { codeHash: ACCOUNT_LOCK, hashType: type, args: 0x },
type: { codeHash: ACCOUNT_TYPE, hashType: type, args: namespace 20B },
data: AccountData{ manager: ≠0, ≠ account-lock; all else unchanged }
}
cell_depscell_deps
cell_dep:ACCOUNT_TYPE 代码cell_dep: ACCOUNT_TYPE codecode cell (mainnet 0x3072…bf0b:0)
// needed by CKB to run the type; not read by the script
cell_dep:ACCOUNT_LOCK 代码cell_dep: ACCOUNT_LOCK codecode cell (mainnet 0x522c…9268:1)
// needed by CKB to run the lock; not read by the script
cell_dep:付款 / 授权 lock 的代码cell_dep: code of the payer / owner lockse.g. secp256k1 dep_group — for the other inputs’ locks
witnesses(WitnessArgs)witnesses (WitnessArgs)
witnesses[0]witnesses[0]{ input_type: "edit_manager",
output_type: records of output[0] // blake2b = witness_hash }
限制Constraints
- 数量arity:: 1 进 1 出1 in 1 out (27)
- data:: 只允许 manager 变化(witness_hash 也不变)only manager may change (witness_hash fixed) (27)
- manager:: 非全 0not all-zero (38)
- manager:: ≠ account-lock≠ account-lock (44)
- lock / capacity:: lock 不变,capacity 不减lock unchanged, capacity not reduced (27)
- 授权auth:: owner 同意owner consents (29)
1 → 1转让 transferTransfer
Inputs 输入Inputs
input[0] 名字 AccountCellinput[0] name AccountCellCell{
capacity: P,
lock: { codeHash: ACCOUNT_LOCK, hashType: type, args: 0x },
type: { codeHash: ACCOUNT_TYPE, hashType: type, args: namespace 20B },
data: AccountData{ version 0x03, witness_hash, next, expires,
owner, manager, label }
}
input[1] 原 owner 授权 cellinput[1] owner authorization cellCell{
capacity: any,
lock: lock hash[0..20] = owner, a consenting lock,
type: any,
data: any
}
// any position; spending it is the consent (no signature read by the type)
➜
Outputs 输出Outputs
output[0] 名字′output[0] name′Cell{
capacity: ≥ P,
lock: { codeHash: ACCOUNT_LOCK, hashType: type, args: 0x },
type: { codeHash: ACCOUNT_TYPE, hashType: type, args: namespace 20B },
data: AccountData{ owner: B (≠0, ≠ account-lock), manager = B;
witness_hash / expires unchanged }
}
cell_depscell_deps
cell_dep:ACCOUNT_TYPE 代码cell_dep: ACCOUNT_TYPE codecode cell (mainnet 0x3072…bf0b:0)
// needed by CKB to run the type; not read by the script
cell_dep:ACCOUNT_LOCK 代码cell_dep: ACCOUNT_LOCK codecode cell (mainnet 0x522c…9268:1)
// needed by CKB to run the lock; not read by the script
cell_dep:付款 / 授权 lock 的代码cell_dep: code of the payer / owner lockse.g. secp256k1 dep_group — for the other inputs’ locks
witnesses(WitnessArgs)witnesses (WitnessArgs)
witnesses[0]witnesses[0]{ input_type: "transfer",
output_type: records of output[0] // blake2b = witness_hash }
限制Constraints
- 数量arity:: 1 进 1 出1 in 1 out (27)
- data:: id/next/label/expires/witness_hash 不变(记录随名字走)id/next/label/expires/witness_hash unchanged (records travel) (27)
- owner:: 非全 0not all-zero (38)
- owner:: ≠ account-lock≠ account-lock (44)
- manager = 新 owner= new owner (27)
- lock / capacity:: lock 不变,capacity 不减lock unchanged, capacity not reduced (27)
- 授权auth:: 原 owner 同意current owner consents (29)
2 → 1回收 recycleRecycle
Inputs 输入Inputs
input[0] 前驱 AccountCell pinput[0] predecessor pCell{
capacity: P,
lock: { codeHash: ACCOUNT_LOCK, hashType: type, args: 0x },
type: { codeHash: ACCOUNT_TYPE, hashType: type, args: namespace 20B },
data: AccountData{ version 0x03, witness_hash, next, expires,
owner, manager, label,
next: x.id }
}
input[1] 过期名字 xinput[1] expired name xCell{
since: 0x40… absolute timestamp ≥ x.expires + 2,592,000,
capacity: X,
lock: { codeHash: ACCOUNT_LOCK, hashType: type, args: 0x },
type: { codeHash: ACCOUNT_TYPE, hashType: type, args: namespace 20B },
data: AccountData{ version 0x03, witness_hash, next, expires,
owner, manager, label,
next: N }
}
➜
Outputs 输出Outputs
output[0] p′output[0] p′Cell{
capacity: ≥ P,
lock: { codeHash: ACCOUNT_LOCK, hashType: type, args: 0x },
type: { codeHash: ACCOUNT_TYPE, hashType: type, args: namespace 20B },
data: AccountData{ version 0x03, witness_hash, next, expires,
owner, manager, label,
next = N; all else = p }
}
output[1…] 任意output[1…] anythingX capacity: destination not constrained
cell_depscell_deps
cell_dep:ACCOUNT_TYPE 代码cell_dep: ACCOUNT_TYPE codecode cell (mainnet 0x3072…bf0b:0)
// needed by CKB to run the type; not read by the script
cell_dep:ACCOUNT_LOCK 代码cell_dep: ACCOUNT_LOCK codecode cell (mainnet 0x522c…9268:1)
// needed by CKB to run the lock; not read by the script
witnesses(WitnessArgs)witnesses (WitnessArgs)
witnesses[0]witnesses[0]{ input_type: "recycle",
output_type: records of output[0] p′ }
since (x input)
flags1B
timestamp7B
- flags 1B 0x40 = 绝对 + 时间戳0x40 = absolute + timestamp = 0x40 (28)
- timestamp 7B unix 秒unix seconds ≥ expires + 30d (28)
since0x400000006f0c5a00 ← ts 0x6f0c5a00
任何人可回收;x 的 capacity 去向不受限制。Anyone may recycle; where x’s capacity goes is not constrained.
限制Constraints
- 数量arity:: 2 进 1 出2 in 1 out (25)
- relink:: p′.next = x.next;x.id = p.nextp′.next = x.next; x.id = p.next (25)
- p′:: label/expires/owner/manager/witness_hash/lock 不变,capacity 不减label/expires/owner/manager/witness_hash/lock unchanged, capacity not reduced (27)
- x:: 不是根not the root (46)
- x since:: 绝对时间戳 ≥ expires + 2,592,000 sabsolute timestamp ≥ expires + 2,592,000 s (28)
部署与来源Deployments & source 未核验unverified
源码source LusoCryptoLabs/cells-contracts@34dad3c2 · contracts/account-cell-type/src/main.rs · crates/cells-core/src/lib.rs (exact commit read when writing spec/plugin (default-branch HEAD, 2026-09-28). Deployment constants from cellula-sdk@0.2.1 dist/deployments.js and docs/TRUST.md.)
二进制核验binary check 未核验unverified Live mainnet code cell (upgraded 2026-09-28 21:00Z, block 20583638) has data hash 0x99ea…a088, which docs/TRUST.md at this commit lists; README and tests/fixtures still show the pre-upgrade 0xf86b…ae30 (the fixture blake2b = 0xf86b…). No artifact at this commit hashes to 0x99ea…; reproducible build (gcc 13.2 + rustc 1.96 + 3 env values) not attempted. Testnet 0x11d8…352b also unverified.
| 网络network | code_hash | cell_dep | type_id args | 数据哈希data hash | 部署交易deploy tx |
|---|---|---|---|---|---|
| mainnet | 0xd96cee56727a2bb9a21408c154d278df5095fb4b4dcfd50516156424479bfe54 type | 0x3072417e79…7677bf0b:0 code | 0x5170970070…b3de9a5a | 0x99ea60a436…786aa088 | 0x3072417e79…7677bf0b #20583638 |
| testnet | 0xe0706b176678181d982290d93dfcd82098e60cceaa4a87f10f32dcbcc91df1d9 type | 0xe3c204947c…8a3acce4:0 code | 0x4b33dfe66b…2d7a98f0 | 0x11d8695e47…220a352b | 0xe3c204947c…8a3acce4 #22559039 |
链上数据核对于 on-chain data checked 2026-10-21
错误码(cells-core Error):20 MalformedAccountData,21 WitnessHashMismatch,23 UnknownAction,24 NotInPredecessorRange,25 LinkedListBroken,27 StructuralDrift,28 NotExpired,29 Unauthorized,30 InvalidCharset,31 InvalidLength,34 GenesisSeedMissing,35 InsufficientPrice,36 CommitMissing,37 CommitTooYoung,38 NullOwner,39 ExpiryTooSoon,40 ParentMissing,41 ParentOutlived,42 TreasuryUnpaid,43 TermTooLong,44 OwnerIsCellLock,45 TooDeep,46 RootNotRecyclable,47 CommitNotOwned,48 CellLockNotAccountLock;4 Encoding(系统调用 / args 过短)。Error codes (cells-core Error): 20 MalformedAccountData, 21 WitnessHashMismatch, 23 UnknownAction, 24 NotInPredecessorRange, 25 LinkedListBroken, 27 StructuralDrift, 28 NotExpired, 29 Unauthorized, 30 InvalidCharset, 31 InvalidLength, 34 GenesisSeedMissing, 35 InsufficientPrice, 36 CommitMissing, 37 CommitTooYoung, 38 NullOwner, 39 ExpiryTooSoon, 40 ParentMissing, 41 ParentOutlived, 42 TreasuryUnpaid, 43 TermTooLong, 44 OwnerIsCellLock, 45 TooDeep, 46 RootNotRecyclable, 47 CommitNotOwned, 48 CellLockNotAccountLock; 4 Encoding (syscall / args too short).
同意(consents):ACP / anyone-can-pay Omnilock / PW-Lock 输入不算同意;input-type-proxy-lock(deed)需其 args 指向的 type cell 在同意的 lock 下被花费(最多 2 层);sale-lock 输入只同意 transfer。Consent: ACP / anyone-can-pay Omnilock / PW-Lock inputs give none; an input-type-proxy-lock (deed) consents only if the type cell in its args is spent under a consenting lock (≤ 2 levels); a sale-lock input consents to transfer only.
不校验签名:授权完全靠“花费 owner lock 下的 cell”。合约可由单 key / multisig 升级(docs/TRUST.md)。No signatures checked: authorization is “spend a cell under the owner lock”. The contracts are upgradeable by a key/multisig (docs/TRUST.md).
同意(consents):ACP / anyone-can-pay Omnilock / PW-Lock 输入不算同意;input-type-proxy-lock(deed)需其 args 指向的 type cell 在同意的 lock 下被花费(最多 2 层);sale-lock 输入只同意 transfer。Consent: ACP / anyone-can-pay Omnilock / PW-Lock inputs give none; an input-type-proxy-lock (deed) consents only if the type cell in its args is spent under a consenting lock (≤ 2 levels); a sale-lock input consents to transfer only.
不校验签名:授权完全靠“花费 owner lock 下的 cell”。合约可由单 key / multisig 升级(docs/TRUST.md)。No signatures checked: authorization is “spend a cell under the owner lock”. The contracts are upgradeable by a key/multisig (docs/TRUST.md).