| 222 | }; |
| 223 | |
| 224 | class CScriptNum { |
| 225 | /** |
| 226 | * Numeric opcodes (OP_1ADD, etc) are restricted to operating on 4-byte |
| 227 | * integers. The semantics are subtle, though: operands must be in the range |
| 228 | * [-2^31 +1...2^31 -1], but results may overflow (and are valid as long as |
| 229 | * they are not used in a subsequent numeric operation). CScriptNum enforces |
| 230 | * those semantics by storing results as an int64 and allowing out-of-range |
| 231 | * values to be returned as a vector of bytes but throwing an exception if |
| 232 | * arithmetic is done or the result is interpreted as an integer. |
| 233 | */ |
| 234 | public: |
| 235 | explicit CScriptNum(const int64_t &n) { m_value = n; } |
| 236 | |
| 237 | explicit CScriptNum(const std::vector<uint8_t> &vch, bool fRequireMinimal, |
| 238 | const size_t nMaxNumSize) { |
| 239 | if (vch.size() > nMaxNumSize) { |
| 240 | throw scriptnum_overflow_error("script number overflow"); |
| 241 | } |
| 242 | if (fRequireMinimal && !IsMinimallyEncoded(vch, nMaxNumSize)) { |
| 243 | throw scriptnum_encoding_error( |
| 244 | "non-minimally encoded script number"); |
| 245 | } |
| 246 | m_value = set_vch(vch); |
| 247 | } |
| 248 | |
| 249 | static bool IsMinimallyEncoded(const std::vector<uint8_t> &vch, |
| 250 | const size_t nMaxNumSize); |
| 251 | |
| 252 | static bool MinimallyEncode(std::vector<uint8_t> &data); |
| 253 | |
| 254 | inline bool operator==(const int64_t &rhs) const { return m_value == rhs; } |
| 255 | inline bool operator!=(const int64_t &rhs) const { return m_value != rhs; } |
| 256 | inline bool operator<=(const int64_t &rhs) const { return m_value <= rhs; } |
| 257 | inline bool operator<(const int64_t &rhs) const { return m_value < rhs; } |
| 258 | inline bool operator>=(const int64_t &rhs) const { return m_value >= rhs; } |
| 259 | inline bool operator>(const int64_t &rhs) const { return m_value > rhs; } |
| 260 | |
| 261 | inline bool operator==(const CScriptNum &rhs) const { |
| 262 | return operator==(rhs.m_value); |
| 263 | } |
| 264 | inline bool operator!=(const CScriptNum &rhs) const { |
| 265 | return operator!=(rhs.m_value); |
| 266 | } |
| 267 | inline bool operator<=(const CScriptNum &rhs) const { |
| 268 | return operator<=(rhs.m_value); |
| 269 | } |
| 270 | inline bool operator<(const CScriptNum &rhs) const { |
| 271 | return operator<(rhs.m_value); |
| 272 | } |
| 273 | inline bool operator>=(const CScriptNum &rhs) const { |
| 274 | return operator>=(rhs.m_value); |
| 275 | } |
| 276 | inline bool operator>(const CScriptNum &rhs) const { |
| 277 | return operator>(rhs.m_value); |
| 278 | } |
| 279 | |
| 280 | inline CScriptNum operator+(const int64_t &rhs) const { |
| 281 | int64_t result; |
no outgoing calls