@@ -18,89 +18,104 @@ class ScriptPubKey extends Script
1818 */
1919 public function isReturn (): bool
2020 {
21- $ operations = $ this ->parse ();
22-
23- return count ($ operations ) >= 1 &&
24- $ operations [0 ]->code == Opcodes::OP_RETURN ;
21+ return $ this ->size >= 1 && ord ($ this ->data [0 ]) == Opcodes::OP_RETURN ;
2522 }
2623
2724 /**
2825 * @return bool
2926 */
3027 public function isPayToPubKey (): bool
3128 {
32- $ operations = $ this ->parse ();
29+ // compressed pubkey
30+ if ($ this ->size == 35 &&
31+ ord ($ this ->data [0 ]) == 33 &&
32+ ord ($ this ->data [-1 ]) == Opcodes::OP_CHECKSIG &&
33+ ($ this ->data [1 ] == "\x02" || $ this ->data [1 ] == "\x03" )) {
34+ return true ;
35+ }
36+
37+ // uncompressed pubkey
38+ if ($ this ->size == 67 &&
39+ ord ($ this ->data [0 ]) == 65 &&
40+ ord ($ this ->data [-1 ]) == Opcodes::OP_CHECKSIG &&
41+ $ this ->data [1 ] == "\x04" ) {
42+ return true ;
43+ }
3344
34- return count ($ operations ) == 2 &&
35- ($ operations [0 ]->size == 33 || $ operations [0 ]->size == 65 ) &&
36- $ operations [1 ]->code == Opcodes::OP_CHECKSIG ;
45+ return false ;
3746 }
3847
3948 /**
4049 * @return bool
4150 */
4251 public function isPayToPubKeyHash (): bool
4352 {
44- $ operations = $ this ->parse ();
45-
46- return count ($ operations ) == 5 &&
47- $ operations [0 ]->code == Opcodes::OP_DUP &&
48- $ operations [1 ]->code == Opcodes::OP_HASH160 &&
49- $ operations [2 ]->size == 20 &&
50- $ operations [3 ]->code == Opcodes::OP_EQUALVERIFY &&
51- $ operations [4 ]->code == Opcodes::OP_CHECKSIG ;
53+ return $ this ->size == 25 &&
54+ ord ($ this ->data [0 ]) == Opcodes::OP_DUP &&
55+ ord ($ this ->data [1 ]) == Opcodes::OP_HASH160 &&
56+ ord ($ this ->data [2 ]) == 20 &&
57+ ord ($ this ->data [-2 ]) == Opcodes::OP_EQUALVERIFY &&
58+ ord ($ this ->data [-1 ]) == Opcodes::OP_CHECKSIG ;
5259 }
5360
5461 /**
5562 * @return bool
5663 */
5764 public function isPayToScriptHash (): bool
5865 {
59- $ operations = $ this ->parse ();
60-
61- return count ($ operations ) == 3 &&
62- $ operations [0 ]->code == Opcodes::OP_HASH160 &&
63- $ operations [1 ]->size == 20 &&
64- $ operations [2 ]->code == Opcodes::OP_EQUAL ;
66+ return $ this ->size == 23 &&
67+ ord ($ this ->data [0 ]) == Opcodes::OP_HASH160 &&
68+ ord ($ this ->data [1 ]) == 20 &&
69+ ord ($ this ->data [-1 ]) == Opcodes::OP_EQUAL ;
6570 }
6671
6772 /**
6873 * @return bool
6974 */
7075 public function isMultisig (): bool
7176 {
72- $ operations = $ this ->parse ();
77+ $ keys = ord ($ this ->data [0 ]);
78+ $ sigs = ord ($ this ->data [-2 ]);
79+
80+ if (!($ this ->size >= 24 &&
81+ $ keys >= Opcodes::OP_1 && $ keys <= Opcodes::OP_16 &&
82+ $ sigs && $ sigs <= Opcodes::OP_16 &&
83+ $ keys >= $ sigs &&
84+ ord ($ this ->data [-1 ]) == Opcodes::OP_CHECKMULTISIG )) {
85+ return false ;
86+ }
87+
88+ for ($ i = 1 , $ k = 0 ; $ i < $ this ->size - 2 ; $ i += 21 , $ k ++) {
89+ if (ord ($ this ->data [$ i ]) != 20 ) {
90+ return false ;
91+ }
92+ }
7393
74- return ($ count = count ($ operations )) >= 4 &&
75- $ operations [0 ]->code >= Opcodes::OP_1 &&
76- $ operations [$ count - 2 ]->code >= Opcodes::OP_1 &&
77- $ operations [$ count - 1 ]->code == Opcodes::OP_CHECKMULTISIG ;
94+ return $ keys - Opcodes::OP_1 + 1 == $ k ;
7895 }
7996
8097 /**
8198 * @return bool
8299 */
83100 public function isPayToWitnessPubKeyHash (): bool
84101 {
85- $ operations = $ this ->parse ( );
102+ $ version = ord ( $ this ->data [ 0 ] );
86103
87- return count ($ operations ) == 2 &&
88- $ operations [0 ]->code >= Opcodes::OP_0 &&
89- $ operations [0 ]->code <= Opcodes::OP_16 &&
90- $ operations [1 ]->size == 20 ;
104+ return $ this ->size == 22 &&
105+ $ version >= Opcodes::OP_0 && $ version <= Opcodes::OP_16 &&
106+ ord ($ this ->data [1 ]) == 20 ;
91107 }
92108
93109 /**
94110 * @return bool
95111 */
96112 public function isPayToWitnessScriptHash (): bool
97113 {
98- $ operations = $ this ->parse ( );
114+ $ version = ord ( $ this ->data [ 0 ] );
99115
100- return count ($ operations ) == 2 &&
101- $ operations [0 ]->code >= Opcodes::OP_0 &&
102- $ operations [0 ]->code <= Opcodes::OP_16 &&
103- $ operations [1 ]->size == 32 ;
116+ return $ this ->size == 34 &&
117+ $ version >= Opcodes::OP_0 && $ version <= Opcodes::OP_16 &&
118+ ord ($ this ->data [1 ]) == 32 ;
104119 }
105120
106121 /**
0 commit comments