mirror of
https://github.com/Retropex/bitcoin.git
synced 2025-05-12 19:20:42 +02:00
policy: GetScriptForTransactionInput to figure out P2SH, witness, taproot
This commit is contained in:
parent
a3068674ff
commit
f30200fb0f
@ -321,3 +321,50 @@ int64_t GetVirtualTransactionInputSize(const CTxIn& txin, int64_t nSigOpCost, un
|
||||
{
|
||||
return GetVirtualTransactionSize(GetTransactionInputWeight(txin), nSigOpCost, bytes_per_sigop);
|
||||
}
|
||||
|
||||
std::pair<CScript, unsigned int> GetScriptForTransactionInput(CScript prev_script, const CTxIn& txin)
|
||||
{
|
||||
bool p2sh = false;
|
||||
if (prev_script.IsPayToScriptHash()) {
|
||||
std::vector <std::vector<unsigned char> > stack;
|
||||
if (!EvalScript(stack, txin.scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SigVersion::BASE)) {
|
||||
return std::make_pair(CScript(), 0);
|
||||
}
|
||||
if (stack.empty()) {
|
||||
return std::make_pair(CScript(), 0);
|
||||
}
|
||||
prev_script = CScript(stack.back().begin(), stack.back().end());
|
||||
p2sh = true;
|
||||
}
|
||||
|
||||
int witnessversion = 0;
|
||||
std::vector<unsigned char> witnessprogram;
|
||||
|
||||
if (!prev_script.IsWitnessProgram(witnessversion, witnessprogram)) {
|
||||
// For P2SH, scriptSig is always push-only, so the actual script is only the last stack item
|
||||
// For non-P2SH, prevScript is likely the real script, but not part of this transaction, and scriptSig could very well be executable, so return the latter instead
|
||||
return std::make_pair(p2sh ? prev_script : txin.scriptSig, WITNESS_SCALE_FACTOR);
|
||||
}
|
||||
|
||||
auto stack = std::span{txin.scriptWitness.stack};
|
||||
|
||||
if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_SCRIPTHASH_SIZE) {
|
||||
if (stack.empty()) return std::make_pair(CScript(), 0); // invalid
|
||||
auto& script_data = stack.back();
|
||||
prev_script = CScript(script_data.begin(), script_data.end());
|
||||
return std::make_pair(prev_script, 1);
|
||||
}
|
||||
|
||||
if (witnessversion == 1 && witnessprogram.size() == WITNESS_V1_TAPROOT_SIZE && !p2sh) {
|
||||
if (stack.size() >= 2 && !stack.back().empty() && stack.back()[0] == ANNEX_TAG) {
|
||||
SpanPopBack(stack);
|
||||
}
|
||||
if (stack.size() >= 2) {
|
||||
SpanPopBack(stack); // Ignore control block
|
||||
prev_script = CScript(stack.back().begin(), stack.back().end());
|
||||
return std::make_pair(prev_script, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_pair(CScript(), 0);
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
class CCoinsViewCache;
|
||||
class CFeeRate;
|
||||
@ -181,4 +182,6 @@ static inline int64_t GetVirtualTransactionInputSize(const CTxIn& tx)
|
||||
return GetVirtualTransactionInputSize(tx, 0, 0);
|
||||
}
|
||||
|
||||
std::pair<CScript, unsigned int> GetScriptForTransactionInput(CScript prev_script, const CTxIn&);
|
||||
|
||||
#endif // BITCOIN_POLICY_POLICY_H
|
||||
|
Loading…
Reference in New Issue
Block a user