mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 14:59:39 -04:00
Add StandardTemplateHash definition
and associated SignatureChecker method.
This commit is contained in:
parent
cdc32994fe
commit
3e090231b8
2 changed files with 91 additions and 0 deletions
|
@ -1377,6 +1377,18 @@ uint256 GetSpentAmountsSHA256(const std::vector<CTxOut>& outputs_spent)
|
|||
HashWriter ss{};
|
||||
for (const auto& txout : outputs_spent) {
|
||||
ss << txout.nValue;
|
||||
|
||||
}
|
||||
return ss.GetSHA256();
|
||||
}
|
||||
|
||||
/** Compute the (single) SHA256 of the concatenation of all scriptSigs in a tx. */
|
||||
template <class T>
|
||||
uint256 GetScriptSigsSHA256(const T& txTo)
|
||||
{
|
||||
HashWriter ss{};
|
||||
for (const auto& in : txTo.vin) {
|
||||
ss << in.scriptSig;
|
||||
}
|
||||
return ss.GetSHA256();
|
||||
}
|
||||
|
@ -1391,9 +1403,62 @@ uint256 GetSpentScriptsSHA256(const std::vector<CTxOut>& outputs_spent)
|
|||
return ss.GetSHA256();
|
||||
}
|
||||
|
||||
template<typename TxType>
|
||||
uint256 GetDefaultCheckTemplateVerifyHashWithScript(
|
||||
const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash,
|
||||
const uint256& scriptSig_hash, const uint32_t input_index)
|
||||
{
|
||||
auto h = HashWriter{}
|
||||
<< tx.version
|
||||
<< tx.nLockTime
|
||||
<< scriptSig_hash
|
||||
<< uint32_t(tx.vin.size())
|
||||
<< sequences_hash
|
||||
<< uint32_t(tx.vout.size())
|
||||
<< outputs_hash
|
||||
<< input_index;
|
||||
return h.GetSHA256();
|
||||
}
|
||||
|
||||
template<typename TxType>
|
||||
uint256 GetDefaultCheckTemplateVerifyHashEmptyScript(
|
||||
const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash,
|
||||
const uint32_t input_index)
|
||||
{
|
||||
auto h = HashWriter{}
|
||||
<< tx.version
|
||||
<< tx.nLockTime
|
||||
<< uint32_t(tx.vin.size())
|
||||
<< sequences_hash
|
||||
<< uint32_t(tx.vout.size())
|
||||
<< outputs_hash
|
||||
<< input_index;
|
||||
return h.GetSHA256();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
template<typename TxType>
|
||||
uint256 GetDefaultCheckTemplateVerifyHash(const TxType& tx, uint32_t input_index) {
|
||||
return GetDefaultCheckTemplateVerifyHash(tx, GetOutputsSHA256(tx), GetSequencesSHA256(tx), input_index);
|
||||
}
|
||||
|
||||
template<typename TxType>
|
||||
uint256 GetDefaultCheckTemplateVerifyHash(
|
||||
const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash, const uint32_t input_index) {
|
||||
bool skip_scriptSigs = std::find_if(tx.vin.begin(), tx.vin.end(),
|
||||
[](const CTxIn& c) { return c.scriptSig != CScript(); }) == tx.vin.end();
|
||||
return skip_scriptSigs ? GetDefaultCheckTemplateVerifyHashEmptyScript(tx, outputs_hash, sequences_hash, input_index) :
|
||||
GetDefaultCheckTemplateVerifyHashWithScript(tx, outputs_hash, sequences_hash, GetScriptSigsSHA256(tx), input_index);
|
||||
}
|
||||
|
||||
template
|
||||
uint256 GetDefaultCheckTemplateVerifyHash(
|
||||
const CTransaction& tx, const uint256& outputs_hash, const uint256& sequences_hash, const uint32_t input_index);
|
||||
template
|
||||
uint256 GetDefaultCheckTemplateVerifyHash(
|
||||
const CMutableTransaction& tx, const uint256& outputs_hash, const uint256& sequences_hash, const uint32_t input_index);
|
||||
|
||||
template <class T>
|
||||
void PrecomputedTransactionData::Init(const T& txTo, std::vector<CTxOut>&& spent_outputs, bool force)
|
||||
{
|
||||
|
@ -1781,6 +1846,15 @@ bool GenericTransactionSignatureChecker<T>::CheckSequence(const CScriptNum& nSeq
|
|||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool GenericTransactionSignatureChecker<T>::CheckDefaultCheckTemplateVerifyHash(const std::vector<unsigned char>& hash) const
|
||||
{
|
||||
// Should already be checked before calling...
|
||||
assert(hash.size() == 32);
|
||||
assert(txTo != nullptr);
|
||||
uint256 hash_tmpl = GetDefaultCheckTemplateVerifyHash(*txTo, nIn);
|
||||
return std::equal(hash_tmpl.begin(), hash_tmpl.end(), hash.data());
|
||||
}
|
||||
// explicit instantiation
|
||||
template class GenericTransactionSignatureChecker<CTransaction>;
|
||||
template class GenericTransactionSignatureChecker<CMutableTransaction>;
|
||||
|
|
|
@ -187,6 +187,17 @@ struct PrecomputedTransactionData
|
|||
explicit PrecomputedTransactionData(const T& tx);
|
||||
};
|
||||
|
||||
/**
|
||||
* Compute the default template hash for OP_CHECKTEMPLATEVERIFY using some precomputed
|
||||
* hash inputs.
|
||||
*
|
||||
* (This exported interface is only used in tests.)
|
||||
*/
|
||||
template<typename TxType>
|
||||
uint256 GetDefaultCheckTemplateVerifyHash(
|
||||
const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash,
|
||||
const uint32_t input_index);
|
||||
|
||||
enum class SigVersion
|
||||
{
|
||||
BASE = 0, //!< Bare scripts and BIP16 P2SH-wrapped redeemscripts
|
||||
|
@ -265,6 +276,11 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
virtual bool CheckDefaultCheckTemplateVerifyHash(const std::vector<unsigned char>& hash) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual ~BaseSignatureChecker() = default;
|
||||
};
|
||||
|
||||
|
@ -301,6 +317,7 @@ public:
|
|||
bool CheckSchnorrSignature(std::span<const unsigned char> sig, std::span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override;
|
||||
bool CheckLockTime(const CScriptNum& nLockTime) const override;
|
||||
bool CheckSequence(const CScriptNum& nSequence) const override;
|
||||
bool CheckDefaultCheckTemplateVerifyHash(const std::vector<unsigned char>& hash) const override;
|
||||
};
|
||||
|
||||
using TransactionSignatureChecker = GenericTransactionSignatureChecker<CTransaction>;
|
||||
|
|
Loading…
Add table
Reference in a new issue