Skip to content

Commit 48e97f6

Browse files
committed
multisig out fix
1 parent 1575907 commit 48e97f6

File tree

2 files changed

+46
-9
lines changed

2 files changed

+46
-9
lines changed

src/Script/ScriptPubKey.php

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
class ScriptPubKey extends Script
1717
{
1818
/**
19+
* ScriptPubKey: OP_RETURN ...
1920
* @return bool
2021
*/
2122
public function isReturn(): bool
@@ -24,6 +25,7 @@ public function isReturn(): bool
2425
}
2526

2627
/**
28+
* ScriptPubKey: (empty)
2729
* @return bool
2830
*/
2931
public function isEmpty(): bool
@@ -53,6 +55,9 @@ protected function isPubKey(int $size, string $prefix): bool
5355
}
5456

5557
/**
58+
* ScriptPubKey: OP_PUSHDATA(33) [0x02] [pubkey compressed] OP_CHECKSIG
59+
* ScriptPubKey: OP_PUSHDATA(33) [0x03] [pubkey compressed] OP_CHECKSIG
60+
* ScriptPubKey: OP_PUSHDATA(65) [0x04] [pubkey] OP_CHECKSIG
5661
* @return bool
5762
*/
5863
public function isPayToPubKey(): bool
@@ -64,6 +69,7 @@ public function isPayToPubKey(): bool
6469
}
6570

6671
/**
72+
* ScriptPubKey: OP_DUP OP_HASH160 OP_PUSHDATA(20) [pubkey hash] OP_EQUALVERIFY OP_CHECKSIG
6773
* @return bool
6874
*/
6975
public function isPayToPubKeyHash(): bool
@@ -77,7 +83,8 @@ public function isPayToPubKeyHash(): bool
7783
}
7884

7985
/**
80-
* handle output of TX 059787f0673ab2c00b8f2f9810fdd14b0cd6a3034cc44dc30de124f606d3670a
86+
* Handle output of TX 059787f0673ab2c00b8f2f9810fdd14b0cd6a3034cc44dc30de124f606d3670a
87+
* ScriptPubKey: OP_DUP OP_HASH160 OP_PUSHDATA1 [pubkey hash] OP_EQUALVERIFY OP_CHECKSIG
8188
* @return bool
8289
*/
8390
public function isPayToPubKeyHashAlt(): bool
@@ -92,6 +99,7 @@ public function isPayToPubKeyHashAlt(): bool
9299
}
93100

94101
/**
102+
* ScriptPubKey: OP_HASH160 PUSHDATA(20) [script hash] OP_EQUAL
95103
* @return bool
96104
*/
97105
public function isPayToScriptHash(): bool
@@ -103,13 +111,15 @@ public function isPayToScriptHash(): bool
103111
}
104112

105113
/**
114+
* ScriptPubKey: [num sigs] [...pub keys..] [num pub keys] OP_CHECKMULTISIG
106115
* @return bool
107116
*/
108117
public function isMultisig(): bool
109118
{
110119
$sigs = ord($this->data[0]);
111120
$keys = ord($this->data[-2]);
112121

122+
// check pattern
113123
if (!($this->size >= 37 &&
114124
$sigs >= Opcodes::OP_1 && $sigs <= Opcodes::OP_16 &&
115125
$keys >= Opcodes::OP_1 && $keys <= Opcodes::OP_16 &&
@@ -118,20 +128,18 @@ public function isMultisig(): bool
118128
return false;
119129
}
120130

121-
for ($i = 1, $k = 0; $i < $this->size - 2; $k++) {
131+
// check valid keys
132+
for ($i = 1, $j = $k = 0; $i < $this->size - 2; $j++) {
122133
$size = ord($this->data[$i]);
123-
124-
if (!$this->isPubKey($size, $this->data[$i + 1])) {
125-
return false;
126-
}
127-
134+
$k += $this->isPubKey($size, $this->data[$i + 1]);
128135
$i += $size + 1;
129136
}
130137

131-
return $keys - Opcodes::OP_1 + 1 == $k;
138+
return $k > 0 && $keys - Opcodes::OP_1 + 1 == $j;
132139
}
133140

134141
/**
142+
* ScriptPubKey: [version] OP_PUSHDATA(20) [pubkey hash]
135143
* @return bool
136144
*/
137145
public function isPayToWitnessPubKeyHash(): bool
@@ -144,6 +152,7 @@ public function isPayToWitnessPubKeyHash(): bool
144152
}
145153

146154
/**
155+
* ScriptPubKey: [version] OP_PUSHDATA(32) [script hash]
147156
* @return bool
148157
*/
149158
public function isPayToWitnessScriptHash(): bool

tests/ScriptPubKeyTest.php

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public function testParseP2SH()
9191
}
9292

9393
// [numsigs] [...pubkeys...] [numpubkeys] OP_CHECKMULTISIG
94-
public function testParseMultisig()
94+
public function testParseMultisig1()
9595
{
9696
$hex = '51'; // 1
9797
$hex .= '21'; // 33
@@ -106,6 +106,34 @@ public function testParseMultisig()
106106
$this->assertTrue($script->isMultisig());
107107
}
108108

109+
public function testParseMultisig2()
110+
{
111+
$hex = '51'; // 1
112+
$hex .= '21'; // 33
113+
$hex .= '035b219535a5e9238bccc25c71ce4fddf024f5d9b452887225d23057b870d444b9'; // pubkey
114+
$hex .= '41'; // 65
115+
$hex .= '0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'; // pubkey
116+
$hex .= '51'; // 1
117+
$hex .= 'ae'; // OP_CHECKMULTISIG
118+
119+
$script = new ScriptPubKey(hex2bin($hex));
120+
121+
$this->assertFalse($script->isMultisig());
122+
}
123+
124+
public function testParseMultisig3()
125+
{
126+
$hex = '51'; // 1
127+
$hex .= '21'; // 33
128+
$hex .= '005b219535a5e9238bccc25c71ce4fddf024f5d9b452887225d23057b870d444b9'; // pubkey
129+
$hex .= '51'; // 1
130+
$hex .= 'ae'; // OP_CHECKMULTISIG
131+
132+
$script = new ScriptPubKey(hex2bin($hex));
133+
134+
$this->assertFalse($script->isMultisig());
135+
}
136+
109137
// [segwit ver] [pubkey hash]
110138
public function testParseP2WPKH()
111139
{

0 commit comments

Comments
 (0)