Skip to content

Commit 1346b72

Browse files
committed
update
Signed-off-by: Eval EXEC <[email protected]>
1 parent 64047ae commit 1346b72

File tree

9 files changed

+204
-85
lines changed

9 files changed

+204
-85
lines changed

Cargo.lock

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/subcommands/deploy/tx_builder.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::collections::HashMap;
22

33
use anyhow::{anyhow, Result};
44
use ckb_sdk::{
5-
constants::{MULTISIG_SCRIPT, SIGHASH_TYPE_HASH},
5+
constants::{MultisigScript, SIGHASH_TYPE_HASH},
66
traits::{
77
CellCollector, CellQueryOptions, DefaultCellCollector, DefaultHeaderDepResolver,
88
DefaultTransactionDependencyProvider, OffchainTransactionDependencyProvider, Signer,
@@ -79,10 +79,7 @@ pub fn build_tx<T: ChangeInfo>(
7979
.iter()
8080
.filter_map(|info| info.build_cell_output(lock_script, first_cell_input))
8181
.unzip();
82-
let mut cell_deps = vec![genesis_info.sighash_dep()];
83-
if multisig_config.is_some() {
84-
cell_deps.push(genesis_info.multisig_dep());
85-
}
82+
8683
let mut unlockers = HashMap::new();
8784
let signer = DummySigner {
8885
args: vec![from_address.payload().args()],
@@ -93,10 +90,22 @@ pub fn build_tx<T: ChangeInfo>(
9390
sighash_script_id,
9491
Box::new(sighash_unlocker) as Box<dyn ScriptUnlocker>,
9592
);
93+
94+
let mut cell_deps = vec![genesis_info.sighash_dep()];
9695
if let Some(cfg) = multisig_config {
96+
let multisig_script =
97+
MultisigScript::try_from(cfg.lock_code_hash()).unwrap_or_else(|_err| {
98+
panic!(
99+
"Failed to get multisig script from {}",
100+
cfg.lock_code_hash(),
101+
)
102+
});
103+
104+
cell_deps.push(genesis_info.multisig_dep(multisig_script));
105+
97106
let multisig_signer = SecpMultisigScriptSigner::new(Box::new(signer), cfg.clone());
98107
let multisig_unlocker = SecpMultisigUnlocker::new(multisig_signer);
99-
let multisig_script_id = MULTISIG_SCRIPT;
108+
let multisig_script_id = multisig_script.script_id();
100109
unlockers.insert(
101110
multisig_script_id,
102111
Box::new(multisig_unlocker) as Box<dyn ScriptUnlocker>,

src/subcommands/tx.rs

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::str::FromStr;
77

88
use ckb_jsonrpc_types as json_types;
99
use ckb_jsonrpc_types::JsonBytes;
10-
use ckb_sdk::constants::{MultisigScript, MULTISIG_SCRIPT};
10+
use ckb_sdk::constants::MultisigScript;
1111
use ckb_sdk::{
1212
constants::SECP_SIGNATURE_SIZE, unlock::MultisigConfig, Address, AddressPayload, HumanCapacity,
1313
NetworkType,
@@ -74,8 +74,8 @@ impl<'a> TxSubCommand<'a> {
7474
.required(true)
7575
.validator(|input| AddressParser::new_sighash().validate(input))
7676
.about("Normal sighash address");
77-
let arg_multisig_lock_hash = Arg::with_name("lock-code-hash")
78-
.long("lock-code-hash")
77+
let arg_multisig_lock_hash = Arg::with_name("multisig-code-hash")
78+
.long("multisig-code-hash")
7979
.takes_value(true)
8080
.multiple(false)
8181
.required(false)
@@ -157,6 +157,7 @@ impl<'a> TxSubCommand<'a> {
157157
.arg(arg_skip_check.clone()),
158158
App::new("add-output")
159159
.about("Add cell output")
160+
.arg(arg_multisig_lock_hash.clone())
160161
.arg(
161162
Arg::with_name("to-sighash-address")
162163
.long("to-sighash-address")
@@ -173,14 +174,26 @@ impl<'a> TxSubCommand<'a> {
173174
.long("to-short-multisig-address")
174175
.conflicts_with("to-long-multisig-address")
175176
.takes_value(true)
176-
.validator(|input| AddressParser::new_multisig().validate(input))
177-
.about("To short multisig address"),
177+
.requires("multisig-code-hash")
178+
.validator(|input| {
179+
AddressParser::new_multisig(MultisigScript::Legacy)
180+
.validate(input)
181+
.or(AddressParser::new_multisig(MultisigScript::V1)
182+
.validate(input))
183+
})
184+
.about("To short multisig address(encode with lagacy multisig script)"),
178185
)
179186
.arg(
180187
Arg::with_name("to-long-multisig-address")
181188
.long("to-long-multisig-address")
182189
.takes_value(true)
183-
.validator(|input| AddressParser::new_multisig().validate(input))
190+
.requires("multisig-code-hash")
191+
.validator(|input| {
192+
AddressParser::new_multisig(MultisigScript::Legacy)
193+
.validate(input)
194+
.or(AddressParser::new_multisig(MultisigScript::V1)
195+
.validate(input))
196+
})
184197
.about("To long multisig address (special case, include since)"),
185198
)
186199
.arg(arg::capacity().required(true))
@@ -322,12 +335,24 @@ impl CliSubCommand for TxSubCommand<'_> {
322335
("add-output", Some(m)) => {
323336
let tx_file: PathBuf = FilePathParser::new(true).from_matches(m, "tx-file")?;
324337
let capacity: u64 = CapacityParser.from_matches(m, "capacity")?;
338+
339+
let multisig_lock_code_hash: H256 =
340+
FixedHashParser::<H256>::default().from_matches(m, "multisig-code-hash")?;
341+
let multisig_script = MultisigScript::try_from(multisig_lock_code_hash.clone())
342+
.map_err(|_err| {
343+
format!(
344+
"invalid multisig lock code hash: {}",
345+
multisig_lock_code_hash
346+
)
347+
})?;
348+
325349
let to_sighash_address_opt: Option<Address> =
326350
AddressParser::new_sighash().from_matches_opt(m, "to-sighash-address")?;
327-
let to_short_multisig_address_opt: Option<Address> = AddressParser::new_multisig()
328-
.from_matches_opt(m, "to-short-multisig-address")?;
351+
let to_short_multisig_address_opt: Option<Address> =
352+
AddressParser::new_multisig(multisig_script)
353+
.from_matches_opt(m, "to-short-multisig-address")?;
329354
let to_long_multisig_address_opt: Option<Address> =
330-
AddressParser::new_multisig()
355+
AddressParser::new_multisig(multisig_script)
331356
.from_matches_opt(m, "to-long-multisig-address")?;
332357

333358
let to_data = get_to_data(m)?;
@@ -370,7 +395,7 @@ impl CliSubCommand for TxSubCommand<'_> {
370395
}
371396
("add-multisig-config", Some(m)) => {
372397
let multisig_lock_code_hash: H256 =
373-
FixedHashParser::<H256>::default().from_matches(m, "lock-code-hash")?;
398+
FixedHashParser::<H256>::default().from_matches(m, "multisig-code-hash")?;
374399
let multisig_script = MultisigScript::try_from(multisig_lock_code_hash.clone())
375400
.map_err(|_err| {
376401
format!(
@@ -597,7 +622,7 @@ impl CliSubCommand for TxSubCommand<'_> {
597622
}
598623
("build-multisig-address", Some(m)) => {
599624
let multisig_lock_code_hash: H256 =
600-
FixedHashParser::<H256>::default().from_matches(m, "lock-code-hash")?;
625+
FixedHashParser::<H256>::default().from_matches(m, "multisig-code-hash")?;
601626
let multisig_script = MultisigScript::try_from(multisig_lock_code_hash.clone())
602627
.map_err(|_err| {
603628
format!(
@@ -651,7 +676,11 @@ fn print_cell_info(
651676
type_script_empty: bool,
652677
) {
653678
let address_payload = AddressPayload::from(lock);
654-
let lock_kind = if address_payload.code_hash(Some(network)) == MULTISIG_SCRIPT.code_hash.pack()
679+
let lock_kind = if [
680+
MultisigScript::Legacy.script_id().code_hash.pack(),
681+
MultisigScript::V1.script_id().code_hash.pack(),
682+
]
683+
.contains(&address_payload.code_hash(Some(network)))
655684
{
656685
if address_payload.args().len() == 20 {
657686
"multisig without since"
@@ -842,7 +871,7 @@ pub struct ReprMultisigConfig {
842871

843872
// for compatibility
844873
fn compatibility_lock_code_hash() -> H256 {
845-
MultisigScript::Deprecated.script_id().code_hash
874+
MultisigScript::Legacy.script_id().code_hash
846875
}
847876

848877
impl ReprMultisigConfig {

src/subcommands/util.rs

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use ckb_crypto::secp::SECP256K1;
1414
use ckb_hash::blake2b_256;
1515
use ckb_jsonrpc_types::{self as json_types, JsonBytes};
1616
use ckb_sdk::{
17-
constants::{DAO_TYPE_HASH, MULTISIG_SCRIPT, SIGHASH_TYPE_HASH, TYPE_ID_CODE_HASH},
17+
constants::{MultisigScript, DAO_TYPE_HASH, SIGHASH_TYPE_HASH, TYPE_ID_CODE_HASH},
1818
util::serialize_signature,
1919
Address, AddressPayload, NetworkType, OldAddress,
2020
};
@@ -111,6 +111,19 @@ impl<'a> UtilSubCommand<'a> {
111111
.conflicts_with(arg::privkey_path().get_name())
112112
.about("The address extended from `m/44'/309'/0'` (Search 2000 receiving addresses and 2000 change addresses max)");
113113

114+
let arg_multisig_lock_hash = Arg::with_name("multisig-code-hash")
115+
.long("multisig-code-hash")
116+
.takes_value(true)
117+
.multiple(false)
118+
.required(false)
119+
.default_value("0x36c971b8d41fbd94aabca77dc75e826729ac98447b46f91e00796155dddb0d29")
120+
.possible_values(&[
121+
"0x5c5069eb0857efc65e1bca0c07df34c31663b3622fd3876c876320fc9634e2a8",
122+
"0x36c971b8d41fbd94aabca77dc75e826729ac98447b46f91e00796155dddb0d29",
123+
])
124+
.validator(|input| FixedHashParser::<H256>::default().validate(input))
125+
.about("Specifies the multisig code hash to use (default: `0x36c971b8d41fbd94aabca77dc75e826729ac98447b46f91e00796155dddb0d29`). \nThe alternative hash (`0x5c5069eb0857efc65e1bca0c07df34c31663b3622fd3876c876320fc9634e2a8`) is deprecated and NOT recommended for use.");
126+
114127
App::new(name)
115128
.about("Utilities")
116129
.subcommands(vec![
@@ -263,6 +276,7 @@ impl<'a> UtilSubCommand<'a> {
263276
App::new("to-multisig-addr")
264277
.about("Convert address in single signature format to multisig format")
265278
.arg(arg_sighash_address.clone())
279+
.arg(arg_multisig_lock_hash.clone())
266280
.arg(
267281
Arg::with_name("locktime")
268282
.long("locktime")
@@ -681,14 +695,24 @@ message = "0x"
681695
.parse(input)?
682696
};
683697

698+
let multisig_lock_code_hash: H256 =
699+
FixedHashParser::<H256>::default().from_matches(m, "multisig-code-hash")?;
700+
let multisig_script = MultisigScript::try_from(multisig_lock_code_hash.clone())
701+
.map_err(|_err| {
702+
format!(
703+
"invalid multisig lock code hash: {}",
704+
multisig_lock_code_hash
705+
)
706+
})?;
707+
684708
let genesis_timestamp =
685709
NaiveDateTime::parse_from_str("2019-11-16 06:00:00", "%Y-%m-%d %H:%M:%S")
686710
.map(|dt| dt.and_utc().timestamp_millis() as u64)
687711
.unwrap();
688712
let target_timestamp = to_timestamp(locktime)?;
689713
let elapsed = target_timestamp.saturating_sub(genesis_timestamp);
690714
let (epoch_fraction, addr_payload) =
691-
gen_multisig_addr(address.payload(), None, elapsed);
715+
gen_multisig_addr(multisig_script, address.payload(), None, elapsed);
692716
let multisig_addr = Address::new(NetworkType::Mainnet, addr_payload, true);
693717
let resp = format!("{},{},{}", address, locktime, multisig_addr);
694718
if debug {
@@ -701,7 +725,7 @@ message = "0x"
701725
elapsed / 1000,
702726
epoch_fraction,
703727
hex_string(multisig_addr.payload().args().as_ref()),
704-
MULTISIG_SCRIPT.code_hash,
728+
MultisigScript::Legacy.script_id().code_hash,
705729
);
706730
}
707731
Ok(Output::new_output(serde_json::json!(resp)))
@@ -713,6 +737,16 @@ message = "0x"
713737
DateTime::parse_from_rfc3339(m.value_of("locktime").unwrap())
714738
.map(|dt| dt.timestamp_millis() as u64)
715739
.map_err(|err| err.to_string())?;
740+
741+
let multisig_lock_code_hash: H256 =
742+
FixedHashParser::<H256>::default().from_matches(m, "multisig-code-hash")?;
743+
let multisig_script = MultisigScript::try_from(multisig_lock_code_hash.clone())
744+
.map_err(|_err| {
745+
format!(
746+
"invalid multisig lock code hash: {}",
747+
multisig_lock_code_hash
748+
)
749+
})?;
716750
let (tip_epoch, tip_timestamp) =
717751
self.rpc_client.get_tip_header().map(|header_view| {
718752
let header = header_view.inner;
@@ -722,7 +756,7 @@ message = "0x"
722756
})?;
723757
let elapsed = locktime_timestamp.saturating_sub(tip_timestamp.0);
724758
let (epoch, multisig_addr) =
725-
gen_multisig_addr(address.payload(), Some(tip_epoch), elapsed);
759+
gen_multisig_addr(multisig_script, address.payload(), Some(tip_epoch), elapsed);
726760
let resp = serde_json::json!({
727761
"address": {
728762
"mainnet": Address::new(NetworkType::Mainnet, multisig_addr.clone(), true).to_string(),
@@ -789,10 +823,10 @@ message = "0x"
789823
},
790824
"secp256k1_blake160_multisig_all": {
791825
"script_id": {
792-
"code_hash": MULTISIG_SCRIPT.code_hash,
793-
"hash_type": json_types::ScriptHashType::from(MULTISIG_SCRIPT.hash_type),
826+
"code_hash": MultisigScript::Legacy.script_id().code_hash,
827+
"hash_type": json_types::ScriptHashType::from(MultisigScript::Legacy.script_id().hash_type),
794828
},
795-
"cell_dep": json_types::CellDep::from(genesis_info.multisig_dep()),
829+
"cell_dep": json_types::CellDep::from(genesis_info.multisig_dep(MultisigScript::Legacy)),
796830
},
797831
"dao": {
798832
"script_id": {
@@ -901,6 +935,7 @@ fn sign_message<P: ?Sized + AsRef<[ChildNumber]>>(
901935
}
902936

903937
fn gen_multisig_addr(
938+
multisig_script: MultisigScript,
904939
sighash_address_payload: &AddressPayload,
905940
tip_epoch_opt: Option<EpochNumberWithFraction>,
906941
elapsed: u64,
@@ -925,8 +960,8 @@ fn gen_multisig_addr(
925960
data.freeze()
926961
};
927962
let payload = AddressPayload::new_full(
928-
MULTISIG_SCRIPT.hash_type,
929-
MULTISIG_SCRIPT.code_hash.pack(),
963+
multisig_script.script_id().hash_type,
964+
multisig_script.script_id().code_hash.pack(),
930965
args,
931966
);
932967
(epoch_fraction, payload)
@@ -947,11 +982,13 @@ mod test {
947982
fn test_gen_multisig_addr() {
948983
let payload = AddressPayload::new_short(CodeHashIndex::Sighash, H160::default());
949984

950-
let (epoch, _) = gen_multisig_addr(&payload, None, BLOCK_PERIOD * 2000);
985+
let (epoch, _) =
986+
gen_multisig_addr(MultisigScript::Legacy, &payload, None, BLOCK_PERIOD * 2000);
951987
assert_eq!(epoch, EpochNumberWithFraction::new(1, 200, EPOCH_LENGTH));
952988

953989
// (1+2/3) + (1+1/2) = 3+1/6
954990
let (epoch, _) = gen_multisig_addr(
991+
MultisigScript::Legacy,
955992
&payload,
956993
Some(EpochNumberWithFraction::new(1, 400, 600)),
957994
BLOCK_PERIOD * 2700,

src/subcommands/wallet.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use ckb_chain_spec::consensus::TYPE_ID_CODE_HASH;
88
use ckb_hash::new_blake2b;
99
use ckb_jsonrpc_types as json_types;
1010
use ckb_sdk::{
11-
constants::{MultisigScript, DAO_TYPE_HASH, MULTISIG_SCRIPT, SIGHASH_TYPE_HASH},
11+
constants::{MultisigScript, DAO_TYPE_HASH, SIGHASH_TYPE_HASH},
1212
traits::{
1313
CellCollector, CellQueryOptions, DefaultCellCollector, DefaultHeaderDepResolver,
1414
DefaultTransactionDependencyProvider, MaturityOption, PrimaryScriptType, Signer,
@@ -169,9 +169,12 @@ impl<'a> WalletSubCommand<'a> {
169169
.transpose()?;
170170
let from_locked_address: Option<Address> = from_locked_address
171171
.map(|input| {
172-
AddressParser::new_multisig()
172+
AddressParser::new_multisig(MultisigScript::Legacy)
173173
.set_network(network_type)
174174
.parse(&input)
175+
.or(AddressParser::new_multisig(MultisigScript::V1)
176+
.set_network(network_type)
177+
.parse(&input))
175178
})
176179
.transpose()?;
177180
let to_capacity: u64 = CapacityParser.parse(&capacity)?.into();
@@ -243,11 +246,11 @@ impl<'a> WalletSubCommand<'a> {
243246
|| (to_address_hash_type == ScriptHashType::Type
244247
&& to_address_code_hash == SIGHASH_TYPE_HASH
245248
&& to_address_args_len == 20)
246-
|| (to_address_hash_type == MultisigScript::Latest.script_id().hash_type
247-
&& to_address_code_hash == MultisigScript::Latest.script_id().code_hash
249+
|| (to_address_hash_type == MultisigScript::V1.script_id().hash_type
250+
&& to_address_code_hash == MultisigScript::V1.script_id().code_hash
248251
&& (to_address_args_len == 20 || to_address_args_len == 28))
249-
|| (to_address_hash_type == MultisigScript::Deprecated.script_id().hash_type
250-
&& to_address_code_hash == MultisigScript::Deprecated.script_id().code_hash
252+
|| (to_address_hash_type == MultisigScript::Legacy.script_id().hash_type
253+
&& to_address_code_hash == MultisigScript::Legacy.script_id().code_hash
251254
&& (to_address_args_len == 20 || to_address_args_len == 28)))
252255
{
253256
return Err(format!(
@@ -355,7 +358,7 @@ impl<'a> WalletSubCommand<'a> {
355358
let threshold = 1;
356359

357360
let mut matched_multisig_config = None;
358-
for multisig_script in [MultisigScript::Latest, MultisigScript::Deprecated] {
361+
for multisig_script in [MultisigScript::V1, MultisigScript::Legacy] {
359362
let config = MultisigConfig::new_with(
360363
multisig_script,
361364
sighash_addresses.clone(),
@@ -377,7 +380,15 @@ impl<'a> WalletSubCommand<'a> {
377380
0,
378381
(lock_script, placehodler_witness, SinceSource::LockArgs(20)),
379382
);
380-
let multisig_script_id = MULTISIG_SCRIPT;
383+
let multisig_script_id =
384+
MultisigScript::try_from(matched_multisig_config.lock_code_hash())
385+
.unwrap_or_else(|_| {
386+
panic!(
387+
"must get multisig script by {}",
388+
matched_multisig_config.lock_code_hash()
389+
)
390+
})
391+
.script_id();
381392
let multisig_unlocker = {
382393
let signer = get_signer()?;
383394
SecpMultisigUnlocker::new(SecpMultisigScriptSigner::new(

0 commit comments

Comments
 (0)