Changeset View
Changeset View
Standalone View
Standalone View
src/script/script.h
Show All 25 Lines | |||||
static const int MAX_OPS_PER_SCRIPT = 201; | static const int MAX_OPS_PER_SCRIPT = 201; | ||||
// Maximum number of public keys per multisig | // Maximum number of public keys per multisig | ||||
static const int MAX_PUBKEYS_PER_MULTISIG = 20; | static const int MAX_PUBKEYS_PER_MULTISIG = 20; | ||||
// Maximum script length in bytes | // Maximum script length in bytes | ||||
static const int MAX_SCRIPT_SIZE = 10000; | static const int MAX_SCRIPT_SIZE = 10000; | ||||
// Default maximum element size for conversion to a CScriptNum | |||||
static const int DEFAULT_MAX_NUM_BYTES = 4; | |||||
// Threshold for nLockTime: below this value it is interpreted as block number, | // Threshold for nLockTime: below this value it is interpreted as block number, | ||||
// otherwise as UNIX timestamp. Thresold is Tue Nov 5 00:53:20 1985 UTC | // otherwise as UNIX timestamp. Thresold is Tue Nov 5 00:53:20 1985 UTC | ||||
static const unsigned int LOCKTIME_THRESHOLD = 500000000; | static const unsigned int LOCKTIME_THRESHOLD = 500000000; | ||||
template <typename T> std::vector<uint8_t> ToByteVector(const T &in) { | template <typename T> std::vector<uint8_t> ToByteVector(const T &in) { | ||||
return std::vector<uint8_t>(in.begin(), in.end()); | return std::vector<uint8_t>(in.begin(), in.end()); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 141 Lines • ▼ Show 20 Lines | enum opcodetype { | ||||
OP_PUBKEYS = 0xfb, | OP_PUBKEYS = 0xfb, | ||||
OP_PUBKEYHASH = 0xfd, | OP_PUBKEYHASH = 0xfd, | ||||
OP_PUBKEY = 0xfe, | OP_PUBKEY = 0xfe, | ||||
OP_INVALIDOPCODE = 0xff, | OP_INVALIDOPCODE = 0xff, | ||||
}; | }; | ||||
const char *GetOpName(opcodetype opcode); | const char *GetOpName(opcodetype opcode); | ||||
bool IsMinimalArray(const std::vector<uint8_t> &vch, | |||||
const size_t nMaxNumSize = DEFAULT_MAX_NUM_BYTES); | |||||
std::vector<uint8_t> MinimalizeBigEndianArray(const std::vector<uint8_t> &data); | std::vector<uint8_t> MinimalizeBigEndianArray(const std::vector<uint8_t> &data); | ||||
class scriptnum_error : public std::runtime_error { | class scriptnum_error : public std::runtime_error { | ||||
public: | public: | ||||
explicit scriptnum_error(const std::string &str) | explicit scriptnum_error(const std::string &str) | ||||
: std::runtime_error(str) {} | : std::runtime_error(str) {} | ||||
}; | }; | ||||
class CScriptNum { | class CScriptNum { | ||||
/** | /** | ||||
* Numeric opcodes (OP_1ADD, etc) are restricted to operating on 4-byte | * Numeric opcodes (OP_1ADD, etc) are restricted to operating on 4-byte | ||||
* integers. The semantics are subtle, though: operands must be in the range | * integers. The semantics are subtle, though: operands must be in the range | ||||
* [-2^31 +1...2^31 -1], but results may overflow (and are valid as long as | * [-2^31 +1...2^31 -1], but results may overflow (and are valid as long as | ||||
* they are not used in a subsequent numeric operation). CScriptNum enforces | * they are not used in a subsequent numeric operation). CScriptNum enforces | ||||
* those semantics by storing results as an int64 and allowing out-of-range | * those semantics by storing results as an int64 and allowing out-of-range | ||||
* values to be returned as a vector of bytes but throwing an exception if | * values to be returned as a vector of bytes but throwing an exception if | ||||
* arithmetic is done or the result is interpreted as an integer. | * arithmetic is done or the result is interpreted as an integer. | ||||
*/ | */ | ||||
public: | public: | ||||
static const size_t MAXIMUM_ELEMENT_SIZE = 4; | |||||
explicit CScriptNum(const int64_t &n) { m_value = n; } | explicit CScriptNum(const int64_t &n) { m_value = n; } | ||||
explicit CScriptNum(const std::vector<uint8_t> &vch, bool fRequireMinimal, | explicit CScriptNum(const std::vector<uint8_t> &vch, bool fRequireMinimal, | ||||
const size_t nMaxNumSize = DEFAULT_MAX_NUM_BYTES) { | const size_t nMaxNumSize = MAXIMUM_ELEMENT_SIZE) { | ||||
if (vch.size() > nMaxNumSize) { | if (vch.size() > nMaxNumSize) { | ||||
throw scriptnum_error("script number overflow"); | throw scriptnum_error("script number overflow"); | ||||
} | } | ||||
if (fRequireMinimal && !IsMinimalArray(vch, nMaxNumSize)) { | if (fRequireMinimal && !IsMinimallyEncoded(vch, nMaxNumSize)) { | ||||
throw scriptnum_error("non-minimally encoded script number"); | throw scriptnum_error("non-minimally encoded script number"); | ||||
} | } | ||||
m_value = set_vch(vch); | m_value = set_vch(vch); | ||||
} | } | ||||
static bool IsMinimallyEncoded( | |||||
const std::vector<uint8_t> &vch, | |||||
const size_t nMaxNumSize = CScriptNum::MAXIMUM_ELEMENT_SIZE); | |||||
inline bool operator==(const int64_t &rhs) const { return m_value == rhs; } | inline bool operator==(const int64_t &rhs) const { return m_value == rhs; } | ||||
inline bool operator!=(const int64_t &rhs) const { return m_value != rhs; } | inline bool operator!=(const int64_t &rhs) const { return m_value != rhs; } | ||||
inline bool operator<=(const int64_t &rhs) const { return m_value <= rhs; } | inline bool operator<=(const int64_t &rhs) const { return m_value <= rhs; } | ||||
inline bool operator<(const int64_t &rhs) const { return m_value < rhs; } | inline bool operator<(const int64_t &rhs) const { return m_value < rhs; } | ||||
inline bool operator>=(const int64_t &rhs) const { return m_value >= rhs; } | inline bool operator>=(const int64_t &rhs) const { return m_value >= rhs; } | ||||
inline bool operator>(const int64_t &rhs) const { return m_value > rhs; } | inline bool operator>(const int64_t &rhs) const { return m_value > rhs; } | ||||
inline bool operator==(const CScriptNum &rhs) const { | inline bool operator==(const CScriptNum &rhs) const { | ||||
▲ Show 20 Lines • Show All 405 Lines • Show Last 20 Lines |