Skip to content

Commit 62b34c4

Browse files
committed
Upgrade multisig
Signed-off-by: Eval EXEC <[email protected]>
1 parent c8877c2 commit 62b34c4

File tree

12 files changed

+148
-95
lines changed

12 files changed

+148
-95
lines changed

examples/send_ckb_multisig_example.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,16 @@ fn main() -> Result<(), Box<dyn StdErr>> {
2525
2,
2626
)?;
2727
let sender = multisig_config.to_address(network_info.network_type, None);
28+
println!("sender: {}", sender);
2829
let receiver = Address::from_str("ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq2qf8keemy2p5uu0g0gn8cd4ju23s5269qk8rg4r")?;
2930

3031
let iterator = InputIterator::new_with_address(&[sender], &network_info);
3132
let mut builder = SimpleTransactionBuilder::new(configuration, iterator);
32-
builder.add_output(&receiver, Capacity::shannons(510_0000_0000u64));
33+
builder.add_output(&receiver, Capacity::shannons(6100000000u64));
3334

3435
let mut tx_with_groups =
3536
builder.build(&HandlerContexts::new_multisig(multisig_config.clone()))?;
37+
println!("tx_with_groups:{:?}", &tx_with_groups);
3638

3739
let json_tx = ckb_jsonrpc_types::TransactionView::from(tx_with_groups.get_tx_view().clone());
3840
println!("tx: {}", serde_json::to_string_pretty(&json_tx).unwrap());

