ckb_sdk/transaction/handler/
sighash.rs1use ckb_types::{
2 core::DepType,
3 h256,
4 packed::{CellDep, OutPoint, Script, WitnessArgs},
5 prelude::{Builder, Entity, Pack},
6};
7
8use crate::{
9 constants, core::TransactionBuilder, tx_builder::TxBuilderError, unlock::UnlockError,
10 NetworkInfo, NetworkType, ScriptGroup,
11};
12
13use super::{HandlerContext, ScriptHandler};
14
15pub struct Secp256k1Blake160SighashAllScriptHandler {
16 cell_deps: Vec<CellDep>,
17}
18
19pub struct Secp256k1Blake160SighashAllScriptContext;
20
21impl HandlerContext for Secp256k1Blake160SighashAllScriptContext {}
22
23impl Secp256k1Blake160SighashAllScriptHandler {
24 pub fn is_match(&self, script: &Script) -> bool {
25 script.code_hash() == constants::SIGHASH_TYPE_HASH.pack()
26 }
27 #[cfg(not(target_arch = "wasm32"))]
28 pub fn new_with_network(network: &NetworkInfo) -> Result<Self, TxBuilderError> {
29 let mut ret = Self { cell_deps: vec![] };
30 ret.init(network)?;
31 Ok(ret)
32 }
33 pub async fn new_with_network_async(network: &NetworkInfo) -> Result<Self, TxBuilderError> {
34 let mut ret = Self { cell_deps: vec![] };
35 ret.init_async(network).await?;
36 Ok(ret)
37 }
38
39 pub fn new_with_customize(cell_deps: Vec<CellDep>) -> Self {
40 Self { cell_deps }
41 }
42}
43#[cfg_attr(target_arch="wasm32", async_trait::async_trait(?Send))]
44#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
45impl ScriptHandler for Secp256k1Blake160SighashAllScriptHandler {
46 fn build_transaction(
47 &self,
48 tx_builder: &mut TransactionBuilder,
49 script_group: &mut ScriptGroup,
50 context: &dyn HandlerContext,
51 ) -> Result<bool, TxBuilderError> {
52 if !self.is_match(&script_group.script) {
53 return Ok(false);
54 }
55 if let Some(_args) = context
56 .as_any()
57 .downcast_ref::<Secp256k1Blake160SighashAllScriptContext>()
58 {
59 tx_builder.dedup_cell_deps(self.cell_deps.clone());
60 let index = *script_group.input_indices.first().unwrap();
61 let witness = if let Some(witness) = tx_builder.get_witnesses().get(index) {
62 let witness_data = witness.raw_data();
63 if witness_data.is_empty() {
64 WitnessArgs::new_builder()
65 } else {
66 WitnessArgs::from_slice(witness_data.as_ref())
67 .map_err(|_| UnlockError::InvalidWitnessArgs(index))?
68 .as_builder()
69 }
70 } else {
71 WitnessArgs::new_builder()
72 }
73 .lock(Some(bytes::Bytes::from(vec![0u8; 65])).pack())
74 .build();
75 tx_builder.set_witness(index, witness.as_bytes().pack());
76 Ok(true)
77 } else {
78 Ok(false)
79 }
80 }
81
82 #[cfg(not(target_arch = "wasm32"))]
83 fn init(&mut self, network: &NetworkInfo) -> Result<(), TxBuilderError> {
84 let out_point = if network.network_type == NetworkType::Mainnet {
85 OutPoint::new_builder()
86 .tx_hash(
87 h256!("0x71a7ba8fc96349fea0ed3a5c47992e3b4084b031a42264a018e0072e8172e46c")
88 .pack(),
89 )
90 .index(0u32)
91 .build()
92 } else if network.network_type == NetworkType::Testnet {
93 OutPoint::new_builder()
94 .tx_hash(
95 h256!("0xf8de3bb47d055cdf460d93a2a6e1b05f7432f9777c8c474abf4eec1d4aee5d37")
96 .pack(),
97 )
98 .index(0u32)
99 .build()
100 } else if network.network_type == NetworkType::Preview {
101 OutPoint::new_builder()
102 .tx_hash(
103 h256!("0x0fab65924f2784f17ad7f86d6aef4b04ca1ca237102a68961594acebc5c77816")
104 .pack(),
105 )
106 .index(0u32)
107 .build()
108 } else {
109 return Err(TxBuilderError::UnsupportedNetworkType(network.network_type));
110 };
111
112 let cell_dep = CellDep::new_builder()
113 .out_point(out_point)
114 .dep_type(DepType::DepGroup)
115 .build();
116 self.cell_deps.push(cell_dep);
117 Ok(())
118 }
119 async fn init_async(&mut self, network: &NetworkInfo) -> Result<(), TxBuilderError> {
120 let out_point = if network.network_type == NetworkType::Mainnet {
121 OutPoint::new_builder()
122 .tx_hash(
123 h256!("0x71a7ba8fc96349fea0ed3a5c47992e3b4084b031a42264a018e0072e8172e46c")
124 .pack(),
125 )
126 .index(0u32)
127 .build()
128 } else if network.network_type == NetworkType::Testnet {
129 OutPoint::new_builder()
130 .tx_hash(
131 h256!("0xf8de3bb47d055cdf460d93a2a6e1b05f7432f9777c8c474abf4eec1d4aee5d37")
132 .pack(),
133 )
134 .index(0u32)
135 .build()
136 } else if network.network_type == NetworkType::Preview {
137 OutPoint::new_builder()
138 .tx_hash(
139 h256!("0x0fab65924f2784f17ad7f86d6aef4b04ca1ca237102a68961594acebc5c77816")
140 .pack(),
141 )
142 .index(0u32)
143 .build()
144 } else {
145 return Err(TxBuilderError::UnsupportedNetworkType(network.network_type));
146 };
147
148 let cell_dep = CellDep::new_builder()
149 .out_point(out_point)
150 .dep_type(DepType::DepGroup)
151 .build();
152 self.cell_deps.push(cell_dep);
153 Ok(())
154 }
155}