MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / ParseScript

Function ParseScript

src/script/descriptor.cpp:2335–2756  ·  view source on GitHub ↗

Parse a script in a particular context. */ NOLINTNEXTLINE(misc-no-recursion)

Source from the content-addressed store, hash-verified

2333/** Parse a script in a particular context. */
2334// NOLINTNEXTLINE(misc-no-recursion)
2335std::vector<std::unique_ptr<DescriptorImpl>> ParseScript(uint32_t& key_exp_index, std::span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
2336{
2337 using namespace script;
2338 Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
2339 std::vector<std::unique_ptr<DescriptorImpl>> ret;
2340 auto expr = Expr(sp);
2341 if (Func("pk", expr)) {
2342 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx, out, error);
2343 if (pubkeys.empty()) {
2344 error = strprintf("pk(): %s", error);
2345 return {};
2346 }
2347 for (auto& pubkey : pubkeys) {
2348 ret.emplace_back(std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR));
2349 }
2350 return ret;
2351 }
2352 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && Func("pkh", expr)) {
2353 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx, out, error);
2354 if (pubkeys.empty()) {
2355 error = strprintf("pkh(): %s", error);
2356 return {};
2357 }
2358 for (auto& pubkey : pubkeys) {
2359 ret.emplace_back(std::make_unique<PKHDescriptor>(std::move(pubkey)));
2360 }
2361 return ret;
2362 }
2363 if (ctx == ParseScriptContext::TOP && Func("combo", expr)) {
2364 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx, out, error);
2365 if (pubkeys.empty()) {
2366 error = strprintf("combo(): %s", error);
2367 return {};
2368 }
2369 for (auto& pubkey : pubkeys) {
2370 ret.emplace_back(std::make_unique<ComboDescriptor>(std::move(pubkey)));
2371 }
2372 return ret;
2373 } else if (Func("combo", expr)) {
2374 error = "Can only have combo() at top level";
2375 return {};
2376 }
2377 const bool multi = Func("multi", expr);
2378 const bool sortedmulti = !multi && Func("sortedmulti", expr);
2379 const bool multi_a = !(multi || sortedmulti) && Func("multi_a", expr);
2380 const bool sortedmulti_a = !(multi || sortedmulti || multi_a) && Func("sortedmulti_a", expr);
2381 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (multi || sortedmulti)) ||
2382 (ctx == ParseScriptContext::P2TR && (multi_a || sortedmulti_a))) {
2383 auto threshold = Expr(expr);
2384 uint32_t thres;
2385 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers; // List of multipath expanded pubkeys
2386 if (const auto maybe_thres{ToIntegral<uint32_t>(std::string_view{threshold.begin(), threshold.end()})}) {
2387 thres = *maybe_thres;
2388 } else {
2389 error = strprintf("Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
2390 return {};
2391 }
2392 size_t script_size = 0;

Callers 5

ParseFunction · 0.70
BOOST_AUTO_TEST_CASEFunction · 0.50
BOOST_AUTO_TEST_CASEFunction · 0.50
BOOST_AUTO_TEST_CASEFunction · 0.50
FUZZ_TARGETFunction · 0.50

Calls 15

ExprFunction · 0.85
FuncFunction · 0.85
ParsePubkeyFunction · 0.85
ConstFunction · 0.85
DecodeDestinationFunction · 0.85
IsValidDestinationFunction · 0.85
IsHexFunction · 0.85
ParseHexFunction · 0.85
FromStringFunction · 0.85
IsSaneMethod · 0.80
IsNotSatisfiableMethod · 0.80
FindInsaneSubMethod · 0.80

Tested by 4

BOOST_AUTO_TEST_CASEFunction · 0.40
BOOST_AUTO_TEST_CASEFunction · 0.40
BOOST_AUTO_TEST_CASEFunction · 0.40
FUZZ_TARGETFunction · 0.40