ckb_ez/
core.rs

1use ckb_types::prelude::Entity;
2
3pub const SCRIPT_HASH_TYPE_DATA: u8 = 0;
4pub const SCRIPT_HASH_TYPE_TYPE: u8 = 1;
5pub const SCRIPT_HASH_TYPE_DATA1: u8 = 2;
6pub const SCRIPT_HASH_TYPE_DATA2: u8 = 4;
7
8#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
9pub struct Script {
10    pub code_hash: [u8; 32],
11    pub hash_type: u8,
12    pub args: Vec<u8>,
13}
14
15impl Script {
16    pub fn new(code_hash: [u8; 32], hash_type: u8, args: Vec<u8>) -> Self {
17        Self { code_hash, hash_type, args }
18    }
19
20    pub fn new_type_id(args: Vec<u8>) -> Self {
21        Self {
22            code_hash: ckb_chain_spec::consensus::TYPE_ID_CODE_HASH.0,
23            hash_type: ckb_types::core::ScriptHashType::Type.into(),
24            args: args,
25        }
26    }
27
28    pub fn molecule(&self) -> Vec<u8> {
29        crate::molecule::encode_dynvec(vec![
30            crate::molecule::Byte32::new(self.code_hash).molecule(),
31            crate::molecule::Byte::new(self.hash_type).molecule(),
32            crate::molecule::Bytes::new(self.args.clone()).molecule(),
33        ])
34    }
35
36    pub fn molecule_decode(data: &[u8]) -> Self {
37        let result = crate::molecule::decode_dynvec(data);
38        Self {
39            code_hash: crate::molecule::Byte32::molecule_decode(&result[0]),
40            hash_type: crate::molecule::Byte::molecule_decode(&result[1]),
41            args: crate::molecule::Bytes::molecule_decode(&result[2]),
42        }
43    }
44
45    pub fn pack(&self) -> ckb_types::packed::Script {
46        ckb_types::packed::Script::from_slice(&self.molecule()).unwrap()
47    }
48
49    pub fn hash(&self) -> [u8; 32] {
50        ckb_hash::blake2b_256(self.molecule())
51    }
52}
53
54#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
55pub struct OutPoint {
56    pub tx_hash: [u8; 32],
57    pub index: u32,
58}
59
60impl OutPoint {
61    pub fn new(tx_hash: [u8; 32], index: u32) -> Self {
62        Self { tx_hash, index }
63    }
64
65    pub fn molecule(&self) -> Vec<u8> {
66        crate::molecule::encode_seq(vec![
67            crate::molecule::Byte32::new(self.tx_hash).molecule(),
68            crate::molecule::U32::new(self.index).molecule(),
69        ])
70    }
71
72    pub fn molecule_decode(data: &[u8]) -> Self {
73        let result = crate::molecule::decode_seq(
74            data,
75            &[crate::molecule::Byte32::molecule_size(), crate::molecule::U32::molecule_size()],
76        );
77        Self {
78            tx_hash: crate::molecule::Byte32::molecule_decode(&result[0]),
79            index: crate::molecule::U32::molecule_decode(&result[1]),
80        }
81    }
82
83    pub fn molecule_size() -> usize {
84        crate::molecule::Byte32::molecule_size() + crate::molecule::U32::molecule_size()
85    }
86
87    pub fn pack(&self) -> ckb_types::packed::OutPoint {
88        ckb_types::packed::OutPoint::from_slice(&self.molecule()).unwrap()
89    }
90}
91
92#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
93pub struct CellInput {
94    pub since: u64,
95    pub previous_output: OutPoint,
96}
97
98impl CellInput {
99    pub fn new(since: u64, previous_output: OutPoint) -> Self {
100        Self { since, previous_output }
101    }
102
103    pub fn molecule(&self) -> Vec<u8> {
104        crate::molecule::encode_seq(vec![
105            crate::molecule::U64::new(self.since).molecule(),
106            self.previous_output.molecule(),
107        ])
108    }
109
110    pub fn molecule_decode(data: &[u8]) -> Self {
111        let result =
112            crate::molecule::decode_seq(data, &[crate::molecule::U64::molecule_size(), OutPoint::molecule_size()]);
113        CellInput {
114            since: crate::molecule::U64::molecule_decode(&result[0]),
115            previous_output: OutPoint::molecule_decode(&result[1]),
116        }
117    }
118
119    pub fn molecule_size() -> usize {
120        crate::molecule::U64::molecule_size() + OutPoint::molecule_size()
121    }
122
123    pub fn pack(&self) -> ckb_types::packed::CellInput {
124        ckb_types::packed::CellInput::from_slice(&self.molecule()).unwrap()
125    }
126}
127
128#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
129pub struct CellOutput {
130    pub capacity: u64,
131    pub lock: Script,
132    pub kype: Option<Script>,
133}
134
135impl CellOutput {
136    pub fn new(capacity: u64, lock: Script, kype: Option<Script>) -> Self {
137        Self { capacity, lock, kype }
138    }
139
140    pub fn molecule(&self) -> Vec<u8> {
141        crate::molecule::encode_dynvec(vec![
142            crate::molecule::U64::new(self.capacity).molecule(),
143            self.lock.molecule(),
144            match &self.kype {
145                Some(kype) => kype.molecule(),
146                None => vec![],
147            },
148        ])
149    }
150
151    pub fn molecule_decode(data: &[u8]) -> Self {
152        let result = crate::molecule::decode_dynvec(data);
153        CellOutput {
154            capacity: crate::molecule::U64::molecule_decode(&result[0]),
155            lock: Script::molecule_decode(&result[1]),
156            kype: if !result[2].is_empty() { Some(Script::molecule_decode(&result[2])) } else { None },
157        }
158    }
159
160    pub fn pack(&self) -> ckb_types::packed::CellOutput {
161        ckb_types::packed::CellOutput::from_slice(&self.molecule()).unwrap()
162    }
163}
164
165#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
166pub struct CellDep {
167    pub out_point: OutPoint,
168    pub dep_type: u8,
169}
170
171impl CellDep {
172    pub fn new(out_point: OutPoint, dep_type: u8) -> Self {
173        Self { out_point, dep_type }
174    }
175
176    pub fn molecule(&self) -> Vec<u8> {
177        crate::molecule::encode_seq(vec![
178            self.out_point.molecule(),
179            crate::molecule::Byte::new(self.dep_type).molecule(),
180        ])
181    }
182
183    pub fn molecule_decode(data: &[u8]) -> Self {
184        let result =
185            crate::molecule::decode_seq(data, &[OutPoint::molecule_size(), crate::molecule::Byte::molecule_size()]);
186        CellDep {
187            out_point: OutPoint::molecule_decode(&result[0]),
188            dep_type: crate::molecule::Byte::molecule_decode(&result[1]),
189        }
190    }
191
192    pub fn molecule_size() -> usize {
193        OutPoint::molecule_size() + crate::molecule::Byte::molecule_size()
194    }
195
196    pub fn pack(&self) -> ckb_types::packed::CellDep {
197        ckb_types::packed::CellDep::from_slice(&self.molecule()).unwrap()
198    }
199}
200
201#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
202pub struct RawTransaction {
203    pub version: u32,
204    pub cell_deps: Vec<CellDep>,
205    pub header_deps: Vec<[u8; 32]>,
206    pub inputs: Vec<CellInput>,
207    pub outputs: Vec<CellOutput>,
208    pub outputs_data: Vec<Vec<u8>>,
209}
210
211impl RawTransaction {
212    pub fn new(
213        version: u32,
214        cell_deps: Vec<CellDep>,
215        header_deps: Vec<[u8; 32]>,
216        inputs: Vec<CellInput>,
217        outputs: Vec<CellOutput>,
218        outputs_data: Vec<Vec<u8>>,
219    ) -> Self {
220        Self { version, cell_deps, header_deps, inputs, outputs, outputs_data }
221    }
222
223    pub fn molecule(&self) -> Vec<u8> {
224        crate::molecule::encode_dynvec(vec![
225            crate::molecule::U32::new(self.version).molecule(),
226            crate::molecule::encode_fixvec(self.cell_deps.iter().map(|e| e.molecule()).collect()),
227            crate::molecule::encode_fixvec(
228                self.header_deps.iter().map(|e| crate::molecule::Byte32::new(*e).molecule()).collect(),
229            ),
230            crate::molecule::encode_fixvec(self.inputs.iter().map(|e| e.molecule()).collect()),
231            crate::molecule::encode_dynvec(self.outputs.iter().map(|e| e.molecule()).collect()),
232            crate::molecule::encode_dynvec(
233                self.outputs_data.iter().map(|e| crate::molecule::Bytes::new(e.clone()).molecule()).collect(),
234            ),
235        ])
236    }
237
238    pub fn molecule_decode(data: &[u8]) -> Self {
239        let result = crate::molecule::decode_dynvec(data);
240        Self {
241            version: crate::molecule::U32::molecule_decode(&result[0]),
242            cell_deps: crate::molecule::decode_fixvec(&result[1])
243                .iter()
244                .map(|e| CellDep::molecule_decode(&e))
245                .collect(),
246            header_deps: crate::molecule::decode_fixvec(&result[2])
247                .iter()
248                .map(|e| crate::molecule::Byte32::molecule_decode(&e))
249                .collect(),
250            inputs: crate::molecule::decode_fixvec(&result[3]).iter().map(|e| CellInput::molecule_decode(&e)).collect(),
251            outputs: crate::molecule::decode_dynvec(&result[4])
252                .iter()
253                .map(|e| CellOutput::molecule_decode(&e))
254                .collect(),
255            outputs_data: crate::molecule::decode_dynvec(&result[5])
256                .iter()
257                .map(|e| crate::molecule::Bytes::molecule_decode(&e))
258                .collect(),
259        }
260    }
261}
262
263#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
264pub struct Transaction {
265    pub raw: RawTransaction,
266    pub witnesses: Vec<Vec<u8>>,
267}
268
269impl Transaction {
270    pub fn new(raw: RawTransaction, witnesses: Vec<Vec<u8>>) -> Self {
271        Self { raw, witnesses }
272    }
273
274    pub fn molecule(&self) -> Vec<u8> {
275        crate::molecule::encode_dynvec(vec![
276            self.raw.molecule(),
277            crate::molecule::encode_dynvec(
278                self.witnesses.iter().map(|e| crate::molecule::Bytes::new(e.clone()).molecule()).collect(),
279            ),
280        ])
281    }
282
283    pub fn molecule_decode(data: &[u8]) -> Self {
284        let result = crate::molecule::decode_dynvec(data);
285        Transaction {
286            raw: RawTransaction::molecule_decode(&result[0]),
287            witnesses: crate::molecule::decode_dynvec(&result[1])
288                .iter()
289                .map(|e| crate::molecule::Bytes::molecule_decode(&e))
290                .collect(),
291        }
292    }
293
294    pub fn pack(&self) -> ckb_types::packed::Transaction {
295        ckb_types::packed::Transaction::from_slice(&self.molecule()).unwrap()
296    }
297}
298
299#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
300pub struct WitnessArgs {
301    pub lock: Option<Vec<u8>>,
302    pub input_type: Option<Vec<u8>>,
303    pub output_type: Option<Vec<u8>>,
304}
305
306impl WitnessArgs {
307    pub fn new(lock: Option<Vec<u8>>, input_type: Option<Vec<u8>>, output_type: Option<Vec<u8>>) -> Self {
308        Self { lock, input_type, output_type }
309    }
310
311    pub fn molecule(&self) -> Vec<u8> {
312        crate::molecule::encode_dynvec(vec![
313            match &self.lock {
314                Some(lock) => crate::molecule::Bytes::new(lock.clone()).molecule(),
315                None => vec![],
316            },
317            match &self.input_type {
318                Some(kype) => crate::molecule::Bytes::new(kype.clone()).molecule(),
319                None => vec![],
320            },
321            match &self.output_type {
322                Some(kype) => crate::molecule::Bytes::new(kype.clone()).molecule(),
323                None => vec![],
324            },
325        ])
326    }
327
328    pub fn molecule_decode(data: &[u8]) -> Self {
329        let result = crate::molecule::decode_dynvec(data);
330        Self {
331            lock: if !result[0].is_empty() { Some(crate::molecule::Bytes::molecule_decode(&result[0])) } else { None },
332            input_type: if !result[1].is_empty() {
333                Some(crate::molecule::Bytes::molecule_decode(&result[1]))
334            } else {
335                None
336            },
337            output_type: if !result[2].is_empty() {
338                Some(crate::molecule::Bytes::molecule_decode(&result[2]))
339            } else {
340                None
341            },
342        }
343    }
344
345    pub fn pack(&self) -> ckb_types::packed::WitnessArgs {
346        ckb_types::packed::WitnessArgs::from_slice(&self.molecule()).unwrap()
347    }
348}
349
350#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
351pub struct RawHeader {
352    pub version: u32,
353    pub compact_target: u32,
354    pub timestamp: u64,
355    pub number: u64,
356    pub epoch: u64,
357    pub parent_hash: [u8; 32],
358    pub transactions_root: [u8; 32],
359    pub proposals_hash: [u8; 32],
360    pub extra_hash: [u8; 32],
361    pub dao: [u8; 32],
362}
363
364impl RawHeader {
365    pub fn new(
366        version: u32,
367        compact_target: u32,
368        timestamp: u64,
369        number: u64,
370        epoch: u64,
371        parent_hash: [u8; 32],
372        transactions_root: [u8; 32],
373        proposals_hash: [u8; 32],
374        extra_hash: [u8; 32],
375        dao: [u8; 32],
376    ) -> Self {
377        Self {
378            version,
379            compact_target,
380            timestamp,
381            number,
382            epoch,
383            parent_hash,
384            transactions_root,
385            proposals_hash,
386            extra_hash,
387            dao,
388        }
389    }
390
391    pub fn molecule(&self) -> Vec<u8> {
392        return crate::molecule::encode_seq(vec![
393            crate::molecule::U32::new(self.version).molecule(),
394            crate::molecule::U32::new(self.compact_target).molecule(),
395            crate::molecule::U64::new(self.timestamp).molecule(),
396            crate::molecule::U64::new(self.number).molecule(),
397            crate::molecule::U64::new(self.epoch).molecule(),
398            crate::molecule::Byte32::new(self.parent_hash).molecule(),
399            crate::molecule::Byte32::new(self.transactions_root).molecule(),
400            crate::molecule::Byte32::new(self.proposals_hash).molecule(),
401            crate::molecule::Byte32::new(self.extra_hash).molecule(),
402            crate::molecule::Byte32::new(self.dao).molecule(),
403        ]);
404    }
405
406    pub fn molecule_decode(data: &[u8]) -> Self {
407        let result = crate::molecule::decode_seq(
408            data,
409            &[
410                crate::molecule::U32::molecule_size(),
411                crate::molecule::U32::molecule_size(),
412                crate::molecule::U64::molecule_size(),
413                crate::molecule::U64::molecule_size(),
414                crate::molecule::U64::molecule_size(),
415                crate::molecule::Byte32::molecule_size(),
416                crate::molecule::Byte32::molecule_size(),
417                crate::molecule::Byte32::molecule_size(),
418                crate::molecule::Byte32::molecule_size(),
419                crate::molecule::Byte32::molecule_size(),
420            ],
421        );
422        Self {
423            version: crate::molecule::U32::molecule_decode(&result[0]),
424            compact_target: crate::molecule::U32::molecule_decode(&result[1]),
425            timestamp: crate::molecule::U64::molecule_decode(&result[2]),
426            number: crate::molecule::U64::molecule_decode(&result[3]),
427            epoch: crate::molecule::U64::molecule_decode(&result[4]),
428            parent_hash: crate::molecule::Byte32::molecule_decode(&result[5]),
429            transactions_root: crate::molecule::Byte32::molecule_decode(&result[6]),
430            proposals_hash: crate::molecule::Byte32::molecule_decode(&result[7]),
431            extra_hash: crate::molecule::Byte32::molecule_decode(&result[8]),
432            dao: crate::molecule::Byte32::molecule_decode(&result[9]),
433        }
434    }
435
436    pub fn molecule_size() -> usize {
437        vec![
438            crate::molecule::U32::molecule_size(),
439            crate::molecule::U32::molecule_size(),
440            crate::molecule::U64::molecule_size(),
441            crate::molecule::U64::molecule_size(),
442            crate::molecule::U64::molecule_size(),
443            crate::molecule::Byte32::molecule_size(),
444            crate::molecule::Byte32::molecule_size(),
445            crate::molecule::Byte32::molecule_size(),
446            crate::molecule::Byte32::molecule_size(),
447            crate::molecule::Byte32::molecule_size(),
448        ]
449        .iter()
450        .sum()
451    }
452
453    pub fn pack(&self) -> ckb_types::packed::RawHeader {
454        ckb_types::packed::RawHeader::from_slice(&self.molecule()).unwrap()
455    }
456}
457
458#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
459pub struct Header {
460    pub raw: RawHeader,
461    pub nonce: u128,
462}
463
464impl Header {
465    pub fn new(raw: RawHeader, nonce: u128) -> Self {
466        Self { raw, nonce }
467    }
468
469    pub fn molecule(&self) -> Vec<u8> {
470        return crate::molecule::encode_seq(vec![
471            self.raw.molecule(),
472            crate::molecule::U128::new(self.nonce).molecule(),
473        ]);
474    }
475
476    pub fn molecule_decode(data: &[u8]) -> Self {
477        let result =
478            crate::molecule::decode_seq(data, &[RawHeader::molecule_size(), crate::molecule::U128::molecule_size()]);
479        Self { raw: RawHeader::molecule_decode(&result[0]), nonce: crate::molecule::U128::molecule_decode(&result[1]) }
480    }
481
482    pub fn molecule_size() -> usize {
483        RawHeader::molecule_size() + crate::molecule::U128::molecule_size()
484    }
485
486    pub fn pack(&self) -> ckb_types::packed::Header {
487        ckb_types::packed::Header::from_slice(&self.molecule()).unwrap()
488    }
489}
490
491#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
492pub struct UncleBlock {
493    pub header: Header,
494    pub proposals: Vec<Vec<u8>>,
495}
496
497impl UncleBlock {
498    pub fn new(header: Header, proposals: Vec<Vec<u8>>) -> Self {
499        Self { header, proposals }
500    }
501
502    pub fn molecule(&self) -> Vec<u8> {
503        return crate::molecule::encode_dynvec(vec![
504            self.header.molecule(),
505            crate::molecule::encode_fixvec(self.proposals.clone()),
506        ]);
507    }
508
509    pub fn molecule_decode(data: &[u8]) -> Self {
510        let result = crate::molecule::decode_dynvec(data);
511        Self { header: Header::molecule_decode(&result[0]), proposals: crate::molecule::decode_fixvec(&result[1]) }
512    }
513
514    pub fn pack(&self) -> ckb_types::packed::UncleBlock {
515        ckb_types::packed::UncleBlock::from_slice(&self.molecule()).unwrap()
516    }
517}
518
519#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
520pub struct Block {
521    pub header: Header,
522    pub uncles: Vec<UncleBlock>,
523    pub transactions: Vec<Transaction>,
524    pub proposals: Vec<Vec<u8>>,
525}
526
527impl Block {
528    pub fn new(
529        header: Header,
530        uncles: Vec<UncleBlock>,
531        transactions: Vec<Transaction>,
532        proposals: Vec<Vec<u8>>,
533    ) -> Self {
534        Self { header, uncles, transactions, proposals }
535    }
536
537    pub fn molecule(&self) -> Vec<u8> {
538        return crate::molecule::encode_dynvec(vec![
539            self.header.molecule(),
540            crate::molecule::encode_dynvec(self.uncles.iter().map(|e| e.molecule()).collect()),
541            crate::molecule::encode_dynvec(self.transactions.iter().map(|e| e.molecule()).collect()),
542            crate::molecule::encode_fixvec(self.proposals.clone()),
543        ]);
544    }
545
546    pub fn molecule_decode(data: &[u8]) -> Self {
547        let result = crate::molecule::decode_dynvec(data);
548        Self {
549            header: Header::molecule_decode(&result[0]),
550            uncles: crate::molecule::decode_dynvec(&result[1]).iter().map(|e| UncleBlock::molecule_decode(e)).collect(),
551            transactions: crate::molecule::decode_dynvec(&result[2])
552                .iter()
553                .map(|e| Transaction::molecule_decode(e))
554                .collect(),
555            proposals: crate::molecule::decode_fixvec(&result[3]),
556        }
557    }
558
559    pub fn pack(&self) -> ckb_types::packed::Block {
560        ckb_types::packed::Block::from_slice(&self.molecule()).unwrap()
561    }
562}
563
564#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
565pub struct BlockV1 {
566    pub header: Header,
567    pub uncles: Vec<UncleBlock>,
568    pub transactions: Vec<Transaction>,
569    pub proposals: Vec<Vec<u8>>,
570    pub extension: Vec<u8>,
571}
572
573impl BlockV1 {
574    pub fn new(
575        header: Header,
576        uncles: Vec<UncleBlock>,
577        transactions: Vec<Transaction>,
578        proposals: Vec<Vec<u8>>,
579        extension: Vec<u8>,
580    ) -> Self {
581        Self { header, uncles, transactions, proposals, extension }
582    }
583
584    pub fn molecule(&self) -> Vec<u8> {
585        return crate::molecule::encode_dynvec(vec![
586            self.header.molecule(),
587            crate::molecule::encode_dynvec(self.uncles.iter().map(|e| e.molecule()).collect()),
588            crate::molecule::encode_dynvec(self.transactions.iter().map(|e| e.molecule()).collect()),
589            crate::molecule::encode_fixvec(self.proposals.clone()),
590            crate::molecule::Bytes::new(self.extension.clone()).molecule(),
591        ]);
592    }
593
594    pub fn molecule_decode(data: &[u8]) -> Self {
595        let result = crate::molecule::decode_dynvec(data);
596        Self {
597            header: Header::molecule_decode(&result[0]),
598            uncles: crate::molecule::decode_dynvec(&result[1]).iter().map(|e| UncleBlock::molecule_decode(e)).collect(),
599            transactions: crate::molecule::decode_dynvec(&result[2])
600                .iter()
601                .map(|e| Transaction::molecule_decode(e))
602                .collect(),
603            proposals: crate::molecule::decode_fixvec(&result[3]),
604            extension: crate::molecule::Bytes::molecule_decode(&result[4]),
605        }
606    }
607
608    pub fn pack(&self) -> ckb_types::packed::BlockV1 {
609        ckb_types::packed::BlockV1::from_slice(&self.molecule()).unwrap()
610    }
611}
612
613#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
614pub struct CellbaseWitness {
615    pub lock: Script,
616    pub message: Vec<u8>,
617}
618
619impl CellbaseWitness {
620    pub fn new(lock: Script, message: Vec<u8>) -> Self {
621        Self { lock, message }
622    }
623
624    pub fn molecule(&self) -> Vec<u8> {
625        crate::molecule::encode_dynvec(vec![
626            self.lock.molecule(),
627            crate::molecule::Bytes::new(self.message.clone()).molecule(),
628        ])
629    }
630
631    pub fn molecule_decode(data: &[u8]) -> Self {
632        let result = crate::molecule::decode_dynvec(data);
633        Self { lock: Script::molecule_decode(&result[0]), message: crate::molecule::Bytes::molecule_decode(&result[1]) }
634    }
635
636    pub fn pack(&self) -> ckb_types::packed::CellbaseWitness {
637        ckb_types::packed::CellbaseWitness::from_slice(&self.molecule()).unwrap()
638    }
639}