MCPcopy Create free account
hub / github.com/ElementsProject/elements / ParseScript

Function ParseScript

src/script/descriptor.cpp:1038–1235  ·  view source on GitHub ↗

Parse a script in a particular context. */

Source from the content-addressed store, hash-verified

1036
1037/** Parse a script in a particular context. */
1038std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
1039{
1040 using namespace spanparsing;
1041
1042 auto expr = Expr(sp);
1043 bool sorted_multi = false;
1044 if (Func("pk", expr)) {
1045 auto pubkey = ParsePubkey(key_exp_index, expr, ctx, out, error);
1046 if (!pubkey) return nullptr;
1047 ++key_exp_index;
1048 return std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR);
1049 }
1050 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && Func("pkh", expr)) {
1051 auto pubkey = ParsePubkey(key_exp_index, expr, ctx, out, error);
1052 if (!pubkey) return nullptr;
1053 ++key_exp_index;
1054 return std::make_unique<PKHDescriptor>(std::move(pubkey));
1055 } else if (Func("pkh", expr)) {
1056 error = "Can only have pkh at top level, in sh(), or in wsh()";
1057 return nullptr;
1058 }
1059 if (ctx == ParseScriptContext::TOP && Func("combo", expr)) {
1060 auto pubkey = ParsePubkey(key_exp_index, expr, ctx, out, error);
1061 if (!pubkey) return nullptr;
1062 ++key_exp_index;
1063 return std::make_unique<ComboDescriptor>(std::move(pubkey));
1064 } else if (Func("combo", expr)) {
1065 error = "Can only have combo() at top level";
1066 return nullptr;
1067 }
1068 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && ((sorted_multi = Func("sortedmulti", expr)) || Func("multi", expr))) {
1069 auto threshold = Expr(expr);
1070 uint32_t thres;
1071 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1072 if (!ParseUInt32(std::string(threshold.begin(), threshold.end()), &thres)) {
1073 error = strprintf("Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
1074 return nullptr;
1075 }
1076 size_t script_size = 0;
1077 while (expr.size()) {
1078 if (!Const(",", expr)) {
1079 error = strprintf("Multi: expected ',', got '%c'", expr[0]);
1080 return nullptr;
1081 }
1082 auto arg = Expr(expr);
1083 auto pk = ParsePubkey(key_exp_index, arg, ctx, out, error);
1084 if (!pk) return nullptr;
1085 script_size += pk->GetSize() + 1;
1086 providers.emplace_back(std::move(pk));
1087 key_exp_index++;
1088 }
1089 if (providers.empty() || providers.size() > MAX_PUBKEYS_PER_MULTISIG) {
1090 error = strprintf("Cannot have %u keys in multisig; must have between 1 and %d keys, inclusive", providers.size(), MAX_PUBKEYS_PER_MULTISIG);
1091 return nullptr;
1092 } else if (thres < 1) {
1093 error = strprintf("Multisig threshold cannot be %d, must be at least 1", thres);
1094 return nullptr;
1095 } else if (thres > providers.size()) {

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
ParseUInt32Function · 0.85
ConstFunction · 0.85
DecodeDestinationFunction · 0.85
IsValidDestinationFunction · 0.85
IsHexFunction · 0.85
ParseHexFunction · 0.85
emplace_backMethod · 0.80
CScriptClass · 0.70
beginMethod · 0.45

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