Skip to content

Commit b01fdfb

Browse files
committed
Update Multisig
Signed-off-by: Eval EXEC <execvy@gmail.com>
1 parent 034f5b0 commit b01fdfb

7 files changed

Lines changed: 117 additions & 19 deletions

File tree

ckb/src/main/java/org/nervos/ckb/transaction/handler/Secp256k1Blake160MultisigAllScriptHandler.java

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@
44
import org.nervos.ckb.sign.ScriptGroup;
55
import org.nervos.ckb.sign.signer.Secp256k1Blake160MultisigAllSigner;
66
import org.nervos.ckb.transaction.AbstractTransactionBuilder;
7-
import org.nervos.ckb.type.CellDep;
8-
import org.nervos.ckb.type.OutPoint;
9-
import org.nervos.ckb.type.Script;
10-
import org.nervos.ckb.type.WitnessArgs;
7+
import org.nervos.ckb.type.*;
118
import org.nervos.ckb.utils.Numeric;
129

1310
import java.util.Arrays;
@@ -16,8 +13,10 @@
1613
public class Secp256k1Blake160MultisigAllScriptHandler implements ScriptHandler {
1714
private List<CellDep> cellDeps;
1815
private byte[] codeHash;
16+
private Script.HashType hashType;
17+
private MultisigVersion multisigVersion;
1918

20-
public Secp256k1Blake160MultisigAllScriptHandler() {
19+
public Secp256k1Blake160MultisigAllScriptHandler(MultisigVersion multisigVersion) {
2120
}
2221

2322
public List<CellDep> getCellDeps() {
@@ -36,30 +35,67 @@ public void setCodeHash(byte[] codeHash) {
3635
this.codeHash = codeHash;
3736
}
3837

38+
public Script.HashType getHashType() {
39+
return hashType;
40+
}
41+
42+
public void setHashType(Script.HashType hashType) {
43+
this.hashType = hashType;
44+
}
45+
46+
public MultisigVersion getMultisigVersion() {
47+
return multisigVersion;
48+
}
49+
50+
public void setMultisigVersion(MultisigVersion multisigVersion) {
51+
this.multisigVersion = multisigVersion;
52+
}
53+
3954
@Override
4055
public void init(Network network) {
4156
OutPoint outPoint = new OutPoint();
4257
if (network == Network.MAINNET) {
43-
outPoint.txHash = Numeric.hexStringToByteArray("0x71a7ba8fc96349fea0ed3a5c47992e3b4084b031a42264a018e0072e8172e46c");
44-
outPoint.index = 1;
58+
switch (this.multisigVersion) {
59+
case Legacy:
60+
outPoint.txHash = Numeric.hexStringToByteArray("0x71a7ba8fc96349fea0ed3a5c47992e3b4084b031a42264a018e0072e8172e46c");
61+
outPoint.index = 1;
62+
break;
63+
case V2:
64+
outPoint.txHash = Numeric.hexStringToByteArray("0x6888aa39ab30c570c2c30d9d5684d3769bf77265a7973211a3c087fe8efbf738");
65+
outPoint.index = 0;
66+
break;
67+
default:
68+
throw new IllegalArgumentException("Unsupported multisig version");
69+
}
4570
} else if (network == Network.TESTNET) {
46-
outPoint.txHash = Numeric.hexStringToByteArray("0xf8de3bb47d055cdf460d93a2a6e1b05f7432f9777c8c474abf4eec1d4aee5d37");
47-
outPoint.index = 1;
71+
switch (this.multisigVersion) {
72+
case Legacy:
73+
outPoint.txHash = Numeric.hexStringToByteArray("0xf8de3bb47d055cdf460d93a2a6e1b05f7432f9777c8c474abf4eec1d4aee5d37");
74+
outPoint.index = 1;
75+
break;
76+
case V2:
77+
outPoint.txHash = Numeric.hexStringToByteArray("0x2eefdeb21f3a3edf697c28a52601b4419806ed60bb427420455cc29a090b26d5");
78+
outPoint.index = 0;
79+
break;
80+
default:
81+
throw new IllegalArgumentException("Unsupported multisig version");
82+
}
4883
} else {
4984
throw new IllegalArgumentException("Unsupported network");
5085
}
5186
CellDep cellDep = new CellDep();
5287
cellDep.outPoint = outPoint;
5388
cellDep.depType = CellDep.DepType.DEP_GROUP;
5489
cellDeps = Arrays.asList(cellDep);
55-
this.codeHash = Script.SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH;
90+
this.codeHash = this.multisigVersion.codeHash();
91+
this.hashType = this.multisigVersion.hashType();
5692
}
5793

5894
private boolean isMatched(Script script) {
5995
if (script == null) {
6096
return false;
6197
}
62-
return Arrays.equals(script.codeHash, codeHash);
98+
return Arrays.equals(script.codeHash, codeHash) && script.hashType == hashType;
6399
}
64100

65101
@Override

core/src/main/java/org/nervos/ckb/sign/TransactionSigner.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ public class TransactionSigner {
1919
.registerLockScriptSigner(
2020
Script.SECP256K1_BLAKE160_SIGNHASH_ALL_CODE_HASH, new Secp256k1Blake160SighashAllSigner())
2121
.registerLockScriptSigner(
22-
Script.SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH, new Secp256k1Blake160MultisigAllSigner())
22+
Script.SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH_LEGACY, new Secp256k1Blake160MultisigAllSigner())
23+
.registerLockScriptSigner(
24+
Script.SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH_V2, new Secp256k1Blake160MultisigAllSigner())
2325
.registerLockScriptSigner(
2426
Script.ANY_CAN_PAY_CODE_HASH_TESTNET, new AcpSigner())
2527
.registerLockScriptSigner(
@@ -31,7 +33,9 @@ Script.PW_LOCK_CODE_HASH_TESTNET, new PwSigner())
3133
.registerLockScriptSigner(
3234
Script.SECP256K1_BLAKE160_SIGNHASH_ALL_CODE_HASH, new Secp256k1Blake160SighashAllSigner())
3335
.registerLockScriptSigner(
34-
Script.SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH, new Secp256k1Blake160MultisigAllSigner())
36+
Script.SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH_LEGACY, new Secp256k1Blake160MultisigAllSigner())
37+
.registerLockScriptSigner(
38+
Script.SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH_V2, new Secp256k1Blake160MultisigAllSigner())
3539
.registerLockScriptSigner(
3640
Script.ANY_CAN_PAY_CODE_HASH_MAINNET, new AcpSigner())
3741
.registerLockScriptSigner(
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package org.nervos.ckb.type;
2+
3+
public enum MultisigVersion {
4+
/// Multisig Script deployed on Genesis Block
5+
/// https://explorer.nervos.org/script/0x5c5069eb0857efc65e1bca0c07df34c31663b3622fd3876c876320fc9634e2a8/type
6+
Legacy,
7+
/// Latest multisig script, Enhance multisig handling for optional since value
8+
/// https://github.com/nervosnetwork/ckb-system-scripts/pull/99
9+
/// https://explorer.nervos.org/script/0x36c971b8d41fbd94aabca77dc75e826729ac98447b46f91e00796155dddb0d29/data1
10+
V2;
11+
12+
public byte[] codeHash(){
13+
switch (this)
14+
{
15+
case Legacy:
16+
return Script.SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH_LEGACY;
17+
case V2:
18+
return Script.SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH_V2;
19+
default:
20+
throw new IllegalArgumentException("Unknown multisig version: " + this);
21+
}
22+
}
23+
24+
public Script.HashType hashType() {
25+
switch (this)
26+
{
27+
case Legacy:
28+
return Script.HashType.TYPE;
29+
case V2:
30+
return Script.HashType.DATA1;
31+
default:
32+
throw new IllegalArgumentException("Unknown multisig version: " + this);
33+
}
34+
}
35+
}

core/src/main/java/org/nervos/ckb/type/Script.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,19 @@
1111
import static org.nervos.ckb.utils.MoleculeConverter.packByte32;
1212
import static org.nervos.ckb.utils.MoleculeConverter.packBytes;
1313

14+
1415
public class Script {
1516
public static final byte[] SECP256K1_BLAKE160_SIGNHASH_ALL_CODE_HASH =
1617
Numeric.hexStringToByteArray("0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8");
17-
public static final byte[] SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH =
18+
// Multisig Script deployed on Genesis Block
19+
// https://explorer.nervos.org/script/0x5c5069eb0857efc65e1bca0c07df34c31663b3622fd3876c876320fc9634e2a8/type
20+
public static final byte[] SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH_LEGACY =
1821
Numeric.hexStringToByteArray("0x5c5069eb0857efc65e1bca0c07df34c31663b3622fd3876c876320fc9634e2a8");
22+
// Latest multisig script, Enhance multisig handling for optional since value
23+
// https://github.com/nervosnetwork/ckb-system-scripts/pull/99
24+
// https://explorer.nervos.org/script/0x36c971b8d41fbd94aabca77dc75e826729ac98447b46f91e00796155dddb0d29/data1
25+
public static final byte[] SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH_V2=
26+
Numeric.hexStringToByteArray("0x36c971b8d41fbd94aabca77dc75e826729ac98447b46f91e00796155dddb0d29");
1927
public static final byte[] ANY_CAN_PAY_CODE_HASH_MAINNET =
2028
Numeric.hexStringToByteArray("0xd369597ff47f29fbc0d47d2e3775370d1250b85140c670e4718af712983a2354");
2129
public static final byte[] ANY_CAN_PAY_CODE_HASH_TESTNET =

core/src/main/java/org/nervos/ckb/utils/address/Address.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ private static Address decodeShort(byte[] payload, Network network) {
8585
if (args.length != 20) {
8686
throw new AddressFormatException("Invalid args length " + args.length);
8787
}
88-
codeHash = Script.SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH;
88+
codeHash = Script.SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH_LEGACY;
8989
} else if (codeHashIndex == 0x02) {
9090
if (args.length < 20 || args.length > 22) {
9191
throw new AddressFormatException("Invalid args length " + args.length);
@@ -145,7 +145,7 @@ public String encodeShort() {
145145
byte[] codeHash = script.codeHash;
146146
if (Arrays.equals(codeHash, Script.SECP256K1_BLAKE160_SIGNHASH_ALL_CODE_HASH)) {
147147
codeHashIndex = 0x00;
148-
} else if (Arrays.equals(codeHash, Script.SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH)) {
148+
} else if (Arrays.equals(codeHash, Script.SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH_LEGACY)) {
149149
codeHashIndex = 0x01;
150150
} else if ((network == Network.MAINNET && Arrays.equals(codeHash, Script.ANY_CAN_PAY_CODE_HASH_MAINNET)
151151
|| (network == Network.TESTNET && Arrays.equals(codeHash, Script.ANY_CAN_PAY_CODE_HASH_TESTNET)))) {
@@ -260,4 +260,4 @@ public int hashCode() {
260260
result = 31 * result + network.hashCode();
261261
return result;
262262
}
263-
}
263+
}

core/src/test/java/utils/AddressTest.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.junit.jupiter.api.Test;
44
import org.nervos.ckb.Network;
5+
import org.nervos.ckb.type.MultisigVersion;
56
import org.nervos.ckb.type.Script;
67
import org.nervos.ckb.utils.Numeric;
78
import org.nervos.ckb.utils.address.Address;
@@ -22,7 +23,7 @@ public void testDecodeDecode() {
2223
testShort(script, Network.MAINNET, "ckb1qyqt8xaupvm8837nv3gtc9x0ekkj64vud3jqfwyw5v");
2324
testShort(script, Network.TESTNET, "ckt1qyqt8xaupvm8837nv3gtc9x0ekkj64vud3jq5t63cs");
2425

25-
script = generateScript(Script.SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH,
26+
script = generateScript(Script.SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH_LEGACY,
2627
"4fb2be2e5d0c1a3b8694f832350a33c1685d477a", Script.HashType.TYPE);
2728
testShort(script, Network.MAINNET, "ckb1qyq5lv479ewscx3ms620sv34pgeuz6zagaaqklhtgg");
2829
testShort(script, Network.TESTNET, "ckt1qyq5lv479ewscx3ms620sv34pgeuz6zagaaqt6f5y5");
@@ -59,6 +60,20 @@ public void testDecodeDecode() {
5960
"b39bbc0b3673c7d36450bc14cfcdad2d559c6c64", Script.HashType.DATA1);
6061
testFullBech32m(script, Network.MAINNET, "ckb1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq4nnw7qkdnnclfkg59uzn8umtfd2kwxceqcydzyt");
6162
testFullBech32m(script, Network.TESTNET, "ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq4nnw7qkdnnclfkg59uzn8umtfd2kwxceqkkxdwn");
63+
64+
// multiscript v2
65+
66+
script = generateScript(MultisigVersion.V2.codeHash(),
67+
"986b5c23988427044e57d188fee45530d8877bcc", MultisigVersion.V2.hashType());
68+
testFullBech32m(script, Network.MAINNET, "ckb1qqmvjudc6s0mm992hjnhm367sfnjntycg3a5d7g7qpukz4wamvxjjq5cddwz8xyyyuzyu4733rlwg4fsmzrhhnqvclulh");
69+
"986b5c23988427044e57d188fee45530d8877bcc", MultisigVersion.V2.hashType());
70+
testFullBech32m(script, Network.TESTNET, "ckt1qqmvjudc6s0mm992hjnhm367sfnjntycg3a5d7g7qpukz4wamvxjjq5cddwz8xyyyuzyu4733rlwg4fsmzrhhnqz25n40");
71+
72+
script = generateScript(MultisigVersion.Legacy.codeHash(),
73+
"986b5c23988427044e57d188fee45530d8877bcc", MultisigVersion.Legacy.hashType());
74+
testFullBech32m(script, Network.MAINNET, "ckb1qpw9q60tppt7l3j7r09qcp7lxnp3vcanvgha8pmvsa3jplykxn32sqvcddwz8xyyyuzyu4733rlwg4fsmzrhhnqq5gm75");
75+
"986b5c23988427044e57d188fee45530d8877bcc", MultisigVersion.Legacy.hashType());
76+
testFullBech32m(script, Network.TESTNET, "ckt1qpw9q60tppt7l3j7r09qcp7lxnp3vcanvgha8pmvsa3jplykxn32sqvcddwz8xyyyuzyu4733rlwg4fsmzrhhnqwxr55v");
6277
}
6378

6479
private void testShort(Script script, Network network, String encoded) {

example/src/main/java/org/nervos/ckb/example/SendCkbMultisigExample.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public static void main(String[] args) throws IOException {
2525
"0x7336b0ba900684cb3cb00f0d46d4f64c0994a562",
2626
"0x5724c1e3925a5206944d753a6f3edaedf977d77f");
2727
Script lock = new Script(
28-
Script.SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH,
28+
Script.SECP256K1_BLAKE160_MULTISIG_ALL_CODE_HASH_LEGACY,
2929
multisigScript.computeHash(),
3030
Script.HashType.TYPE);
3131
// ckt1qpw9q60tppt7l3j7r09qcp7lxnp3vcanvgha8pmvsa3jplykxn32sqdunqvd3g2felqv6qer8pkydws8jg9qxlca0st5v

0 commit comments

Comments
 (0)