6
6
#ifndef H_BITCOIN_SCRIPT
7
7
#define H_BITCOIN_SCRIPT
8
8
9
- #include " bignum.h"
10
9
#include " key.h"
11
10
#include " util.h"
12
11
@@ -25,6 +24,155 @@ class CTransaction;
25
24
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520 ; // bytes
26
25
static const unsigned int MAX_OP_RETURN_RELAY = 40 ; // bytes
27
26
27
+ class scriptnum_error : public std ::runtime_error
28
+ {
29
+ public:
30
+ explicit scriptnum_error (const std::string& str) : std::runtime_error(str) {}
31
+ };
32
+
33
+ class CScriptNum
34
+ {
35
+ // Numeric opcodes (OP_1ADD, etc) are restricted to operating on 4-byte integers.
36
+ // The semantics are subtle, though: operands must be in the range [-2^31 +1...2^31 -1],
37
+ // but results may overflow (and are valid as long as they are not used in a subsequent
38
+ // numeric operation). CScriptNum enforces those semantics by storing results as
39
+ // an int64 and allowing out-of-range values to be returned as a vector of bytes but
40
+ // throwing an exception if arithmetic is done or the result is interpreted as an integer.
41
+ public:
42
+
43
+ explicit CScriptNum (const int64_t & n)
44
+ {
45
+ m_value = n;
46
+ }
47
+
48
+ explicit CScriptNum (const std::vector<unsigned char >& vch)
49
+ {
50
+ if (vch.size () > nMaxNumSize)
51
+ throw scriptnum_error (" CScriptNum(const std::vector<unsigned char>&) : overflow" );
52
+ m_value = set_vch (vch);
53
+ }
54
+
55
+ inline bool operator ==(const int64_t & rhs) const { return m_value == rhs; }
56
+ inline bool operator !=(const int64_t & rhs) const { return m_value != rhs; }
57
+ inline bool operator <=(const int64_t & rhs) const { return m_value <= rhs; }
58
+ inline bool operator < (const int64_t & rhs) const { return m_value < rhs; }
59
+ inline bool operator >=(const int64_t & rhs) const { return m_value >= rhs; }
60
+ inline bool operator > (const int64_t & rhs) const { return m_value > rhs; }
61
+
62
+ inline bool operator ==(const CScriptNum& rhs) const { return operator ==(rhs.m_value ); }
63
+ inline bool operator !=(const CScriptNum& rhs) const { return operator !=(rhs.m_value ); }
64
+ inline bool operator <=(const CScriptNum& rhs) const { return operator <=(rhs.m_value ); }
65
+ inline bool operator < (const CScriptNum& rhs) const { return operator < (rhs.m_value ); }
66
+ inline bool operator >=(const CScriptNum& rhs) const { return operator >=(rhs.m_value ); }
67
+ inline bool operator > (const CScriptNum& rhs) const { return operator > (rhs.m_value ); }
68
+
69
+ inline CScriptNum operator +( const int64_t & rhs) const { return CScriptNum (m_value + rhs);}
70
+ inline CScriptNum operator -( const int64_t & rhs) const { return CScriptNum (m_value - rhs);}
71
+ inline CScriptNum operator +( const CScriptNum& rhs) const { return operator +(rhs.m_value ); }
72
+ inline CScriptNum operator -( const CScriptNum& rhs) const { return operator -(rhs.m_value ); }
73
+
74
+ inline CScriptNum& operator +=( const CScriptNum& rhs) { return operator +=(rhs.m_value ); }
75
+ inline CScriptNum& operator -=( const CScriptNum& rhs) { return operator -=(rhs.m_value ); }
76
+
77
+ inline CScriptNum operator -() const
78
+ {
79
+ assert (m_value != std::numeric_limits<int64_t >::min ());
80
+ return CScriptNum (-m_value);
81
+ }
82
+
83
+ inline CScriptNum& operator =( const int64_t & rhs)
84
+ {
85
+ m_value = rhs;
86
+ return *this ;
87
+ }
88
+
89
+ inline CScriptNum& operator +=( const int64_t & rhs)
90
+ {
91
+ assert (rhs == 0 || (rhs > 0 && m_value <= std::numeric_limits<int64_t >::max () - rhs) ||
92
+ (rhs < 0 && m_value >= std::numeric_limits<int64_t >::min () - rhs));
93
+ m_value += rhs;
94
+ return *this ;
95
+ }
96
+
97
+ inline CScriptNum& operator -=( const int64_t & rhs)
98
+ {
99
+ assert (rhs == 0 || (rhs > 0 && m_value >= std::numeric_limits<int64_t >::min () + rhs) ||
100
+ (rhs < 0 && m_value <= std::numeric_limits<int64_t >::max () + rhs));
101
+ m_value -= rhs;
102
+ return *this ;
103
+ }
104
+
105
+ int getint () const
106
+ {
107
+ if (m_value > std::numeric_limits<int >::max ())
108
+ return std::numeric_limits<int >::max ();
109
+ else if (m_value < std::numeric_limits<int >::min ())
110
+ return std::numeric_limits<int >::min ();
111
+ return m_value;
112
+ }
113
+
114
+ std::vector<unsigned char > getvch () const
115
+ {
116
+ return serialize (m_value);
117
+ }
118
+
119
+ static std::vector<unsigned char > serialize (const int64_t & value)
120
+ {
121
+ if (value == 0 )
122
+ return std::vector<unsigned char >();
123
+
124
+ std::vector<unsigned char > result;
125
+ const bool neg = value < 0 ;
126
+ uint64_t absvalue = neg ? -value : value;
127
+
128
+ while (absvalue)
129
+ {
130
+ result.push_back (absvalue & 0xff );
131
+ absvalue >>= 8 ;
132
+ }
133
+
134
+
135
+ // - If the most significant byte is >= 0x80 and the value is positive, push a
136
+ // new zero-byte to make the significant byte < 0x80 again.
137
+
138
+ // - If the most significant byte is >= 0x80 and the value is negative, push a
139
+ // new 0x80 byte that will be popped off when converting to an integral.
140
+
141
+ // - If the most significant byte is < 0x80 and the value is negative, add
142
+ // 0x80 to it, since it will be subtracted and interpreted as a negative when
143
+ // converting to an integral.
144
+
145
+ if (result.back () & 0x80 )
146
+ result.push_back (neg ? 0x80 : 0 );
147
+ else if (neg)
148
+ result.back () |= 0x80 ;
149
+
150
+ return result;
151
+ }
152
+
153
+ static const size_t nMaxNumSize = 4 ;
154
+
155
+ private:
156
+ static int64_t set_vch (const std::vector<unsigned char >& vch)
157
+ {
158
+ if (vch.empty ())
159
+ return 0 ;
160
+
161
+ int64_t result = 0 ;
162
+ for (size_t i = 0 ; i != vch.size (); ++i)
163
+ result |= static_cast <int64_t >(vch[i]) << 8 *i;
164
+
165
+ // If the input vector's most significant byte is 0x80, remove it from
166
+ // the result's msb and return a negative.
167
+ if (vch.back () & 0x80 )
168
+ return -(result & ~(0x80 << (8 * (vch.size () - 1 ))));
169
+
170
+ return result;
171
+ }
172
+
173
+ int64_t m_value;
174
+ };
175
+
28
176
/* * Signature hash types/flags */
29
177
enum
30
178
{
@@ -225,7 +373,7 @@ const char* GetOpName(opcodetype opcode);
225
373
inline std::string ValueString (const std::vector<unsigned char >& vch)
226
374
{
227
375
if (vch.size () <= 4 )
228
- return strprintf (" %d" , CBigNum (vch).getint ());
376
+ return strprintf (" %d" , CScriptNum (vch).getint ());
229
377
else
230
378
return HexStr (vch);
231
379
}
@@ -261,26 +409,10 @@ class CScript : public std::vector<unsigned char>
261
409
}
262
410
else
263
411
{
264
- CBigNum bn (n);
265
- *this << bn.getvch ();
412
+ *this << CScriptNum::serialize (n);
266
413
}
267
414
return *this ;
268
415
}
269
-
270
- CScript& push_uint64 (uint64_t n)
271
- {
272
- if (n >= 1 && n <= 16 )
273
- {
274
- push_back (n + (OP_1 - 1 ));
275
- }
276
- else
277
- {
278
- CBigNum bn (n);
279
- *this << bn.getvch ();
280
- }
281
- return *this ;
282
- }
283
-
284
416
public:
285
417
CScript () { }
286
418
CScript (const CScript& b) : std::vector<unsigned char >(b.begin(), b.end()) { }
@@ -303,35 +435,15 @@ class CScript : public std::vector<unsigned char>
303
435
}
304
436
305
437
306
- // explicit CScript(char b) is not portable. Use 'signed char' or 'unsigned char'.
307
- explicit CScript (signed char b) { operator <<(b); }
308
- explicit CScript (short b) { operator <<(b); }
309
- explicit CScript (int b) { operator <<(b); }
310
- explicit CScript (long b) { operator <<(b); }
311
- explicit CScript (long long b) { operator <<(b); }
312
- explicit CScript (unsigned char b) { operator <<(b); }
313
- explicit CScript (unsigned int b) { operator <<(b); }
314
- explicit CScript (unsigned short b) { operator <<(b); }
315
- explicit CScript (unsigned long b) { operator <<(b); }
316
- explicit CScript (unsigned long long b) { operator <<(b); }
438
+ CScript (int64_t b) { operator <<(b); }
317
439
318
440
explicit CScript (opcodetype b) { operator <<(b); }
319
441
explicit CScript (const uint256& b) { operator <<(b); }
320
- explicit CScript (const CBigNum & b) { operator <<(b); }
442
+ explicit CScript (const CScriptNum & b) { operator <<(b); }
321
443
explicit CScript (const std::vector<unsigned char >& b) { operator <<(b); }
322
444
323
445
324
- // CScript& operator<<(char b) is not portable. Use 'signed char' or 'unsigned char'.
325
- CScript& operator <<(signed char b) { return push_int64 (b); }
326
- CScript& operator <<(short b) { return push_int64 (b); }
327
- CScript& operator <<(int b) { return push_int64 (b); }
328
- CScript& operator <<(long b) { return push_int64 (b); }
329
- CScript& operator <<(long long b) { return push_int64 (b); }
330
- CScript& operator <<(unsigned char b) { return push_uint64 (b); }
331
- CScript& operator <<(unsigned int b) { return push_uint64 (b); }
332
- CScript& operator <<(unsigned short b) { return push_uint64 (b); }
333
- CScript& operator <<(unsigned long b) { return push_uint64 (b); }
334
- CScript& operator <<(unsigned long long b) { return push_uint64 (b); }
446
+ CScript& operator <<(int64_t b) { return push_int64 (b); }
335
447
336
448
CScript& operator <<(opcodetype opcode)
337
449
{
@@ -363,7 +475,7 @@ class CScript : public std::vector<unsigned char>
363
475
return *this ;
364
476
}
365
477
366
- CScript& operator <<(const CBigNum & b)
478
+ CScript& operator <<(const CScriptNum & b)
367
479
{
368
480
*this << b.getvch ();
369
481
return *this ;
0 commit comments