1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "core_io.h"
#include "core/transaction.h"
#include "script/script.h"
#include "serialize.h"
#include "streams.h"
#include "univalue/univalue.h"
#include "util.h"
#include "utilstrencodings.h"
#include "version.h"
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/assign/list_of.hpp>
using namespace boost;
using namespace boost::algorithm;
using namespace std;
CScript ParseScript(std::string s)
{
CScript result;
static map<string, opcodetype> mapOpNames;
if (mapOpNames.empty())
{
for (int op = 0; op <= OP_NOP10; op++)
{
// Allow OP_RESERVED to get into mapOpNames
if (op < OP_NOP && op != OP_RESERVED)
continue;
const char* name = GetOpName((opcodetype)op);
if (strcmp(name, "OP_UNKNOWN") == 0)
continue;
string strName(name);
mapOpNames[strName] = (opcodetype)op;
// Convenience: OP_ADD and just ADD are both recognized:
replace_first(strName, "OP_", "");
mapOpNames[strName] = (opcodetype)op;
}
}
vector<string> words;
split(words, s, is_any_of(" \t\n"), token_compress_on);
for (std::vector<std::string>::const_iterator w = words.begin(); w != words.end(); ++w)
{
if (w->empty())
{
// Empty string, ignore. (boost::split given '' will return one word)
}
else if (all(*w, is_digit()) ||
(starts_with(*w, "-") && all(string(w->begin()+1, w->end()), is_digit())))
{
// Number
int64_t n = atoi64(*w);
result << n;
}
else if (starts_with(*w, "0x") && (w->begin()+2 != w->end()) && IsHex(string(w->begin()+2, w->end())))
{
// Raw hex data, inserted NOT pushed onto stack:
std::vector<unsigned char> raw = ParseHex(string(w->begin()+2, w->end()));
result.insert(result.end(), raw.begin(), raw.end());
}
else if (w->size() >= 2 && starts_with(*w, "'") && ends_with(*w, "'"))
{
// Single-quoted string, pushed as data. NOTE: this is poor-man's
// parsing, spaces/tabs/newlines in single-quoted strings won't work.
std::vector<unsigned char> value(w->begin()+1, w->end()-1);
result << value;
}
else if (mapOpNames.count(*w))
{
// opcode, e.g. OP_ADD or ADD:
result << mapOpNames[*w];
}
else
{
throw runtime_error("script parse error");
}
}
return result;
}
bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx)
{
if (!IsHex(strHexTx))
return false;
vector<unsigned char> txData(ParseHex(strHexTx));
CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
try {
ssData >> tx;
}
catch (const std::exception &) {
return false;
}
return true;
}
uint256 ParseHashUV(const UniValue& v, const string& strName)
{
string strHex;
if (v.isStr())
strHex = v.getValStr();
if (!IsHex(strHex)) // Note: IsHex("") is false
throw runtime_error(strName+" must be hexadecimal string (not '"+strHex+"')");
uint256 result;
result.SetHex(strHex);
return result;
}
vector<unsigned char> ParseHexUV(const UniValue& v, const string& strName)
{
string strHex;
if (v.isStr())
strHex = v.getValStr();
if (!IsHex(strHex))
throw runtime_error(strName+" must be hexadecimal string (not '"+strHex+"')");
return ParseHex(strHex);
}
|