examples/transfer_from_multisig.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::path::PathBuf;
66
use ckb_hash::blake2b_256;
77
use ckb_jsonrpc_types as json_types;
88
use ckb_sdk::{
9-
constants::{MULTISIG_TYPE_HASH, SIGHASH_TYPE_HASH},
9+
constants::{MULTISIG_SCRIPT, SIGHASH_TYPE_HASH},
1010
rpc::CkbRpcClient,
1111
traits::{
1212
DefaultCellCollector, DefaultCellDepResolver, DefaultHeaderDepResolver,
@@ -222,8 +222,8 @@ fn build_transfer_tx(
222222
) -> Result<TransactionView, Box<dyn StdErr>> {
223223
// Build CapacityBalancer
224224
let sender = Script::new_builder()
225-
.code_hash(MULTISIG_TYPE_HASH.pack())
226-
.hash_type(ScriptHashType::Type.into())
225+
.code_hash(MULTISIG_SCRIPT.code_hash.pack())
226+
.hash_type(MULTISIG_SCRIPT.hash_type.into())
227227
.args(Bytes::from(multisig_config.hash160().as_bytes().to_vec()).pack())
228228
.build();
229229
let sender_addr = Address::new(args.receiver.network(), sender.clone().into(), true);
@@ -289,7 +289,7 @@ fn build_multisig_unlockers(
289289
let signer = SecpCkbRawKeySigner::new_with_secret_keys(keys);
290290
let multisig_signer = SecpMultisigScriptSigner::new(Box::new(signer), config);
291291
let multisig_unlocker = SecpMultisigUnlocker::new(multisig_signer);
292-
let multisig_script_id = ScriptId::new_type(MULTISIG_TYPE_HASH.clone());
292+
let multisig_script_id = MULTISIG_SCRIPT;
293293
let mut unlockers = HashMap::default();
294294
unlockers.insert(
295295
multisig_script_id,

src/constants.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use ckb_types::{core::EpochNumberWithFraction, h256, H256};
22

3+
use crate::ScriptId;
4+
35
pub const PREFIX_MAINNET: &str = "ckb";
46
pub const PREFIX_TESTNET: &str = "ckt";
57

@@ -35,8 +37,35 @@ pub const TYPE_ID_CODE_HASH: H256 = h256!("0x545950455f4944");
3537

3638
pub const SIGHASH_TYPE_HASH: H256 =
3739
h256!("0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8");
38-
pub const MULTISIG_TYPE_HASH: H256 =
39-
h256!("0x5c5069eb0857efc65e1bca0c07df34c31663b3622fd3876c876320fc9634e2a8");
40+
41+
pub const GENESIS_BLOCK_HASH_MAINNET: H256 =
42+
h256!("0x92b197aa1fba0f63633922c61c92375c9c074a93e85963554f5499fe1450d0e5");
43+
44+
pub const GENESIS_BLOCK_HASH_TESTNET: H256 =
45+
h256!("0x10639e0895502b5688a6be8cf69460d76541bfa4821629d86d62ba0aae3f9606");
46+
47+
/// Depreacted MultiSig: HashType: type
48+
pub const MULTISIG_SCRIPT_DEPRECATED: ScriptId = ScriptId::new_type(h256!(
49+
"0x5c5069eb0857efc65e1bca0c07df34c31663b3622fd3876c876320fc9634e2a8"
50+
));
51+
52+
/// MultiSig: HashType: data1,
53+
pub const MULTISIG_SCRIPT: ScriptId = ScriptId::new_data1(h256!(
54+
"0x36c971b8d41fbd94aabca77dc75e826729ac98447b46f91e00796155dddb0d29"
55+
));
56+
57+
/// https://github.com/nervosnetwork/ckb-system-scripts/pull/99#issuecomment-2814285588
58+
pub const MULTISIG_DEP_GROUP_MAINNET: (H256, u32) = (
59+
h256!("0x6888aa39ab30c570c2c30d9d5684d3769bf77265a7973211a3c087fe8efbf738"),
60+
0,
61+
);
62+
63+
/// https://github.com/nervosnetwork/ckb-system-scripts/pull/99#issuecomment-2757175017
64+
pub const MULTISIG_DEP_GROUP_TESTNET: (H256, u32) = (
65+
h256!("0x2eefdeb21f3a3edf697c28a52601b4419806ed60bb427420455cc29a090b26d5"),
66+
0,
67+
);
68+
4069
pub const DAO_TYPE_HASH: H256 =
4170
h256!("0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e");
4271

src/test_util.rs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,9 @@ use ckb_types::core::{HeaderBuilder, TransactionBuilder};
99
use rand::{thread_rng, Rng};
1010
use thiserror::Error;
1111

12+
use crate::constants::MULTISIG_SCRIPT;
1213
use crate::{
13-
constants::{
14-
MULTISIG_GROUP_OUTPUT_LOC, MULTISIG_TYPE_HASH, ONE_CKB, SIGHASH_GROUP_OUTPUT_LOC,
15-
SIGHASH_TYPE_HASH,
16-
},
14+
constants::{MULTISIG_GROUP_OUTPUT_LOC, ONE_CKB, SIGHASH_GROUP_OUTPUT_LOC, SIGHASH_TYPE_HASH},
1715
traits::{
1816
CellCollector, CellCollectorError, CellDepResolver, CellQueryOptions,
1917
DefaultCellDepResolver, HeaderDepResolver, LiveCell, TransactionDependencyError,
@@ -99,18 +97,15 @@ impl Context {
9997
let (output, data) = tx.output_with_data(output_idx).expect("get output+data");
10098
ctx.add_cell_dep(cell_dep, output, data, Some(block_hash.clone()));
10199
}
102-
for (code_hash, cell_dep) in [
103-
(
104-
SIGHASH_TYPE_HASH,
105-
cell_dep_resolver.sighash_dep().unwrap().0.clone(),
106-
),
107-
(
108-
MULTISIG_TYPE_HASH,
109-
cell_dep_resolver.multisig_dep().unwrap().0.clone(),
110-
),
111-
] {
112-
ctx.add_cell_dep_map(ScriptId::new_type(code_hash), cell_dep);
113-
}
100+
ctx.add_cell_dep_map(
101+
ScriptId::new_type(SIGHASH_TYPE_HASH),
102+
cell_dep_resolver.sighash_dep().unwrap().0.clone(),
103+
);
104+
105+
ctx.add_cell_dep_map(
106+
MULTISIG_SCRIPT,
107+
cell_dep_resolver.sighash_dep().unwrap().0.clone(),
108+
);
114109
for tx in block.transactions().iter() {
115110
for (idx, (output, data)) in tx
116111
.outputs()

src/tests/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use ckb_types::{
1313
};
1414

1515
use crate::constants::{
16-
CHEQUE_CELL_SINCE, DAO_TYPE_HASH, MULTISIG_TYPE_HASH, ONE_CKB, SIGHASH_TYPE_HASH,
16+
CHEQUE_CELL_SINCE, DAO_TYPE_HASH, MULTISIG_SCRIPT, ONE_CKB, SIGHASH_TYPE_HASH,
1717
};
1818
use crate::traits::SecpCkbRawKeySigner;
1919
use crate::tx_builder::{
@@ -73,8 +73,8 @@ fn build_sighash_script(args: H160) -> Script {
7373

7474
fn build_multisig_script(cfg: &MultisigConfig) -> Script {
7575
Script::new_builder()
76-
.code_hash(MULTISIG_TYPE_HASH.pack())
77-
.hash_type(ScriptHashType::Type.into())
76+
.code_hash(MULTISIG_SCRIPT.code_hash.pack())
77+
.hash_type(MULTISIG_SCRIPT.hash_type.into())
7878
.args(Bytes::from(cfg.hash160().0.to_vec()).pack())
7979
.build()
8080
}
@@ -105,7 +105,7 @@ fn build_multisig_unlockers(
105105
) -> HashMap<ScriptId, Box<dyn ScriptUnlocker>> {
106106
let signer = SecpCkbRawKeySigner::new_with_secret_keys(vec![key]);
107107
let multisig_unlocker = SecpMultisigUnlocker::from((Box::new(signer) as Box<_>, config));
108-
let multisig_script_id = ScriptId::new_type(MULTISIG_TYPE_HASH.clone());
108+
let multisig_script_id = MULTISIG_SCRIPT;
109109
let mut unlockers = HashMap::default();
110110
unlockers.insert(
111111
multisig_script_id,

src/traits/default_impls.rs

Lines changed: 63 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,32 @@ use super::{
2323
OffchainTransactionDependencyProvider,
2424
};
2525
use crate::rpc::ckb_indexer::{Order, SearchKey, Tip};
26-
use crate::rpc::{CkbRpcAsyncClient, IndexerRpcAsyncClient};
27-
use crate::traits::{
28-
CellCollector, CellCollectorError, CellDepResolver, CellQueryOptions, HeaderDepResolver,
29-
LiveCell, QueryOrder, Signer, SignerError, TransactionDependencyError,
30-
TransactionDependencyProvider,
31-
};
32-
use crate::types::ScriptId;
3326
use crate::util::{get_max_mature_number_async, serialize_signature, zeroize_privkey};
3427
use crate::SECP256K1;
28+
use crate::{
29+
constants::GENESIS_BLOCK_HASH_MAINNET,
30+
rpc::{CkbRpcAsyncClient, IndexerRpcAsyncClient},
31+
};
32+
use crate::{constants::MULTISIG_SCRIPT, types::ScriptId};
3533
use crate::{
3634
constants::{
37-
DAO_OUTPUT_LOC, DAO_TYPE_HASH, MULTISIG_GROUP_OUTPUT_LOC, MULTISIG_OUTPUT_LOC,
38-
MULTISIG_TYPE_HASH, SIGHASH_GROUP_OUTPUT_LOC, SIGHASH_OUTPUT_LOC, SIGHASH_TYPE_HASH,
35+
DAO_OUTPUT_LOC, DAO_TYPE_HASH, SIGHASH_GROUP_OUTPUT_LOC, SIGHASH_OUTPUT_LOC,
36+
SIGHASH_TYPE_HASH,
3937
},
4038
util::keccak160,
4139
};
40+
use crate::{
41+
constants::{
42+
GENESIS_BLOCK_HASH_TESTNET, MULTISIG_DEP_GROUP_MAINNET, MULTISIG_DEP_GROUP_TESTNET,
43+
},
44+
traits::{
45+
CellCollector, CellCollectorError, CellDepResolver, CellQueryOptions, HeaderDepResolver,
46+
LiveCell, QueryOrder, Signer, SignerError, TransactionDependencyError,
47+
TransactionDependencyProvider,
48+
},
49+
};
4250
use ckb_resource::{
43-
CODE_HASH_DAO, CODE_HASH_SECP256K1_BLAKE160_MULTISIG_ALL,
51+
CODE_HASH_DAO, // CODE_HASH_SECP256K1_BLAKE160_MULTISIG_ALL,
4452
CODE_HASH_SECP256K1_BLAKE160_SIGHASH_ALL,
4553
};
4654

@@ -69,7 +77,7 @@ impl DefaultCellDepResolver {
6977
return Err(ParseGenesisInfoError::InvalidBlockNumber(header.number()));
7078
}
7179
let mut sighash_type_hash = None;
72-
let mut multisig_type_hash = None;
80+
// let mut multisig_type_hash = None;
7381
let mut dao_type_hash = None;
7482
let out_points = genesis_block
7583
.transactions()
@@ -95,20 +103,20 @@ impl DefaultCellDepResolver {
95103
);
96104
}
97105
}
98-
if tx_index == MULTISIG_OUTPUT_LOC.0 && index == MULTISIG_OUTPUT_LOC.1 {
99-
multisig_type_hash = output
100-
.type_()
101-
.to_opt()
102-
.map(|script| script.calc_script_hash());
103-
let data_hash = CellOutput::calc_data_hash(&data.raw_data());
104-
if data_hash != CODE_HASH_SECP256K1_BLAKE160_MULTISIG_ALL.pack() {
105-
log::error!(
106-
"System multisig script code hash error! found: {}, expected: {}",
107-
data_hash,
108-
CODE_HASH_SECP256K1_BLAKE160_MULTISIG_ALL,
109-
);
110-
}
111-
}
106+
// if tx_index == MULTISIG_OUTPUT_LOC.0 && index == MULTISIG_OUTPUT_LOC.1 {
107+
// multisig_type_hash = output
108+
// .type_()
109+
// .to_opt()
110+
// .map(|script| script.calc_script_hash());
111+
// let data_hash = CellOutput::calc_data_hash(&data.raw_data());
112+
// if data_hash != CODE_HASH_SECP256K1_BLAKE160_MULTISIG_ALL.pack() {
113+
// log::error!(
114+
// "System multisig script code hash error! found: {}, expected: {}",
115+
// data_hash,
116+
// CODE_HASH_SECP256K1_BLAKE160_MULTISIG_ALL,
117+
// );
118+
// }
119+
// }
112120
if tx_index == DAO_OUTPUT_LOC.0 && index == DAO_OUTPUT_LOC.1 {
113121
dao_type_hash = output
114122
.type_()
@@ -132,9 +140,6 @@ impl DefaultCellDepResolver {
132140
let sighash_type_hash = sighash_type_hash
133141
.ok_or_else(|| "No type hash(sighash) found in txs[0][1]".to_owned())
134142
.map_err(ParseGenesisInfoError::TypeHashNotFound)?;
135-
let multisig_type_hash = multisig_type_hash
136-
.ok_or_else(|| "No type hash(multisig) found in txs[0][4]".to_owned())
137-
.map_err(ParseGenesisInfoError::TypeHashNotFound)?;
138143
let dao_type_hash = dao_type_hash
139144
.ok_or_else(|| "No type hash(dao) found in txs[0][2]".to_owned())
140145
.map_err(ParseGenesisInfoError::TypeHashNotFound)?;
@@ -143,10 +148,34 @@ impl DefaultCellDepResolver {
143148
.out_point(out_points[SIGHASH_GROUP_OUTPUT_LOC.0][SIGHASH_GROUP_OUTPUT_LOC.1].clone())
144149
.dep_type(DepType::DepGroup.into())
145150
.build();
146-
let multisig_dep = CellDep::new_builder()
147-
.out_point(out_points[MULTISIG_GROUP_OUTPUT_LOC.0][MULTISIG_GROUP_OUTPUT_LOC.1].clone())
148-
.dep_type(DepType::DepGroup.into())
149-
.build();
151+
152+
let multisig_dep = if genesis_block.hash().eq(&GENESIS_BLOCK_HASH_MAINNET.pack()) {
153+
// mainnet
154+
CellDep::new_builder()
155+
.out_point(
156+
ckb_types::packed::OutPoint::new_builder()
157+
.tx_hash(MULTISIG_DEP_GROUP_MAINNET.0.pack())
158+
.index(MULTISIG_DEP_GROUP_MAINNET.1.pack())
159+
.build(),
160+
)
161+
.dep_type(DepType::DepGroup.into())
162+
.build()
163+
} else if genesis_block.hash().eq(&GENESIS_BLOCK_HASH_TESTNET.pack()) {
164+
// testnet
165+
CellDep::new_builder()
166+
.out_point(
167+
ckb_types::packed::OutPoint::new_builder()
168+
.tx_hash(MULTISIG_DEP_GROUP_TESTNET.0.pack())
169+
.index(MULTISIG_DEP_GROUP_TESTNET.1.pack())
170+
.build(),
171+
)
172+
.dep_type(DepType::DepGroup.into())
173+
.build()
174+
} else {
175+
//dev net
176+
unimplemented!()
177+
};
178+
150179
let dao_dep = CellDep::new_builder()
151180
.out_point(out_points[DAO_OUTPUT_LOC.0][DAO_OUTPUT_LOC.1].clone())
152181
.build();
@@ -157,7 +186,7 @@ impl DefaultCellDepResolver {
157186
(sighash_dep, "Secp256k1 blake160 sighash all".to_string()),
158187
);
159188
items.insert(
160-
ScriptId::new_type(multisig_type_hash.unpack()),
189+
MULTISIG_SCRIPT,
161190
(multisig_dep, "Secp256k1 blake160 multisig all".to_string()),
162191
);
163192
items.insert(
@@ -188,7 +217,7 @@ impl DefaultCellDepResolver {
188217
self.get(&ScriptId::new_type(SIGHASH_TYPE_HASH))
189218
}
190219
pub fn multisig_dep(&self) -> Option<&(CellDep, String)> {
191-
self.get(&ScriptId::new_type(MULTISIG_TYPE_HASH))
220+
self.get(&MULTISIG_SCRIPT)
192221
}
193222
pub fn dao_dep(&self) -> Option<&(CellDep, String)> {
194223
self.get(&ScriptId::new_type(DAO_TYPE_HASH))

src/transaction/handler/multisig.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ use ckb_types::{
66
};
77

88
use crate::{
9-
constants, core::TransactionBuilder, tx_builder::TxBuilderError, unlock::MultisigConfig,
9+
constants::{self, MULTISIG_DEP_GROUP_MAINNET, MULTISIG_DEP_GROUP_TESTNET},
10+
core::TransactionBuilder,
11+
tx_builder::TxBuilderError,
12+
unlock::MultisigConfig,
1013
NetworkInfo, NetworkType, ScriptGroup,
1114
};
1215

@@ -30,7 +33,8 @@ impl Secp256k1Blake160MultisigAllScriptContext {
3033

3134
impl Secp256k1Blake160MultisigAllScriptHandler {
3235
pub fn is_match(&self, script: &Script) -> bool {
33-
script.code_hash() == constants::MULTISIG_TYPE_HASH.pack()
36+
script.code_hash() == constants::MULTISIG_SCRIPT.code_hash.pack()
37+
&& script.hash_type() == constants::MULTISIG_SCRIPT.hash_type.into()
3438
}
3539
pub fn new_with_network(network: &NetworkInfo) -> Result<Self, TxBuilderError> {
3640
let mut ret = Self { cell_deps: vec![] };
@@ -69,19 +73,13 @@ impl ScriptHandler for Secp256k1Blake160MultisigAllScriptHandler {
6973
fn init(&mut self, network: &NetworkInfo) -> Result<(), TxBuilderError> {
7074
let out_point = if network.network_type == NetworkType::Mainnet {
7175
OutPoint::new_builder()
72-
.tx_hash(
73-
h256!("0x71a7ba8fc96349fea0ed3a5c47992e3b4084b031a42264a018e0072e8172e46c")
74-
.pack(),
75-
)
76-
.index(1u32.pack())
76+
.tx_hash(MULTISIG_DEP_GROUP_MAINNET.0.pack())
77+
.index(MULTISIG_DEP_GROUP_MAINNET.1.pack())
7778
.build()
7879
} else if network.network_type == NetworkType::Testnet {
7980
OutPoint::new_builder()
80-
.tx_hash(
81-
h256!("0xf8de3bb47d055cdf460d93a2a6e1b05f7432f9777c8c474abf4eec1d4aee5d37")
82-
.pack(),
83-
)
84-
.index(1u32.pack())
81+
.tx_hash(MULTISIG_DEP_GROUP_TESTNET.0.pack())
82+
.index(MULTISIG_DEP_GROUP_TESTNET.1.pack())
8583
.build()
8684
} else if network.network_type == NetworkType::Preview {
8785
OutPoint::new_builder()

src/transaction/signer/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use ckb_types::{core, H256};
22
use std::collections::HashMap;
33

44
use crate::{
5-
constants,
5+
constants::{self, MULTISIG_SCRIPT},
66
unlock::{MultisigConfig, UnlockError},
77
NetworkInfo, ScriptGroup, ScriptId, TransactionWithScriptGroups,
88
};
@@ -89,7 +89,7 @@ impl TransactionSigner {
8989
);
9090

9191
unlockers.insert(
92-
ScriptId::new_type(constants::MULTISIG_TYPE_HASH.clone()),
92+
MULTISIG_SCRIPT,
9393
Box::new(multisig::Secp256k1Blake160MultisigAllSigner {}) as Box<_>,
9494
);
9595

0 commit comments

Comments
 (0)