egtui: added "M-U" undo keybind
[iv.d.git] / btc_expers / btcscript.d
blobba92a93a0e792feb639220935121a5ed11ec918a
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;
7 //import iv.vfs.io;
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
29 // Script opcodes
30 enum OpCode {
31 // push value
32 OP_0 = 0x00,
33 OP_FALSE = OP_0,
34 OP_PUSHDATA1 = 0x4c,
35 OP_PUSHDATA2 = 0x4d,
36 OP_PUSHDATA4 = 0x4e,
37 OP_1NEGATE = 0x4f,
38 OP_RESERVED = 0x50,
39 OP_1 = 0x51,
40 OP_TRUE=OP_1,
41 OP_2 = 0x52,
42 OP_3 = 0x53,
43 OP_4 = 0x54,
44 OP_5 = 0x55,
45 OP_6 = 0x56,
46 OP_7 = 0x57,
47 OP_8 = 0x58,
48 OP_9 = 0x59,
49 OP_10 = 0x5a,
50 OP_11 = 0x5b,
51 OP_12 = 0x5c,
52 OP_13 = 0x5d,
53 OP_14 = 0x5e,
54 OP_15 = 0x5f,
55 OP_16 = 0x60,
57 // control
58 OP_NOP = 0x61,
59 OP_VER = 0x62,
60 OP_IF = 0x63,
61 OP_NOTIF = 0x64,
62 OP_VERIF = 0x65,
63 OP_VERNOTIF = 0x66,
64 OP_ELSE = 0x67,
65 OP_ENDIF = 0x68,
66 OP_VERIFY = 0x69,
67 OP_RETURN = 0x6a,
69 // stack ops
70 OP_TOALTSTACK = 0x6b,
71 OP_FROMALTSTACK = 0x6c,
72 OP_2DROP = 0x6d,
73 OP_2DUP = 0x6e,
74 OP_3DUP = 0x6f,
75 OP_2OVER = 0x70,
76 OP_2ROT = 0x71,
77 OP_2SWAP = 0x72,
78 OP_IFDUP = 0x73,
79 OP_DEPTH = 0x74,
80 OP_DROP = 0x75,
81 OP_DUP = 0x76,
82 OP_NIP = 0x77,
83 OP_OVER = 0x78,
84 OP_PICK = 0x79,
85 OP_ROLL = 0x7a,
86 OP_ROT = 0x7b,
87 OP_SWAP = 0x7c,
88 OP_TUCK = 0x7d,
90 // splice ops
91 OP_CAT = 0x7e,
92 OP_SUBSTR = 0x7f,
93 OP_LEFT = 0x80,
94 OP_RIGHT = 0x81,
95 OP_SIZE = 0x82,
97 // bit logic
98 OP_INVERT = 0x83,
99 OP_AND = 0x84,
100 OP_OR = 0x85,
101 OP_XOR = 0x86,
102 OP_EQUAL = 0x87,
103 OP_EQUALVERIFY = 0x88,
104 OP_RESERVED1 = 0x89,
105 OP_RESERVED2 = 0x8a,
107 // numeric
108 OP_1ADD = 0x8b,
109 OP_1SUB = 0x8c,
110 OP_2MUL = 0x8d,
111 OP_2DIV = 0x8e,
112 OP_NEGATE = 0x8f,
113 OP_ABS = 0x90,
114 OP_NOT = 0x91,
115 OP_0NOTEQUAL = 0x92,
117 OP_ADD = 0x93,
118 OP_SUB = 0x94,
119 OP_MUL = 0x95,
120 OP_DIV = 0x96,
121 OP_MOD = 0x97,
122 OP_LSHIFT = 0x98,
123 OP_RSHIFT = 0x99,
125 OP_BOOLAND = 0x9a,
126 OP_BOOLOR = 0x9b,
127 OP_NUMEQUAL = 0x9c,
128 OP_NUMEQUALVERIFY = 0x9d,
129 OP_NUMNOTEQUAL = 0x9e,
130 OP_LESSTHAN = 0x9f,
131 OP_GREATERTHAN = 0xa0,
132 OP_LESSTHANOREQUAL = 0xa1,
133 OP_GREATERTHANOREQUAL = 0xa2,
134 OP_MIN = 0xa3,
135 OP_MAX = 0xa4,
137 OP_WITHIN = 0xa5,
139 // crypto
140 OP_RIPEMD160 = 0xa6,
141 OP_SHA1 = 0xa7,
142 OP_SHA256 = 0xa8,
143 OP_HASH160 = 0xa9,
144 OP_HASH256 = 0xaa,
145 OP_CODESEPARATOR = 0xab,
146 OP_CHECKSIG = 0xac,
147 OP_CHECKSIGVERIFY = 0xad,
148 OP_CHECKMULTISIG = 0xae,
149 OP_CHECKMULTISIGVERIFY = 0xaf,
151 // expansion
152 OP_NOP1 = 0xb0,
153 OP_CHECKLOCKTIMEVERIFY = 0xb1,
154 OP_NOP2 = OP_CHECKLOCKTIMEVERIFY,
155 OP_CHECKSEQUENCEVERIFY = 0xb2,
156 OP_NOP3 = OP_CHECKSEQUENCEVERIFY,
157 OP_NOP4 = 0xb3,
158 OP_NOP5 = 0xb4,
159 OP_NOP6 = 0xb5,
160 OP_NOP7 = 0xb6,
161 OP_NOP8 = 0xb7,
162 OP_NOP9 = 0xb8,
163 OP_NOP10 = 0xb9,
166 MAX_OPCODE = OP_NOP10, // maximum value that an opcode can be
168 // template matching params
169 OP_SMALLINTEGER = 0xfa,
170 OP_PUBKEYS = 0xfb,
171 OP_PUBKEYHASH = 0xfd,
172 OP_PUBKEY = 0xfe,
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);
204 return 1;
208 string btsDecodeOne (const(ubyte)[] code) {
209 import std.format : format;
210 if (code.length == 0) return null;
211 auto anchor = code;
212 auto opc = code[0];
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);
217 if (opclen > 1) {
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);
221 return res;
223 foreach (string name; __traits(allMembers, OpCode)) {
224 if (opc == __traits(getMember, OpCode, name)) return name[3..$];
226 return "UNKNOWN";