17 int num_types = (e <<
"K"_mst) + (e <<
"V"_mst) + (e <<
"B"_mst) + (e <<
"W"_mst);
18 if (num_types == 0)
return ""_mst;
20 assert(!(e <<
"z"_mst) || !(e <<
"o"_mst));
21 assert(!(e <<
"n"_mst) || !(e <<
"z"_mst));
22 assert(!(e <<
"n"_mst) || !(e <<
"W"_mst));
23 assert(!(e <<
"V"_mst) || !(e <<
"d"_mst));
24 assert(!(e <<
"K"_mst) || (e <<
"u"_mst));
25 assert(!(e <<
"V"_mst) || !(e <<
"u"_mst));
26 assert(!(e <<
"e"_mst) || !(e <<
"f"_mst));
27 assert(!(e <<
"e"_mst) || (e <<
"d"_mst));
28 assert(!(e <<
"V"_mst) || !(e <<
"e"_mst));
29 assert(!(e <<
"d"_mst) || !(e <<
"f"_mst));
30 assert(!(e <<
"V"_mst) || (e <<
"f"_mst));
31 assert(!(e <<
"K"_mst) || (e <<
"s"_mst));
32 assert(!(e <<
"z"_mst) || (e <<
"m"_mst));
72 assert(n_keys >= 1 && n_keys <= 20);
98 "W"_mst.If(x <<
"B"_mst) |
103 "W"_mst.If(x <<
"Bo"_mst) |
107 "B"_mst.If(x <<
"K"_mst) |
112 "B"_mst.If(x <<
"Vz"_mst) |
113 "o"_mst.If(x <<
"z"_mst) |
114 "e"_mst.If(x <<
"f"_mst) |
120 "V"_mst.If(x <<
"B"_mst) |
125 "B"_mst.If(x <<
"Bn"_mst) |
126 "e"_mst.If(x <<
"f"_mst) |
132 (x &
"Bzondfems"_mst) |
135 (y &
"KVB"_mst).If(x <<
"V"_mst) |
136 (x &
"n"_mst) | (y &
"n"_mst).If(x <<
"z"_mst) |
137 ((x | y) &
"o"_mst).If((x | y) <<
"z"_mst) |
138 (x & y &
"dmz"_mst) |
139 ((x | y) &
"s"_mst) |
140 "f"_mst.If((y <<
"f"_mst) || (x <<
"s"_mst)) |
142 ((x | y) &
"ghij"_mst) |
143 "k"_mst.If(((x & y) <<
"k"_mst) &&
144 !(((x <<
"g"_mst) && (y <<
"h"_mst)) ||
145 ((x <<
"h"_mst) && (y <<
"g"_mst)) ||
146 ((x <<
"i"_mst) && (y <<
"j"_mst)) ||
147 ((x <<
"j"_mst) && (y <<
"i"_mst))));
149 (x &
"B"_mst).If(y <<
"W"_mst) |
150 ((x | y) &
"o"_mst).If((x | y) <<
"z"_mst) |
151 (x &
"n"_mst) | (y &
"n"_mst).If(x <<
"z"_mst) |
152 (x & y &
"e"_mst).If((x & y) <<
"s"_mst) |
153 (x & y &
"dzm"_mst) |
154 "f"_mst.If(((x & y) <<
"f"_mst) || (x <<
"sf"_mst) || (y <<
"sf"_mst)) |
155 ((x | y) &
"s"_mst) |
157 ((x | y) &
"ghij"_mst) |
158 "k"_mst.If(((x & y) <<
"k"_mst) &&
159 !(((x <<
"g"_mst) && (y <<
"h"_mst)) ||
160 ((x <<
"h"_mst) && (y <<
"g"_mst)) ||
161 ((x <<
"i"_mst) && (y <<
"j"_mst)) ||
162 ((x <<
"j"_mst) && (y <<
"i"_mst))));
164 "B"_mst.If(x <<
"Bd"_mst && y <<
"Wd"_mst) |
165 ((x | y) &
"o"_mst).If((x | y) <<
"z"_mst) |
166 (x & y &
"m"_mst).If((x | y) <<
"s"_mst && (x & y) <<
"e"_mst) |
167 (x & y &
"zse"_mst) |
169 ((x | y) &
"ghij"_mst) |
172 (y &
"B"_mst).If(x <<
"Bdu"_mst) |
173 (x &
"o"_mst).If(y <<
"z"_mst) |
174 (x & y &
"m"_mst).If(x <<
"e"_mst && (x | y) <<
"s"_mst) |
175 (x & y &
"zes"_mst) |
178 ((x | y) &
"ghij"_mst) |
181 (y &
"V"_mst).If(x <<
"Bdu"_mst) |
182 (x &
"o"_mst).If(y <<
"z"_mst) |
183 (x & y &
"m"_mst).If(x <<
"e"_mst && (x | y) <<
"s"_mst) |
186 ((x | y) &
"ghij"_mst) |
189 (x & y &
"VBKufs"_mst) |
190 "o"_mst.If((x & y) <<
"z"_mst) |
191 ((x | y) &
"e"_mst).If((x | y) <<
"f"_mst) |
192 (x & y &
"m"_mst).If((x | y) <<
"s"_mst) |
193 ((x | y) &
"d"_mst) |
195 ((x | y) &
"ghij"_mst) |
198 (y & z &
"BKV"_mst).If(x <<
"Bdu"_mst) |
199 (x & y & z &
"z"_mst) |
200 ((x | (y & z)) &
"o"_mst).If((x | (y & z)) <<
"z"_mst) |
202 (z &
"f"_mst).If((x <<
"s"_mst) || (y <<
"f"_mst)) |
204 (x & z &
"e"_mst).If(x <<
"s"_mst || y <<
"f"_mst) |
205 (x & y & z &
"m"_mst).If(x <<
"e"_mst && (x | y | z) <<
"s"_mst) |
206 (z & (x | y) &
"s"_mst) |
208 ((x | y | z) &
"ghij"_mst) |
209 "k"_mst.If(((x & y & z) <<
"k"_mst) &&
210 !(((x <<
"g"_mst) && (y <<
"h"_mst)) ||
211 ((x <<
"h"_mst) && (y <<
"g"_mst)) ||
212 ((x <<
"i"_mst) && (y <<
"j"_mst)) ||
213 ((x <<
"j"_mst) && (y <<
"i"_mst))));
220 Type acc_tl =
"k"_mst;
221 for (
size_t i = 0; i < sub_types.size(); ++i) {
222 Type t = sub_types[i];
223 if (!(
t << (i ?
"Wdu"_mst :
"Bdu"_mst)))
return ""_mst;
224 if (!(
t <<
"e"_mst)) all_e =
false;
225 if (!(
t <<
"m"_mst)) all_m =
false;
226 if (
t <<
"s"_mst) num_s += 1;
227 args += (
t <<
"z"_mst) ? 0 : (
t <<
"o"_mst) ? 1 : 2;
228 acc_tl = ((acc_tl |
t) &
"ghij"_mst) |
232 "k"_mst.
If(((acc_tl &
t) <<
"k"_mst) && ((
k <= 1) ||
233 ((
k > 1) && !(((acc_tl <<
"g"_mst) && (
t <<
"h"_mst)) ||
234 ((acc_tl <<
"h"_mst) && (
t <<
"g"_mst)) ||
235 ((acc_tl <<
"i"_mst) && (
t <<
"j"_mst)) ||
236 ((acc_tl <<
"j"_mst) && (
t <<
"i"_mst))))));
241 "e"_mst.
If(all_e && num_s == n_subs) |
242 "m"_mst.
If(all_e && all_m && num_s >= n_subs -
k) |
243 "s"_mst.
If(num_s >= n_subs -
k + 1) |
284 std::vector<Opcode> out;
286 while (it != itend) {
287 std::vector<unsigned char> push_data;
289 if (!script.
GetOp(it, opcode, push_data)) {
291 }
else if (opcode >=
OP_1 && opcode <=
OP_16) {
296 out.emplace_back(
OP_CHECKSIG, std::vector<unsigned char>());
304 out.emplace_back(
OP_EQUAL, std::vector<unsigned char>());
312 out.emplace_back(opcode, std::move(push_data));
314 std::reverse(out.begin(), out.end());
319 if (in.first ==
OP_0) {
322 if (!in.second.empty()) {
333 for (
int i = 0; i < (int)sp.
size(); ++i) {
334 if (sp[i] ==
m)
return i;
336 if (sp[i] ==
')')
break;
CScript BuildScript(Ts &&... inputs)
Build a script by concatenating other scripts, or any argument accepted by CScript::operator<<.
OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 [hash] OP_EQUAL.
[X] OP_VERIFY (or -VERIFY version of last opcode in X)
static int DecodeOP_N(opcodetype opcode)
Encode/decode small integers:
bool CheckMinimalPush(const std::vector< unsigned char > &data, opcodetype opcode)
Type ComputeType(Fragment fragment, Type x, Type y, Type z, const std::vector< Type > &sub_types, uint32_t k, size_t data_size, size_t n_subs, size_t n_keys)
Helper function for Node::CalcType.
OP_DUP OP_HASH160 [keyhash] OP_EQUALVERIFY.
OP_SIZE 32 OP_EQUALVERIFY OP_RIPEMD160 [hash] OP_EQUAL.
bool GetOp(const_iterator &pc, opcodetype &opcodeRet, std::vector< unsigned char > &vchRet) const
[k] [key_n]* [n] OP_CHECKMULTISIG
[n] OP_CHECKLOCKTIMEVERIFY
OP_TOALTSTACK [X] OP_FROMALTSTACK.
constexpr std::size_t size() const noexcept
constexpr Type If(bool x) const
The empty type if x is false, itself otherwise.
std::pair< opcodetype, std::vector< unsigned char > > Opcode
ANDOR will construct an andor node from the last three constructed nodes.
AND_B will construct an and_b node from the last two constructed nodes.
size_t ComputeScriptLen(Fragment fragment, Type sub0typ, size_t subsize, uint32_t k, size_t n_subs, size_t n_keys)
Helper function for Node::CalcScriptLen.
int FindNextChar(Span< const char > sp, const char m)
Type SanitizeType(Type e)
A helper sanitizer/checker for the output of CalcType.
std::optional< std::vector< Opcode > > DecomposeScript(const CScript &script)
Decode a script into opcode/push pairs.
[n] OP_CHECKSEQUENCEVERIFY
constexpr bool IsPushdataOp(opcodetype opcode)
OR_C will construct an or_c node from the last two constructed nodes.
opcodetype
Script opcodes.
THRESH will read a wrapped expression, and then look for a COMMA.
OP_DUP OP_IF [X] OP_ENDIF.
static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG
If CTxIn::nSequence encodes a relative lock-time and this flag is set, the relative lock-time has uni...
OR_D will construct an or_d node from the last two constructed nodes.
OP_SIZE OP_0NOTEQUAL OP_IF [X] OP_ENDIF.
OR_I will construct an or_i node from the last two constructed nodes.
Serialized script, used inside transaction inputs and outputs.
Fragment
The different node types in miniscript.
AND_V will construct an and_v node from the last two constructed nodes.
OR_B will construct an or_b node from the last two constructed nodes.
OP_SIZE 32 OP_EQUALVERIFY OP_SHA256 [hash] OP_EQUAL.
static const unsigned int LOCKTIME_THRESHOLD
A Span is an object that can refer to a contiguous sequence of objects.
OP_SIZE 32 OP_EQUALVERIFY OP_HASH256 [hash] OP_EQUAL.
This type encapsulates the miniscript type system properties.
std::optional< int64_t > ParseScriptNumber(const Opcode &in)
Determine whether the passed pair (created by DecomposeScript) is pushing a number.