diff options
author | Pieter Wuille <pieter@wuille.net> | 2022-01-10 13:45:03 -0500 |
---|---|---|
committer | Pieter Wuille <pieter@wuille.net> | 2022-01-12 11:09:41 -0500 |
commit | 79728c4a3d8a74f276daf1e72abbdecdab85a5d8 (patch) | |
tree | ca61b3411b91eb06f26919541ec4561f848197c3 /src/script/standard.cpp | |
parent | 25e95f9ff89a97b87ce218f28274c3c821b2d54d (diff) | |
download | bitcoin-79728c4a3d8a74f276daf1e72abbdecdab85a5d8.tar.xz |
Add (sorted)multi_a descriptor and script derivation
Diffstat (limited to 'src/script/standard.cpp')
-rw-r--r-- | src/script/standard.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/script/standard.cpp b/src/script/standard.cpp index 0dd8eba1ba..806b3169cd 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -139,6 +139,40 @@ static bool MatchMultisig(const CScript& script, int& required_sigs, std::vector return (it + 1 == script.end()); } +std::optional<std::pair<int, std::vector<Span<const unsigned char>>>> MatchMultiA(const CScript& script) +{ + std::vector<Span<const unsigned char>> keyspans; + + // Redundant, but very fast and selective test. + if (script.size() == 0 || script[0] != 32 || script.back() != OP_NUMEQUAL) return {}; + + // Parse keys + auto it = script.begin(); + while (script.end() - it >= 34) { + if (*it != 32) return {}; + ++it; + keyspans.emplace_back(&*it, 32); + it += 32; + if (*it != (keyspans.size() == 1 ? OP_CHECKSIG : OP_CHECKSIGADD)) return {}; + ++it; + } + if (keyspans.size() == 0 || keyspans.size() > MAX_PUBKEYS_PER_MULTI_A) return {}; + + // Parse threshold. + opcodetype opcode; + std::vector<unsigned char> data; + if (!script.GetOp(it, opcode, data)) return {}; + if (it == script.end()) return {}; + if (*it != OP_NUMEQUAL) return {}; + ++it; + if (it != script.end()) return {}; + auto threshold = GetScriptNumber(opcode, data, 1, (int)keyspans.size()); + if (!threshold) return {}; + + // Construct result. + return std::pair{*threshold, std::move(keyspans)}; +} + TxoutType Solver(const CScript& scriptPubKey, std::vector<std::vector<unsigned char>>& vSolutionsRet) { vSolutionsRet.clear(); |