Skip to content

Commit 1575907

Browse files
committed
multisig out fix
1 parent 4b47056 commit 1575907

File tree

2 files changed

+32
-22
lines changed

2 files changed

+32
-22
lines changed

src/Script/ScriptPubKey.php

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,29 +32,37 @@ public function isEmpty(): bool
3232
}
3333

3434
/**
35+
* @param int $size
36+
* @param string $prefix
3537
* @return bool
3638
*/
37-
public function isPayToPubKey(): bool
39+
protected function isPubKey(int $size, string $prefix): bool
3840
{
39-
// compressed pubkey
40-
if ($this->size == PublicKey::LENGTH_COMPRESSED + 2 &&
41-
ord($this->data[0]) == PublicKey::LENGTH_COMPRESSED &&
42-
($this->data[1] == PublicKey::PREFIX_COMPRESSED_EVEN || $this->data[1] == PublicKey::PREFIX_COMPRESSED_ODD) &&
43-
ord($this->data[-1]) == Opcodes::OP_CHECKSIG) {
41+
if ($size == PublicKey::LENGTH_COMPRESSED &&
42+
($prefix == PublicKey::PREFIX_COMPRESSED_EVEN ||
43+
$prefix == PublicKey::PREFIX_COMPRESSED_ODD)) {
4444
return true;
4545
}
4646

47-
// uncompressed pubkey
48-
if ($this->size == PublicKey::LENGTH_UNCOMPRESSED + 2 &&
49-
ord($this->data[0]) == PublicKey::LENGTH_UNCOMPRESSED &&
50-
$this->data[1] == PublicKey::PREFIX_UNCOMPRESSED &&
51-
ord($this->data[-1]) == Opcodes::OP_CHECKSIG) {
47+
if ($size == PublicKey::LENGTH_UNCOMPRESSED &&
48+
$prefix == PublicKey::PREFIX_UNCOMPRESSED) {
5249
return true;
5350
}
5451

5552
return false;
5653
}
5754

55+
/**
56+
* @return bool
57+
*/
58+
public function isPayToPubKey(): bool
59+
{
60+
return (($this->size == PublicKey::LENGTH_COMPRESSED + 2 ||
61+
$this->size == PublicKey::LENGTH_UNCOMPRESSED + 2) &&
62+
$this->isPubKey(ord($this->data[0]), $this->data[1]) &&
63+
ord($this->data[-1]) == Opcodes::OP_CHECKSIG);
64+
}
65+
5866
/**
5967
* @return bool
6068
*/
@@ -102,18 +110,22 @@ public function isMultisig(): bool
102110
$sigs = ord($this->data[0]);
103111
$keys = ord($this->data[-2]);
104112

105-
if (!($this->size >= 24 &&
113+
if (!($this->size >= 37 &&
106114
$sigs >= Opcodes::OP_1 && $sigs <= Opcodes::OP_16 &&
107115
$keys >= Opcodes::OP_1 && $keys <= Opcodes::OP_16 &&
108116
$keys >= $sigs &&
109117
ord($this->data[-1]) == Opcodes::OP_CHECKMULTISIG)) {
110118
return false;
111119
}
112120

113-
for ($i = 1, $k = 0; $i < $this->size - 2; $i += 21, $k++) {
114-
if (ord($this->data[$i]) != 20) {
121+
for ($i = 1, $k = 0; $i < $this->size - 2; $k++) {
122+
$size = ord($this->data[$i]);
123+
124+
if (!$this->isPubKey($size, $this->data[$i + 1])) {
115125
return false;
116126
}
127+
128+
$i += $size + 1;
117129
}
118130

119131
return $keys - Opcodes::OP_1 + 1 == $k;

tests/ScriptPubKeyTest.php

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,12 @@ public function testParseP2SH()
9393
// [numsigs] [...pubkeys...] [numpubkeys] OP_CHECKMULTISIG
9494
public function testParseMultisig()
9595
{
96-
$hex = '52'; // 2
97-
$hex .= '14'; // 20
98-
$hex .= '91b24bf9f5288532960ac687abb035127b1d28a5'; // pubkey hash
99-
$hex .= '14'; // 20
100-
$hex .= 'd6c8e828c1eca1bba065e1b83e1dc2a36e387a42'; // pubkey hash
101-
$hex .= '14'; // 20
102-
$hex .= 'ec7eced2c57ed1292bc4eb9bfd13c9f7603bc338'; // pubkey hash
103-
$hex .= '53'; // 3
96+
$hex = '51'; // 1
97+
$hex .= '21'; // 33
98+
$hex .= '035b219535a5e9238bccc25c71ce4fddf024f5d9b452887225d23057b870d444b9'; // pubkey
99+
$hex .= '41'; // 65
100+
$hex .= '0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'; // pubkey
101+
$hex .= '52'; // 2
104102
$hex .= 'ae'; // OP_CHECKMULTISIG
105103

106104
$script = new ScriptPubKey(hex2bin($hex));

0 commit comments

Comments
 (0)