ckb_sdk/transaction/handler/
typeid.rs1use ckb_hash::new_blake2b;
2use ckb_types::{
3 packed::{Bytes, CellInput},
4 prelude::*,
5};
6
7use crate::{
8 core::TransactionBuilder, tx_builder::TxBuilderError, NetworkInfo, ScriptGroup, ScriptId,
9};
10
11use super::{HandlerContext, ScriptHandler};
12
13pub struct TypeIdHandler;
15
16pub struct TypeIdContext;
17
18impl HandlerContext for TypeIdContext {}
19#[cfg_attr(target_arch="wasm32", async_trait::async_trait(?Send))]
20#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
21impl ScriptHandler for TypeIdHandler {
22 fn build_transaction(
23 &self,
24 tx_builder: &mut TransactionBuilder,
25 script_group: &mut ScriptGroup,
26 context: &dyn HandlerContext,
27 ) -> Result<bool, TxBuilderError> {
28 if context.as_any().is::<TypeIdContext>()
29 && ScriptId::from(&script_group.script).is_type_id()
30 && script_group.input_indices.is_empty()
31 && script_group.output_indices.len() == 1
32 {
33 let input = tx_builder.get_inputs().first().unwrap();
34 let index = *script_group.output_indices.last().unwrap();
35 let args: Bytes = calculate_type_id(input, index as u64).to_vec().pack();
36 let output = tx_builder.get_outputs().get(index).unwrap().clone();
37 let output_type_script = output
38 .type_()
39 .to_opt()
40 .unwrap()
41 .as_builder()
42 .args(args)
43 .build();
44 let updated_output = output
45 .as_builder()
46 .type_(Some(output_type_script.clone()).pack())
47 .build();
48 tx_builder.set_output(index, updated_output);
49 script_group.script = output_type_script;
50 return Ok(true);
51 }
52 Ok(false)
53 }
54 #[cfg(not(target_arch = "wasm32"))]
55 fn init(&mut self, _network: &NetworkInfo) -> Result<(), TxBuilderError> {
56 Ok(())
57 }
58 async fn init_async(&mut self, _network: &NetworkInfo) -> Result<(), TxBuilderError> {
59 Ok(())
60 }
61}
62
63fn calculate_type_id(first_cell_input: &CellInput, output_index: u64) -> [u8; 32] {
64 let mut blake2b = new_blake2b();
65 blake2b.update(first_cell_input.as_slice());
66 blake2b.update(&output_index.to_le_bytes());
67 let mut ret = [0u8; 32];
68 blake2b.finalize(&mut ret);
69 ret
70}