Bitcoin Core  27.99.0
P2P Digital Currency
script_standard_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017-2022 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <test/data/bip341_wallet_vectors.json.h>
6 
7 #include <key.h>
8 #include <key_io.h>
9 #include <script/script.h>
10 #include <script/signingprovider.h>
11 #include <script/solver.h>
12 #include <test/util/setup_common.h>
13 #include <util/strencodings.h>
14 
15 #include <boost/test/unit_test.hpp>
16 
17 #include <univalue.h>
18 
19 
20 BOOST_FIXTURE_TEST_SUITE(script_standard_tests, BasicTestingSetup)
21 
22 BOOST_AUTO_TEST_CASE(dest_default_is_no_dest)
23 {
24  CTxDestination dest;
26 }
27 
28 BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
29 {
30  CKey keys[3];
31  CPubKey pubkeys[3];
32  for (int i = 0; i < 3; i++) {
33  keys[i].MakeNewKey(true);
34  pubkeys[i] = keys[i].GetPubKey();
35  }
36 
37  CScript s;
38  std::vector<std::vector<unsigned char> > solutions;
39 
40  // TxoutType::PUBKEY
41  s.clear();
42  s << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
44  BOOST_CHECK_EQUAL(solutions.size(), 1U);
45  BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0]));
46 
47  // TxoutType::PUBKEYHASH
48  s.clear();
49  s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
51  BOOST_CHECK_EQUAL(solutions.size(), 1U);
52  BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID()));
53 
54  // TxoutType::SCRIPTHASH
55  CScript redeemScript(s); // initialize with leftover P2PKH script
56  s.clear();
57  s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
59  BOOST_CHECK_EQUAL(solutions.size(), 1U);
60  BOOST_CHECK(solutions[0] == ToByteVector(CScriptID(redeemScript)));
61 
62  // TxoutType::MULTISIG
63  s.clear();
64  s << OP_1 <<
65  ToByteVector(pubkeys[0]) <<
66  ToByteVector(pubkeys[1]) <<
69  BOOST_CHECK_EQUAL(solutions.size(), 4U);
70  BOOST_CHECK(solutions[0] == std::vector<unsigned char>({1}));
71  BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0]));
72  BOOST_CHECK(solutions[2] == ToByteVector(pubkeys[1]));
73  BOOST_CHECK(solutions[3] == std::vector<unsigned char>({2}));
74 
75  s.clear();
76  s << OP_2 <<
77  ToByteVector(pubkeys[0]) <<
78  ToByteVector(pubkeys[1]) <<
79  ToByteVector(pubkeys[2]) <<
82  BOOST_CHECK_EQUAL(solutions.size(), 5U);
83  BOOST_CHECK(solutions[0] == std::vector<unsigned char>({2}));
84  BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0]));
85  BOOST_CHECK(solutions[2] == ToByteVector(pubkeys[1]));
86  BOOST_CHECK(solutions[3] == ToByteVector(pubkeys[2]));
87  BOOST_CHECK(solutions[4] == std::vector<unsigned char>({3}));
88 
89  // TxoutType::NULL_DATA
90  s.clear();
91  s << OP_RETURN <<
92  std::vector<unsigned char>({0}) <<
93  std::vector<unsigned char>({75}) <<
94  std::vector<unsigned char>({255});
96  BOOST_CHECK_EQUAL(solutions.size(), 0U);
97 
98  // TxoutType::WITNESS_V0_KEYHASH
99  s.clear();
100  s << OP_0 << ToByteVector(pubkeys[0].GetID());
102  BOOST_CHECK_EQUAL(solutions.size(), 1U);
103  BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID()));
104 
105  // TxoutType::WITNESS_V0_SCRIPTHASH
106  uint256 scriptHash;
107  CSHA256().Write(redeemScript.data(), redeemScript.size())
108  .Finalize(scriptHash.begin());
109 
110  s.clear();
111  s << OP_0 << ToByteVector(scriptHash);
113  BOOST_CHECK_EQUAL(solutions.size(), 1U);
114  BOOST_CHECK(solutions[0] == ToByteVector(scriptHash));
115 
116  // TxoutType::WITNESS_V1_TAPROOT
117  s.clear();
120  BOOST_CHECK_EQUAL(solutions.size(), 1U);
121  BOOST_CHECK(solutions[0] == ToByteVector(uint256::ZERO));
122 
123  // TxoutType::WITNESS_UNKNOWN
124  s.clear();
127  BOOST_CHECK_EQUAL(solutions.size(), 2U);
128  BOOST_CHECK(solutions[0] == std::vector<unsigned char>{16});
129  BOOST_CHECK(solutions[1] == ToByteVector(uint256::ONE));
130 
131  // TxoutType::NONSTANDARD
132  s.clear();
133  s << OP_9 << OP_ADD << OP_11 << OP_EQUAL;
135 }
136 
137 BOOST_AUTO_TEST_CASE(script_standard_Solver_failure)
138 {
139  CKey key = GenerateRandomKey();
140  CPubKey pubkey = key.GetPubKey();
141 
142  CScript s;
143  std::vector<std::vector<unsigned char> > solutions;
144 
145  // TxoutType::PUBKEY with incorrectly sized pubkey
146  s.clear();
147  s << std::vector<unsigned char>(30, 0x01) << OP_CHECKSIG;
149 
150  // TxoutType::PUBKEYHASH with incorrectly sized key hash
151  s.clear();
152  s << OP_DUP << OP_HASH160 << ToByteVector(pubkey) << OP_EQUALVERIFY << OP_CHECKSIG;
154 
155  // TxoutType::SCRIPTHASH with incorrectly sized script hash
156  s.clear();
157  s << OP_HASH160 << std::vector<unsigned char>(21, 0x01) << OP_EQUAL;
159 
160  // TxoutType::MULTISIG 0/2
161  s.clear();
162  s << OP_0 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
164 
165  // TxoutType::MULTISIG 2/1
166  s.clear();
167  s << OP_2 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
169 
170  // TxoutType::MULTISIG n = 2 with 1 pubkey
171  s.clear();
172  s << OP_1 << ToByteVector(pubkey) << OP_2 << OP_CHECKMULTISIG;
174 
175  // TxoutType::MULTISIG n = 1 with 0 pubkeys
176  s.clear();
177  s << OP_1 << OP_1 << OP_CHECKMULTISIG;
179 
180  // TxoutType::NULL_DATA with other opcodes
181  s.clear();
182  s << OP_RETURN << std::vector<unsigned char>({75}) << OP_ADD;
184 
185  // TxoutType::WITNESS_UNKNOWN with incorrect program size
186  s.clear();
187  s << OP_0 << std::vector<unsigned char>(19, 0x01);
189 }
190 
191 BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
192 {
193  CKey key = GenerateRandomKey();
194  CPubKey pubkey = key.GetPubKey();
195 
196  CScript s;
197  CTxDestination address;
198 
199  // TxoutType::PUBKEY
200  s.clear();
201  s << ToByteVector(pubkey) << OP_CHECKSIG;
202  BOOST_CHECK(!ExtractDestination(s, address));
203  BOOST_CHECK(std::get<PubKeyDestination>(address) == PubKeyDestination(pubkey));
204 
205  // TxoutType::PUBKEYHASH
206  s.clear();
207  s << OP_DUP << OP_HASH160 << ToByteVector(pubkey.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
208  BOOST_CHECK(ExtractDestination(s, address));
209  BOOST_CHECK(std::get<PKHash>(address) == PKHash(pubkey));
210 
211  // TxoutType::SCRIPTHASH
212  CScript redeemScript(s); // initialize with leftover P2PKH script
213  s.clear();
214  s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
215  BOOST_CHECK(ExtractDestination(s, address));
216  BOOST_CHECK(std::get<ScriptHash>(address) == ScriptHash(redeemScript));
217 
218  // TxoutType::MULTISIG
219  s.clear();
220  s << OP_1 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
221  BOOST_CHECK(!ExtractDestination(s, address));
222 
223  // TxoutType::NULL_DATA
224  s.clear();
225  s << OP_RETURN << std::vector<unsigned char>({75});
226  BOOST_CHECK(!ExtractDestination(s, address));
227 
228  // TxoutType::WITNESS_V0_KEYHASH
229  s.clear();
230  s << OP_0 << ToByteVector(pubkey.GetID());
231  BOOST_CHECK(ExtractDestination(s, address));
232  WitnessV0KeyHash keyhash;
233  CHash160().Write(pubkey).Finalize(keyhash);
234  BOOST_CHECK(std::get<WitnessV0KeyHash>(address) == keyhash);
235 
236  // TxoutType::WITNESS_V0_SCRIPTHASH
237  s.clear();
238  WitnessV0ScriptHash scripthash;
239  CSHA256().Write(redeemScript.data(), redeemScript.size()).Finalize(scripthash.begin());
240  s << OP_0 << ToByteVector(scripthash);
241  BOOST_CHECK(ExtractDestination(s, address));
242  BOOST_CHECK(std::get<WitnessV0ScriptHash>(address) == scripthash);
243 
244  // TxoutType::WITNESS_UNKNOWN with unknown version
245  s.clear();
246  s << OP_1 << ToByteVector(pubkey);
247  BOOST_CHECK(ExtractDestination(s, address));
248  WitnessUnknown unk{1, ToByteVector(pubkey)};
249  BOOST_CHECK(std::get<WitnessUnknown>(address) == unk);
250 }
251 
252 BOOST_AUTO_TEST_CASE(script_standard_GetScriptFor_)
253 {
254  CKey keys[3];
255  CPubKey pubkeys[3];
256  for (int i = 0; i < 3; i++) {
257  keys[i].MakeNewKey(true);
258  pubkeys[i] = keys[i].GetPubKey();
259  }
260 
261  CScript expected, result;
262 
263  // PKHash
264  expected.clear();
265  expected << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
266  result = GetScriptForDestination(PKHash(pubkeys[0]));
267  BOOST_CHECK(result == expected);
268 
269  // CScriptID
270  CScript redeemScript(result);
271  expected.clear();
272  expected << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
273  result = GetScriptForDestination(ScriptHash(redeemScript));
274  BOOST_CHECK(result == expected);
275 
276  // CNoDestination
277  expected.clear();
279  BOOST_CHECK(result == expected);
280 
281  // GetScriptForRawPubKey
282  expected.clear();
283  expected << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
284  result = GetScriptForRawPubKey(pubkeys[0]);
285  BOOST_CHECK(result == expected);
286 
287  // GetScriptForMultisig
288  expected.clear();
289  expected << OP_2 <<
290  ToByteVector(pubkeys[0]) <<
291  ToByteVector(pubkeys[1]) <<
292  ToByteVector(pubkeys[2]) <<
294  result = GetScriptForMultisig(2, std::vector<CPubKey>(pubkeys, pubkeys + 3));
295  BOOST_CHECK(result == expected);
296 
297  // WitnessV0KeyHash
298  expected.clear();
299  expected << OP_0 << ToByteVector(pubkeys[0].GetID());
301  BOOST_CHECK(result == expected);
302  result = GetScriptForDestination(WitnessV0KeyHash(pubkeys[0].GetID()));
303  BOOST_CHECK(result == expected);
304 
305  // WitnessV0ScriptHash (multisig)
306  CScript witnessScript;
307  witnessScript << OP_1 << ToByteVector(pubkeys[0]) << OP_1 << OP_CHECKMULTISIG;
308 
309  uint256 scriptHash;
310  CSHA256().Write(witnessScript.data(), witnessScript.size())
311  .Finalize(scriptHash.begin());
312 
313  expected.clear();
314  expected << OP_0 << ToByteVector(scriptHash);
315  result = GetScriptForDestination(WitnessV0ScriptHash(witnessScript));
316  BOOST_CHECK(result == expected);
317 }
318 
319 BOOST_AUTO_TEST_CASE(script_standard_taproot_builder)
320 {
361  BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({2,2,2,3,4,5,6,7,8,9,10,11,12,14,14,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,31,31,31,31,31,31,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,128}), true);
362  BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({128,128,127,126,125,124,123,122,121,120,119,118,117,116,115,114,113,112,111,110,109,108,107,106,105,104,103,102,101,100,99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1}), true);
363  BOOST_CHECK_EQUAL(TaprootBuilder::ValidDepths({129,129,128,127,126,125,124,123,122,121,120,119,118,117,116,115,114,113,112,111,110,109,108,107,106,105,104,103,102,101,100,99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1}), false);
364 
365  XOnlyPubKey key_inner{ParseHex("79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798")};
366  XOnlyPubKey key_1{ParseHex("c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5")};
367  XOnlyPubKey key_2{ParseHex("f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9")};
368  CScript script_1 = CScript() << ToByteVector(key_1) << OP_CHECKSIG;
369  CScript script_2 = CScript() << ToByteVector(key_2) << OP_CHECKSIG;
370  uint256 hash_3 = uint256S("31fe7061656bea2a36aa60a2f7ef940578049273746935d296426dc0afd86b68");
371 
372  TaprootBuilder builder;
373  BOOST_CHECK(builder.IsValid() && builder.IsComplete());
374  builder.Add(2, script_2, 0xc0);
375  BOOST_CHECK(builder.IsValid() && !builder.IsComplete());
376  builder.AddOmitted(2, hash_3);
377  BOOST_CHECK(builder.IsValid() && !builder.IsComplete());
378  builder.Add(1, script_1, 0xc0);
379  BOOST_CHECK(builder.IsValid() && builder.IsComplete());
380  builder.Finalize(key_inner);
381  BOOST_CHECK(builder.IsValid() && builder.IsComplete());
382  BOOST_CHECK_EQUAL(EncodeDestination(builder.GetOutput()), "bc1pj6gaw944fy0xpmzzu45ugqde4rz7mqj5kj0tg8kmr5f0pjq8vnaqgynnge");
383 }
384 
385 BOOST_AUTO_TEST_CASE(bip341_spk_test_vectors)
386 {
387  using control_set = decltype(TaprootSpendData::scripts)::mapped_type;
388 
389  UniValue tests;
390  tests.read(json_tests::bip341_wallet_vectors);
391 
392  const auto& vectors = tests["scriptPubKey"];
393 
394  for (const auto& vec : vectors.getValues()) {
395  TaprootBuilder spktest;
396  std::map<std::pair<std::vector<unsigned char>, int>, int> scriptposes;
397  std::function<void (const UniValue&, int)> parse_tree = [&](const UniValue& node, int depth) {
398  if (node.isNull()) return;
399  if (node.isObject()) {
400  auto script = ParseHex(node["script"].get_str());
401  int idx = node["id"].getInt<int>();
402  int leaf_version = node["leafVersion"].getInt<int>();
403  scriptposes[{script, leaf_version}] = idx;
404  spktest.Add(depth, script, leaf_version);
405  } else {
406  parse_tree(node[0], depth + 1);
407  parse_tree(node[1], depth + 1);
408  }
409  };
410  parse_tree(vec["given"]["scriptTree"], 0);
411  spktest.Finalize(XOnlyPubKey(ParseHex(vec["given"]["internalPubkey"].get_str())));
412  BOOST_CHECK_EQUAL(HexStr(GetScriptForDestination(spktest.GetOutput())), vec["expected"]["scriptPubKey"].get_str());
413  BOOST_CHECK_EQUAL(EncodeDestination(spktest.GetOutput()), vec["expected"]["bip350Address"].get_str());
414  auto spend_data = spktest.GetSpendData();
415  BOOST_CHECK_EQUAL(vec["intermediary"]["merkleRoot"].isNull(), spend_data.merkle_root.IsNull());
416  if (!spend_data.merkle_root.IsNull()) {
417  BOOST_CHECK_EQUAL(vec["intermediary"]["merkleRoot"].get_str(), HexStr(spend_data.merkle_root));
418  }
419  BOOST_CHECK_EQUAL(spend_data.scripts.size(), scriptposes.size());
420  for (const auto& scriptpos : scriptposes) {
421  BOOST_CHECK(spend_data.scripts[scriptpos.first] == control_set{ParseHex(vec["expected"]["scriptPathControlBlocks"][scriptpos.second].get_str())});
422  }
423  }
424 }
425 
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
Definition: addresstype.cpp:49
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination corresponds to one with an address.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
Definition: addresstype.h:131
unsigned char * begin()
Definition: hash_type.h:18
A hasher class for Bitcoin's 160-bit hash (SHA-256 + RIPEMD-160).
Definition: hash.h:49
void Finalize(Span< unsigned char > output)
Definition: hash.h:55
CHash160 & Write(Span< const unsigned char > input)
Definition: hash.h:62
An encapsulated private key.
Definition: key.h:33
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
Definition: key.cpp:161
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:188
An encapsulated public key.
Definition: pubkey.h:34
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:164
A hasher class for SHA-256.
Definition: sha256.h:14
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha256.cpp:728
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:702
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:414
void clear()
Definition: script.h:557
A reference to a CScript: the Hash160 of its serialization.
Definition: script.h:583
Utility class to construct Taproot outputs from internal key and script tree.
WitnessV1Taproot GetOutput()
Compute scriptPubKey (after Finalize()).
TaprootSpendData GetSpendData() const
Compute spending data (after Finalize()).
bool IsComplete() const
Return whether there were either no leaves, or the leaves form a Huffman tree.
static bool ValidDepths(const std::vector< int > &depths)
Check if a list of depths is legal (will lead to IsComplete()).
bool IsValid() const
Return true if so far all input was valid.
TaprootBuilder & Add(int depth, Span< const unsigned char > script, int leaf_version, bool track=true)
Add a new script at a certain depth in the tree.
TaprootBuilder & AddOmitted(int depth, const uint256 &hash)
Like Add(), but for a Merkle node with a given hash to the tree.
TaprootBuilder & Finalize(const XOnlyPubKey &internal_key)
Finalize the construction.
bool read(std::string_view raw)
constexpr unsigned char * begin()
Definition: uint256.h:68
size_type size() const
Definition: prevector.h:296
value_type * data()
Definition: prevector.h:532
256-bit opaque blob.
Definition: uint256.h:106
static const uint256 ONE
Definition: uint256.h:112
static const uint256 ZERO
Definition: uint256.h:111
BOOST_AUTO_TEST_SUITE_END()
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
Definition: hash.h:92
CKey GenerateRandomKey(bool compressed) noexcept
Definition: key.cpp:372
std::string EncodeDestination(const CTxDestination &dest)
Definition: key_io.cpp:287
Definition: init.h:25
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
#define BOOST_CHECK(expr)
Definition: object.cpp:17
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:66
@ OP_2
Definition: script.h:84
@ OP_CHECKMULTISIG
Definition: script.h:191
@ OP_CHECKSIG
Definition: script.h:189
@ OP_16
Definition: script.h:98
@ OP_EQUAL
Definition: script.h:145
@ OP_DUP
Definition: script.h:124
@ OP_HASH160
Definition: script.h:186
@ OP_1
Definition: script.h:82
@ OP_ADD
Definition: script.h:160
@ OP_9
Definition: script.h:91
@ OP_3
Definition: script.h:85
@ OP_11
Definition: script.h:93
@ OP_0
Definition: script.h:75
@ OP_RETURN
Definition: script.h:110
@ OP_EQUALVERIFY
Definition: script.h:146
BOOST_AUTO_TEST_CASE(dest_default_is_no_dest)
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
Definition: solver.cpp:140
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
Definition: solver.cpp:214
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
Definition: solver.cpp:209
@ WITNESS_V1_TAPROOT
@ WITNESS_UNKNOWN
Only for Witness versions not already defined above.
@ WITNESS_V0_SCRIPTHASH
@ NULL_DATA
unspendable OP_RETURN script that carries data
@ WITNESS_V0_KEYHASH
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
Definition: strencodings.h:65
Basic testing setup.
Definition: setup_common.h:52
std::map< std::pair< std::vector< unsigned char >, int >, std::set< std::vector< unsigned char >, ShortestVectorFirstComparator > > scripts
Map from (script, leaf_version) to (sets of) control blocks.
CTxDestination subtype to encode any future Witness version.
Definition: addresstype.h:95
uint256 uint256S(const char *str)
Definition: uint256.h:119
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.