41 std::vector<unsigned char> CheckedParseHex(
const std::string& str)
43 if (str.size() && !
IsHex(str))
throw std::runtime_error(
"Non-hex input '" + str +
"'");
49 std::vector<unsigned char> data = CheckedParseHex(str);
50 return CScript(data.begin(), data.end());
58 }
catch (
const std::ios_base::failure&) {
59 throw std::runtime_error(
"Tx deserialization failure");
66 if (!univalue.
isArray())
throw std::runtime_error(
"Prevouts must be array");
67 std::vector<CTxOut> prevouts;
68 for (
size_t i = 0; i < univalue.
size(); ++i) {
71 SpanReader{CheckedParseHex(univalue[i].get_str())} >> txout;
72 }
catch (
const std::ios_base::failure&) {
73 throw std::runtime_error(
"Prevout invalid format");
75 prevouts.push_back(std::move(txout));
82 if (!univalue.
isArray())
throw std::runtime_error(
"Script witness is not array");
84 for (
size_t i = 0; i < univalue.
size(); ++i) {
85 auto bytes = CheckedParseHex(univalue[i].get_str());
86 scriptwitness.
stack.push_back(std::move(bytes));
91 const std::map<std::string, unsigned int> FLAG_NAMES = {
101 std::vector<unsigned int> AllFlags()
103 std::vector<unsigned int>
ret;
105 for (
unsigned int i = 0; i < 128; ++i) {
106 unsigned int flag = 0;
126 const std::vector<unsigned int> ALL_FLAGS = AllFlags();
130 if (str.empty())
return 0;
132 unsigned int flags = 0;
133 std::vector<std::string> words =
SplitString(str,
',');
135 for (
const std::string& word : words) {
136 auto it = FLAG_NAMES.find(word);
137 if (it == FLAG_NAMES.end())
throw std::runtime_error(
"Unknown verification flag " + word);
144 void Test(
const std::string& str)
147 if (!test.
read(str) || !test.
isObject())
throw std::runtime_error(
"Non-object test input");
150 const std::vector<CTxOut> prevouts =
TxOutsFromJSON(test[
"prevouts"]);
151 if (prevouts.size() != tx.
vin.size())
throw std::runtime_error(
"Incorrect number of prevouts");
152 size_t idx = test[
"index"].
getInt<int64_t>();
153 if (idx >= tx.
vin.size())
throw std::runtime_error(
"Invalid index");
157 if (test.
exists(
"success")) {
158 tx.
vin[idx].scriptSig =
ScriptFromHex(test[
"success"][
"scriptSig"].get_str());
161 txdata.
Init(tx, std::vector<CTxOut>(prevouts));
163 for (
const auto flags : ALL_FLAGS) {
166 if (
final || ((
flags & test_flags) ==
flags)) {
167 (void)
VerifyScript(tx.
vin[idx].scriptSig, prevouts[idx].scriptPubKey, &tx.
vin[idx].scriptWitness,
flags, txcheck,
nullptr);
172 if (test.
exists(
"failure")) {
173 tx.
vin[idx].scriptSig =
ScriptFromHex(test[
"failure"][
"scriptSig"].get_str());
176 txdata.
Init(tx, std::vector<CTxOut>(prevouts));
178 for (
const auto flags : ALL_FLAGS) {
180 if ((
flags & test_flags) == test_flags) {
181 (void)
VerifyScript(tx.
vin[idx].scriptSig, prevouts[idx].scriptPubKey, &tx.
vin[idx].scriptWitness,
flags, txcheck,
nullptr);
189 FUZZ_TARGET(script_assets_test_minimizer, .
init = test_init, .hidden =
true)
191 if (buffer.size() < 2 || buffer.back() !=
'\n' || buffer[buffer.size() - 2] !=
',')
return;
192 const std::string str((
const char*)buffer.data(), buffer.size() - 2);
195 }
catch (
const std::runtime_error&) {
Serialized script, used inside transaction inputs and outputs.
An output of a transaction.
Minimal stream for reading from an existing byte array by Span.
bool read(std::string_view raw)
bool exists(const std::string &key) const
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
@ SCRIPT_VERIFY_NULLDUMMY
@ SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY
@ SCRIPT_VERIFY_CHECKSEQUENCEVERIFY
@ ASSERT_FAIL
Abort execution through assertion failure (for consensus code)
static constexpr TransactionSerParams TX_NO_WITNESS
static CScript ScriptFromHex(const std::string &str)
static CMutableTransaction TxFromHex(const std::string &str)
unsigned int ParseScriptFlags(std::string strFlags)
static CScriptWitness ScriptWitnessFromJSON(const UniValue &univalue)
static std::vector< CTxOut > TxOutsFromJSON(const UniValue &univalue)
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
std::vector< std::string > SplitString(std::string_view str, char sep)
A mutable version of CTransaction.
std::vector< std::vector< unsigned char > > stack
void Init(const T &tx, std::vector< CTxOut > &&spent_outputs, bool force=false)
Initialize this PrecomputedTransactionData with transaction data.
bool IsHex(std::string_view str)