mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-02 09:46:52 -05:00
consensus: Store transaction nVersion as uint32_t
Given that the use of a transaction's nVersion is always as an unsigned int, it doesn't make sense to store it as signed and then cast it to unsigned.
This commit is contained in:
parent
6e4d18f37f
commit
27e70f1f5b
16 changed files with 47 additions and 39 deletions
|
@ -203,12 +203,12 @@ static CAmount ExtractAndValidateValue(const std::string& strValue)
|
||||||
|
|
||||||
static void MutateTxVersion(CMutableTransaction& tx, const std::string& cmdVal)
|
static void MutateTxVersion(CMutableTransaction& tx, const std::string& cmdVal)
|
||||||
{
|
{
|
||||||
int64_t newVersion;
|
uint32_t newVersion;
|
||||||
if (!ParseInt64(cmdVal, &newVersion) || newVersion < 1 || newVersion > TX_MAX_STANDARD_VERSION) {
|
if (!ParseUInt32(cmdVal, &newVersion) || newVersion < 1 || newVersion > TX_MAX_STANDARD_VERSION) {
|
||||||
throw std::runtime_error("Invalid TX version requested: '" + cmdVal + "'");
|
throw std::runtime_error("Invalid TX version requested: '" + cmdVal + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
tx.nVersion = (int) newVersion;
|
tx.nVersion = newVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MutateTxLocktime(CMutableTransaction& tx, const std::string& cmdVal)
|
static void MutateTxLocktime(CMutableTransaction& tx, const std::string& cmdVal)
|
||||||
|
|
|
@ -48,11 +48,7 @@ std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx, int flags
|
||||||
int nMinHeight = -1;
|
int nMinHeight = -1;
|
||||||
int64_t nMinTime = -1;
|
int64_t nMinTime = -1;
|
||||||
|
|
||||||
// tx.nVersion is signed integer so requires cast to unsigned otherwise
|
bool fEnforceBIP68 = tx.nVersion >= 2 && flags & LOCKTIME_VERIFY_SEQUENCE;
|
||||||
// we would be doing a signed comparison and half the range of nVersion
|
|
||||||
// wouldn't support BIP 68.
|
|
||||||
bool fEnforceBIP68 = static_cast<uint32_t>(tx.nVersion) >= 2
|
|
||||||
&& flags & LOCKTIME_VERIFY_SEQUENCE;
|
|
||||||
|
|
||||||
// Do not enforce sequence numbers as a relative lock time
|
// Do not enforce sequence numbers as a relative lock time
|
||||||
// unless we have been instructed to
|
// unless we have been instructed to
|
||||||
|
|
|
@ -174,9 +174,7 @@ void TxToUniv(const CTransaction& tx, const uint256& block_hash, UniValue& entry
|
||||||
|
|
||||||
entry.pushKV("txid", tx.GetHash().GetHex());
|
entry.pushKV("txid", tx.GetHash().GetHex());
|
||||||
entry.pushKV("hash", tx.GetWitnessHash().GetHex());
|
entry.pushKV("hash", tx.GetWitnessHash().GetHex());
|
||||||
// Transaction version is actually unsigned in consensus checks, just signed in memory,
|
entry.pushKV("version", tx.nVersion);
|
||||||
// so cast to unsigned before giving it to the user.
|
|
||||||
entry.pushKV("version", static_cast<int64_t>(static_cast<uint32_t>(tx.nVersion)));
|
|
||||||
entry.pushKV("size", tx.GetTotalSize());
|
entry.pushKV("size", tx.GetTotalSize());
|
||||||
entry.pushKV("vsize", (GetTransactionWeight(tx) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR);
|
entry.pushKV("vsize", (GetTransactionWeight(tx) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR);
|
||||||
entry.pushKV("weight", GetTransactionWeight(tx));
|
entry.pushKV("weight", GetTransactionWeight(tx));
|
||||||
|
|
|
@ -63,8 +63,8 @@ std::string CTxOut::ToString() const
|
||||||
return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, HexStr(scriptPubKey).substr(0, 30));
|
return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, HexStr(scriptPubKey).substr(0, 30));
|
||||||
}
|
}
|
||||||
|
|
||||||
CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {}
|
CMutableTransaction::CMutableTransaction() : nVersion{CTransaction::CURRENT_VERSION}, nLockTime{0} {}
|
||||||
CMutableTransaction::CMutableTransaction(const CTransaction& tx) : vin(tx.vin), vout(tx.vout), nVersion(tx.nVersion), nLockTime(tx.nLockTime) {}
|
CMutableTransaction::CMutableTransaction(const CTransaction& tx) : vin(tx.vin), vout(tx.vout), nVersion{tx.nVersion}, nLockTime{tx.nLockTime} {}
|
||||||
|
|
||||||
Txid CMutableTransaction::GetHash() const
|
Txid CMutableTransaction::GetHash() const
|
||||||
{
|
{
|
||||||
|
@ -92,8 +92,8 @@ Wtxid CTransaction::ComputeWitnessHash() const
|
||||||
return Wtxid::FromUint256((HashWriter{} << TX_WITH_WITNESS(*this)).GetHash());
|
return Wtxid::FromUint256((HashWriter{} << TX_WITH_WITNESS(*this)).GetHash());
|
||||||
}
|
}
|
||||||
|
|
||||||
CTransaction::CTransaction(const CMutableTransaction& tx) : vin(tx.vin), vout(tx.vout), nVersion(tx.nVersion), nLockTime(tx.nLockTime), m_has_witness{ComputeHasWitness()}, hash{ComputeHash()}, m_witness_hash{ComputeWitnessHash()} {}
|
CTransaction::CTransaction(const CMutableTransaction& tx) : vin(tx.vin), vout(tx.vout), nVersion{tx.nVersion}, nLockTime{tx.nLockTime}, m_has_witness{ComputeHasWitness()}, hash{ComputeHash()}, m_witness_hash{ComputeWitnessHash()} {}
|
||||||
CTransaction::CTransaction(CMutableTransaction&& tx) : vin(std::move(tx.vin)), vout(std::move(tx.vout)), nVersion(tx.nVersion), nLockTime(tx.nLockTime), m_has_witness{ComputeHasWitness()}, hash{ComputeHash()}, m_witness_hash{ComputeWitnessHash()} {}
|
CTransaction::CTransaction(CMutableTransaction&& tx) : vin(std::move(tx.vin)), vout(std::move(tx.vout)), nVersion{tx.nVersion}, nLockTime{tx.nLockTime}, m_has_witness{ComputeHasWitness()}, hash{ComputeHash()}, m_witness_hash{ComputeWitnessHash()} {}
|
||||||
|
|
||||||
CAmount CTransaction::GetValueOut() const
|
CAmount CTransaction::GetValueOut() const
|
||||||
{
|
{
|
||||||
|
@ -115,7 +115,7 @@ unsigned int CTransaction::GetTotalSize() const
|
||||||
std::string CTransaction::ToString() const
|
std::string CTransaction::ToString() const
|
||||||
{
|
{
|
||||||
std::string str;
|
std::string str;
|
||||||
str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n",
|
str += strprintf("CTransaction(hash=%s, ver=%u, vin.size=%u, vout.size=%u, nLockTime=%u)\n",
|
||||||
GetHash().ToString().substr(0,10),
|
GetHash().ToString().substr(0,10),
|
||||||
nVersion,
|
nVersion,
|
||||||
vin.size(),
|
vin.size(),
|
||||||
|
|
|
@ -197,13 +197,13 @@ static constexpr TransactionSerParams TX_NO_WITNESS{.allow_witness = false};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic transaction serialization format:
|
* Basic transaction serialization format:
|
||||||
* - int32_t nVersion
|
* - uint32_t nVersion
|
||||||
* - std::vector<CTxIn> vin
|
* - std::vector<CTxIn> vin
|
||||||
* - std::vector<CTxOut> vout
|
* - std::vector<CTxOut> vout
|
||||||
* - uint32_t nLockTime
|
* - uint32_t nLockTime
|
||||||
*
|
*
|
||||||
* Extended transaction serialization format:
|
* Extended transaction serialization format:
|
||||||
* - int32_t nVersion
|
* - uint32_t nVersion
|
||||||
* - unsigned char dummy = 0x00
|
* - unsigned char dummy = 0x00
|
||||||
* - unsigned char flags (!= 0)
|
* - unsigned char flags (!= 0)
|
||||||
* - std::vector<CTxIn> vin
|
* - std::vector<CTxIn> vin
|
||||||
|
@ -296,7 +296,7 @@ class CTransaction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Default transaction version.
|
// Default transaction version.
|
||||||
static const int32_t CURRENT_VERSION=2;
|
static const uint32_t CURRENT_VERSION{2};
|
||||||
|
|
||||||
// The local variables are made const to prevent unintended modification
|
// The local variables are made const to prevent unintended modification
|
||||||
// without updating the cached hash value. However, CTransaction is not
|
// without updating the cached hash value. However, CTransaction is not
|
||||||
|
@ -305,7 +305,7 @@ public:
|
||||||
// structure, including the hash.
|
// structure, including the hash.
|
||||||
const std::vector<CTxIn> vin;
|
const std::vector<CTxIn> vin;
|
||||||
const std::vector<CTxOut> vout;
|
const std::vector<CTxOut> vout;
|
||||||
const int32_t nVersion;
|
const uint32_t nVersion;
|
||||||
const uint32_t nLockTime;
|
const uint32_t nLockTime;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -378,7 +378,7 @@ struct CMutableTransaction
|
||||||
{
|
{
|
||||||
std::vector<CTxIn> vin;
|
std::vector<CTxIn> vin;
|
||||||
std::vector<CTxOut> vout;
|
std::vector<CTxOut> vout;
|
||||||
int32_t nVersion;
|
uint32_t nVersion;
|
||||||
uint32_t nLockTime;
|
uint32_t nLockTime;
|
||||||
|
|
||||||
explicit CMutableTransaction();
|
explicit CMutableTransaction();
|
||||||
|
|
|
@ -1748,8 +1748,8 @@ static RPCHelpMan joinpsbts()
|
||||||
}
|
}
|
||||||
psbtxs.push_back(psbtx);
|
psbtxs.push_back(psbtx);
|
||||||
// Choose the highest version number
|
// Choose the highest version number
|
||||||
if (static_cast<uint32_t>(psbtx.tx->nVersion) > best_version) {
|
if (psbtx.tx->nVersion > best_version) {
|
||||||
best_version = static_cast<uint32_t>(psbtx.tx->nVersion);
|
best_version = psbtx.tx->nVersion;
|
||||||
}
|
}
|
||||||
// Choose the lowest lock time
|
// Choose the lowest lock time
|
||||||
if (psbtx.tx->nLockTime < best_locktime) {
|
if (psbtx.tx->nLockTime < best_locktime) {
|
||||||
|
@ -1760,7 +1760,7 @@ static RPCHelpMan joinpsbts()
|
||||||
// Create a blank psbt where everything will be added
|
// Create a blank psbt where everything will be added
|
||||||
PartiallySignedTransaction merged_psbt;
|
PartiallySignedTransaction merged_psbt;
|
||||||
merged_psbt.tx = CMutableTransaction();
|
merged_psbt.tx = CMutableTransaction();
|
||||||
merged_psbt.tx->nVersion = static_cast<int32_t>(best_version);
|
merged_psbt.tx->nVersion = best_version;
|
||||||
merged_psbt.tx->nLockTime = best_locktime;
|
merged_psbt.tx->nLockTime = best_locktime;
|
||||||
|
|
||||||
// Merge
|
// Merge
|
||||||
|
|
|
@ -1743,7 +1743,7 @@ bool GenericTransactionSignatureChecker<T>::CheckSequence(const CScriptNum& nSeq
|
||||||
|
|
||||||
// Fail if the transaction's version number is not set high
|
// Fail if the transaction's version number is not set high
|
||||||
// enough to trigger BIP 68 rules.
|
// enough to trigger BIP 68 rules.
|
||||||
if (static_cast<uint32_t>(txTo->nVersion) < 2)
|
if (txTo->nVersion < 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Sequence numbers with their most significant bit set are not
|
// Sequence numbers with their most significant bit set are not
|
||||||
|
|
|
@ -45,7 +45,7 @@ CMutableTransaction ConsumeTransaction(FuzzedDataProvider& fuzzed_data_provider,
|
||||||
const auto p2wsh_op_true = fuzzed_data_provider.ConsumeBool();
|
const auto p2wsh_op_true = fuzzed_data_provider.ConsumeBool();
|
||||||
tx_mut.nVersion = fuzzed_data_provider.ConsumeBool() ?
|
tx_mut.nVersion = fuzzed_data_provider.ConsumeBool() ?
|
||||||
CTransaction::CURRENT_VERSION :
|
CTransaction::CURRENT_VERSION :
|
||||||
fuzzed_data_provider.ConsumeIntegral<int32_t>();
|
fuzzed_data_provider.ConsumeIntegral<uint32_t>();
|
||||||
tx_mut.nLockTime = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
|
tx_mut.nLockTime = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
|
||||||
const auto num_in = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, max_num_in);
|
const auto num_in = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, max_num_in);
|
||||||
const auto num_out = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, max_num_out);
|
const auto num_out = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, max_num_out);
|
||||||
|
|
|
@ -92,7 +92,7 @@ void static RandomScript(CScript &script) {
|
||||||
|
|
||||||
void static RandomTransaction(CMutableTransaction& tx, bool fSingle)
|
void static RandomTransaction(CMutableTransaction& tx, bool fSingle)
|
||||||
{
|
{
|
||||||
tx.nVersion = int(InsecureRand32());
|
tx.nVersion = InsecureRand32();
|
||||||
tx.vin.clear();
|
tx.vin.clear();
|
||||||
tx.vout.clear();
|
tx.vout.clear();
|
||||||
tx.nLockTime = (InsecureRandBool()) ? InsecureRand32() : 0;
|
tx.nLockTime = (InsecureRandBool()) ? InsecureRand32() : 0;
|
||||||
|
|
|
@ -780,7 +780,7 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
|
||||||
CheckIsStandard(t);
|
CheckIsStandard(t);
|
||||||
|
|
||||||
// Disallowed nVersion
|
// Disallowed nVersion
|
||||||
t.nVersion = -1;
|
t.nVersion = std::numeric_limits<uint32_t>::max();
|
||||||
CheckIsNotStandard(t, "version");
|
CheckIsNotStandard(t, "version");
|
||||||
|
|
||||||
t.nVersion = 0;
|
t.nVersion = 0;
|
||||||
|
|
|
@ -1410,7 +1410,7 @@ class TaprootTest(BitcoinTestFramework):
|
||||||
while left:
|
while left:
|
||||||
# Construct CTransaction with random nVersion, nLocktime
|
# Construct CTransaction with random nVersion, nLocktime
|
||||||
tx = CTransaction()
|
tx = CTransaction()
|
||||||
tx.nVersion = random.choice([1, 2, random.randint(-0x80000000, 0x7fffffff)])
|
tx.nVersion = random.choice([1, 2, random.getrandbits(32)])
|
||||||
min_sequence = (tx.nVersion != 1 and tx.nVersion != 0) * 0x80000000 # The minimum sequence number to disable relative locktime
|
min_sequence = (tx.nVersion != 1 and tx.nVersion != 0) * 0x80000000 # The minimum sequence number to disable relative locktime
|
||||||
if random.choice([True, False]):
|
if random.choice([True, False]):
|
||||||
tx.nLockTime = random.randrange(LOCKTIME_THRESHOLD, self.lastblocktime - 7200) # all absolute locktimes in the past
|
tx.nLockTime = random.randrange(LOCKTIME_THRESHOLD, self.lastblocktime - 7200) # all absolute locktimes in the past
|
||||||
|
|
|
@ -1164,7 +1164,7 @@ class SegWitTest(BitcoinTestFramework):
|
||||||
if not self.wit.is_null():
|
if not self.wit.is_null():
|
||||||
flags |= 1
|
flags |= 1
|
||||||
r = b""
|
r = b""
|
||||||
r += self.nVersion.to_bytes(4, "little", signed=True)
|
r += self.nVersion.to_bytes(4, "little")
|
||||||
if flags:
|
if flags:
|
||||||
dummy = []
|
dummy = []
|
||||||
r += ser_vector(dummy)
|
r += ser_vector(dummy)
|
||||||
|
@ -1975,7 +1975,7 @@ class SegWitTest(BitcoinTestFramework):
|
||||||
def serialize_with_bogus_witness(tx):
|
def serialize_with_bogus_witness(tx):
|
||||||
flags = 3
|
flags = 3
|
||||||
r = b""
|
r = b""
|
||||||
r += tx.nVersion.to_bytes(4, "little", signed=True)
|
r += tx.nVersion.to_bytes(4, "little")
|
||||||
if flags:
|
if flags:
|
||||||
dummy = []
|
dummy = []
|
||||||
r += ser_vector(dummy)
|
r += ser_vector(dummy)
|
||||||
|
|
|
@ -394,7 +394,7 @@ class RPCPackagesTest(BitcoinTestFramework):
|
||||||
peer = node.add_p2p_connection(P2PTxInvStore())
|
peer = node.add_p2p_connection(P2PTxInvStore())
|
||||||
txs = self.wallet.create_self_transfer_chain(chain_length=2)
|
txs = self.wallet.create_self_transfer_chain(chain_length=2)
|
||||||
bad_child = tx_from_hex(txs[1]["hex"])
|
bad_child = tx_from_hex(txs[1]["hex"])
|
||||||
bad_child.nVersion = -1
|
bad_child.nVersion = 0xffffffff
|
||||||
hex_partial_acceptance = [txs[0]["hex"], bad_child.serialize().hex()]
|
hex_partial_acceptance = [txs[0]["hex"], bad_child.serialize().hex()]
|
||||||
res = node.submitpackage(hex_partial_acceptance)
|
res = node.submitpackage(hex_partial_acceptance)
|
||||||
assert_equal(res["package_msg"], "transaction failed")
|
assert_equal(res["package_msg"], "transaction failed")
|
||||||
|
|
|
@ -463,9 +463,9 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||||
self.log.info("Test transaction version numbers")
|
self.log.info("Test transaction version numbers")
|
||||||
|
|
||||||
# Test the minimum transaction version number that fits in a signed 32-bit integer.
|
# Test the minimum transaction version number that fits in a signed 32-bit integer.
|
||||||
# As transaction version is unsigned, this should convert to its unsigned equivalent.
|
# As transaction version is serialized unsigned, this should convert to its unsigned equivalent.
|
||||||
tx = CTransaction()
|
tx = CTransaction()
|
||||||
tx.nVersion = -0x80000000
|
tx.nVersion = 0x80000000
|
||||||
rawtx = tx.serialize().hex()
|
rawtx = tx.serialize().hex()
|
||||||
decrawtx = self.nodes[0].decoderawtransaction(rawtx)
|
decrawtx = self.nodes[0].decoderawtransaction(rawtx)
|
||||||
assert_equal(decrawtx['version'], 0x80000000)
|
assert_equal(decrawtx['version'], 0x80000000)
|
||||||
|
@ -477,6 +477,20 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||||
decrawtx = self.nodes[0].decoderawtransaction(rawtx)
|
decrawtx = self.nodes[0].decoderawtransaction(rawtx)
|
||||||
assert_equal(decrawtx['version'], 0x7fffffff)
|
assert_equal(decrawtx['version'], 0x7fffffff)
|
||||||
|
|
||||||
|
# Test the minimum transaction version number that fits in an unsigned 32-bit integer.
|
||||||
|
tx = CTransaction()
|
||||||
|
tx.nVersion = 0
|
||||||
|
rawtx = tx.serialize().hex()
|
||||||
|
decrawtx = self.nodes[0].decoderawtransaction(rawtx)
|
||||||
|
assert_equal(decrawtx['version'], 0)
|
||||||
|
|
||||||
|
# Test the maximum transaction version number that fits in an unsigned 32-bit integer.
|
||||||
|
tx = CTransaction()
|
||||||
|
tx.nVersion = 0xffffffff
|
||||||
|
rawtx = tx.serialize().hex()
|
||||||
|
decrawtx = self.nodes[0].decoderawtransaction(rawtx)
|
||||||
|
assert_equal(decrawtx['version'], 0xffffffff)
|
||||||
|
|
||||||
def raw_multisig_transaction_legacy_tests(self):
|
def raw_multisig_transaction_legacy_tests(self):
|
||||||
self.log.info("Test raw multisig transactions (legacy)")
|
self.log.info("Test raw multisig transactions (legacy)")
|
||||||
# The traditional multisig workflow does not work with descriptor wallets so these are legacy only.
|
# The traditional multisig workflow does not work with descriptor wallets so these are legacy only.
|
||||||
|
|
|
@ -582,7 +582,7 @@ class CTransaction:
|
||||||
self.wit = copy.deepcopy(tx.wit)
|
self.wit = copy.deepcopy(tx.wit)
|
||||||
|
|
||||||
def deserialize(self, f):
|
def deserialize(self, f):
|
||||||
self.nVersion = int.from_bytes(f.read(4), "little", signed=True)
|
self.nVersion = int.from_bytes(f.read(4), "little")
|
||||||
self.vin = deser_vector(f, CTxIn)
|
self.vin = deser_vector(f, CTxIn)
|
||||||
flags = 0
|
flags = 0
|
||||||
if len(self.vin) == 0:
|
if len(self.vin) == 0:
|
||||||
|
@ -605,7 +605,7 @@ class CTransaction:
|
||||||
|
|
||||||
def serialize_without_witness(self):
|
def serialize_without_witness(self):
|
||||||
r = b""
|
r = b""
|
||||||
r += self.nVersion.to_bytes(4, "little", signed=True)
|
r += self.nVersion.to_bytes(4, "little")
|
||||||
r += ser_vector(self.vin)
|
r += ser_vector(self.vin)
|
||||||
r += ser_vector(self.vout)
|
r += ser_vector(self.vout)
|
||||||
r += self.nLockTime.to_bytes(4, "little")
|
r += self.nLockTime.to_bytes(4, "little")
|
||||||
|
@ -617,7 +617,7 @@ class CTransaction:
|
||||||
if not self.wit.is_null():
|
if not self.wit.is_null():
|
||||||
flags |= 1
|
flags |= 1
|
||||||
r = b""
|
r = b""
|
||||||
r += self.nVersion.to_bytes(4, "little", signed=True)
|
r += self.nVersion.to_bytes(4, "little")
|
||||||
if flags:
|
if flags:
|
||||||
dummy = []
|
dummy = []
|
||||||
r += ser_vector(dummy)
|
r += ser_vector(dummy)
|
||||||
|
|
|
@ -738,7 +738,7 @@ def SegwitV0SignatureMsg(script, txTo, inIdx, hashtype, amount):
|
||||||
hashOutputs = uint256_from_str(hash256(serialize_outputs))
|
hashOutputs = uint256_from_str(hash256(serialize_outputs))
|
||||||
|
|
||||||
ss = bytes()
|
ss = bytes()
|
||||||
ss += txTo.nVersion.to_bytes(4, "little", signed=True)
|
ss += txTo.nVersion.to_bytes(4, "little")
|
||||||
ss += ser_uint256(hashPrevouts)
|
ss += ser_uint256(hashPrevouts)
|
||||||
ss += ser_uint256(hashSequence)
|
ss += ser_uint256(hashSequence)
|
||||||
ss += txTo.vin[inIdx].prevout.serialize()
|
ss += txTo.vin[inIdx].prevout.serialize()
|
||||||
|
@ -817,7 +817,7 @@ def TaprootSignatureMsg(txTo, spent_utxos, hash_type, input_index = 0, scriptpat
|
||||||
in_type = hash_type & SIGHASH_ANYONECANPAY
|
in_type = hash_type & SIGHASH_ANYONECANPAY
|
||||||
spk = spent_utxos[input_index].scriptPubKey
|
spk = spent_utxos[input_index].scriptPubKey
|
||||||
ss = bytes([0, hash_type]) # epoch, hash_type
|
ss = bytes([0, hash_type]) # epoch, hash_type
|
||||||
ss += txTo.nVersion.to_bytes(4, "little", signed=True)
|
ss += txTo.nVersion.to_bytes(4, "little")
|
||||||
ss += txTo.nLockTime.to_bytes(4, "little")
|
ss += txTo.nLockTime.to_bytes(4, "little")
|
||||||
if in_type != SIGHASH_ANYONECANPAY:
|
if in_type != SIGHASH_ANYONECANPAY:
|
||||||
ss += BIP341_sha_prevouts(txTo)
|
ss += BIP341_sha_prevouts(txTo)
|
||||||
|
|
Loading…
Add table
Reference in a new issue