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);
|
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 <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
class CCoinsViewCache;
|
class CCoinsViewCache;
|
||||||
class CFeeRate;
|
class CFeeRate;
|
||||||
@ -181,4 +182,6 @@ static inline int64_t GetVirtualTransactionInputSize(const CTxIn& tx)
|
|||||||
return GetVirtualTransactionInputSize(tx, 0, 0);
|
return GetVirtualTransactionInputSize(tx, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<CScript, unsigned int> GetScriptForTransactionInput(CScript prev_script, const CTxIn&);
|
||||||
|
|
||||||
#endif // BITCOIN_POLICY_POLICY_H
|
#endif // BITCOIN_POLICY_POLICY_H
|
||||||
|
Loading…
Reference in New Issue
Block a user