Navigation Menu

Skip to content

Commit

Permalink
Miniscript: conversion from script
Browse files Browse the repository at this point in the history
Co-Authored-By: Antoine Poinsot <darosior@protonmail.com>
Co-Authored-By: Samuel Dobson <dobsonsa68@gmail.com>
  • Loading branch information
3 people committed Mar 17, 2022
1 parent 1ddaa66 commit 2e55e88
Show file tree
Hide file tree
Showing 3 changed files with 534 additions and 0 deletions.
53 changes: 53 additions & 0 deletions src/script/miniscript.cpp
Expand Up @@ -5,6 +5,7 @@
#include <string>
#include <vector>
#include <script/script.h>
#include <script/standard.h>
#include <script/miniscript.h>

#include <assert.h>
Expand Down Expand Up @@ -281,6 +282,58 @@ size_t ComputeScriptLen(Fragment nodetype, Type sub0typ, size_t subsize, uint32_
return 0;
}

bool DecomposeScript(const CScript& script, std::vector<std::pair<opcodetype, std::vector<unsigned char>>>& out)
{
out.clear();
CScript::const_iterator it = script.begin(), itend = script.end();
while (it != itend) {
std::vector<unsigned char> push_data;
opcodetype opcode;
if (!script.GetOp(it, opcode, push_data)) {
out.clear();
return false;
} else if (opcode >= OP_1 && opcode <= OP_16) {
// Deal with OP_n (GetOp does not turn them into pushes).
push_data.assign(1, CScript::DecodeOP_N(opcode));
} else if (opcode == OP_CHECKSIGVERIFY) {
// Decompose OP_CHECKSIGVERIFY into OP_CHECKSIG OP_VERIFY
out.emplace_back(OP_CHECKSIG, std::vector<unsigned char>());
opcode = OP_VERIFY;
} else if (opcode == OP_CHECKMULTISIGVERIFY) {
// Decompose OP_CHECKMULTISIGVERIFY into OP_CHECKMULTISIG OP_VERIFY
out.emplace_back(OP_CHECKMULTISIG, std::vector<unsigned char>());
opcode = OP_VERIFY;
} else if (opcode == OP_EQUALVERIFY) {
// Decompose OP_EQUALVERIFY into OP_EQUAL OP_VERIFY
out.emplace_back(OP_EQUAL, std::vector<unsigned char>());
opcode = OP_VERIFY;
} else if (IsPushdataOp(opcode)) {
if (!CheckMinimalPush(push_data, opcode)) return false;
} else if (it != itend && (opcode == OP_CHECKSIG || opcode == OP_CHECKMULTISIG || opcode == OP_EQUAL) && (*it == OP_VERIFY)) {
// Rule out non minimal VERIFY sequences
return false;
}
out.emplace_back(opcode, std::move(push_data));
}
std::reverse(out.begin(), out.end());
return true;
}

bool ParseScriptNumber(const std::pair<opcodetype, std::vector<unsigned char>>& in, int64_t& k) {
if (in.first == OP_0) {
k = 0;
return true;
}
if (!in.second.empty()) {
if (IsPushdataOp(in.first) && !CheckMinimalPush(in.second, in.first)) return false;
try {
k = CScriptNum(in.second, true).GetInt64();
return true;
} catch(const scriptnum_error&) {}
}
return false;
}

int FindNextChar(Span<const char> sp, const char m)
{
for (int i = 0; i < (int)sp.size(); ++i) {
Expand Down

0 comments on commit 2e55e88

Please sign in to comment.