1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 module btcscript
is aliced
;
10 // Maximum number of bytes pushable to the stack
11 enum MAX_SCRIPT_ELEMENT_SIZE
= 520;
13 // Maximum number of non-push operations per script
14 enum MAX_OPS_PER_SCRIPT
= 201;
16 // Maximum number of public keys per multisig
17 enum MAX_PUBKEYS_PER_MULTISIG
= 20;
19 // Maximum script length in bytes
20 enum MAX_SCRIPT_SIZE
= 10000;
22 // Maximum number of values on script interpreter stack
23 enum MAX_STACK_SIZE
= 1000;
25 // Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp.
26 //enum LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC
71 OP_FROMALTSTACK
= 0x6c,
103 OP_EQUALVERIFY
= 0x88,
128 OP_NUMEQUALVERIFY
= 0x9d,
129 OP_NUMNOTEQUAL
= 0x9e,
131 OP_GREATERTHAN
= 0xa0,
132 OP_LESSTHANOREQUAL
= 0xa1,
133 OP_GREATERTHANOREQUAL
= 0xa2,
145 OP_CODESEPARATOR
= 0xab,
147 OP_CHECKSIGVERIFY
= 0xad,
148 OP_CHECKMULTISIG
= 0xae,
149 OP_CHECKMULTISIGVERIFY
= 0xaf,
153 OP_CHECKLOCKTIMEVERIFY
= 0xb1,
154 OP_NOP2
= OP_CHECKLOCKTIMEVERIFY
,
155 OP_CHECKSEQUENCEVERIFY
= 0xb2,
156 OP_NOP3
= OP_CHECKSEQUENCEVERIFY
,
166 MAX_OPCODE = OP_NOP10, // maximum value that an opcode can be
168 // template matching params
169 OP_SMALLINTEGER = 0xfa,
171 OP_PUBKEYHASH = 0xfd,
174 OP_INVALIDOPCODE = 0xff,
180 * Numeric opcodes (OP_1ADD, etc) are restricted to operating on 4-byte integers.
181 * The semantics are subtle, though: operands must be in the range [-2^31 +1...2^31 -1],
182 * but results may overflow (and are valid as long as they are not used in a subsequent
183 * numeric operation). CScriptNum enforces those semantics by storing results as
184 * an int64 and allowing out-of-range values to be returned as a vector of bytes but
185 * throwing an exception if arithmetic is done or the result is interpreted as an integer.
188 int btsOpSize (const(ubyte)[] code
) nothrow @trusted @nogc {
189 if (code
.length
== 0) return 0;
190 auto opc
= code
.ptr
[0];
191 if (opc
>= 1 && opc
<= 75) return opc
+1;
192 if (opc
== OpCode
.OP_PUSHDATA1
) {
193 if (code
.length
< 1+1) return cast(int)code
.length
;
194 return 1+code
.ptr
[1];
196 if (opc
== OpCode
.OP_PUSHDATA2
) {
197 if (code
.length
< 1+2) return cast(int)code
.length
;
198 return 1+code
.ptr
[1]+(code
.ptr
[2]<<8);
200 if (opc
== OpCode
.OP_PUSHDATA4
) {
201 if (code
.length
< 1+4) return cast(int)code
.length
;
202 return 1+code
.ptr
[1]+(code
.ptr
[2]<<8)+(code
.ptr
[3]<<16)+(code
.ptr
[4]<<24);
208 string
btsDecodeOne (const(ubyte)[] code
) {
209 import std
.format
: format
;
210 if (code
.length
== 0) return null;
213 if (opc
> OpCode
.OP_NOP10
) return "INVALID";
214 if (opc
== OpCode
.OP_FALSE
) return "FALSE";
215 if (opc
== OpCode
.OP_TRUE
) return "TRUE";
216 int opclen
= btsOpSize(code
);
218 // this is push opcode
219 string res
= "PUSH %d ;".format(opclen
-1);
220 foreach (ubyte b
; code
[1..opclen
]) res
= "%s 0x%02x".format(res
, b
);
223 foreach (string name
; __traits(allMembers
, OpCode
)) {
224 if (opc
== __traits(getMember
, OpCode
, name
)) return name
[3..$];