Bitcoin Core 28.99.0
P2P Digital Currency
transaction_utils.cpp
Go to the documentation of this file.
1// Copyright (c) 2019-2020 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <coins.h>
9
11{
12 CMutableTransaction txCredit;
13 txCredit.version = 1;
14 txCredit.nLockTime = 0;
15 txCredit.vin.resize(1);
16 txCredit.vout.resize(1);
17 txCredit.vin[0].prevout.SetNull();
18 txCredit.vin[0].scriptSig = CScript() << CScriptNum(0) << CScriptNum(0);
19 txCredit.vin[0].nSequence = CTxIn::SEQUENCE_FINAL;
20 txCredit.vout[0].scriptPubKey = scriptPubKey;
21 txCredit.vout[0].nValue = nValue;
22
23 return txCredit;
24}
25
26CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CScriptWitness& scriptWitness, const CTransaction& txCredit)
27{
28 CMutableTransaction txSpend;
29 txSpend.version = 1;
30 txSpend.nLockTime = 0;
31 txSpend.vin.resize(1);
32 txSpend.vout.resize(1);
33 txSpend.vin[0].scriptWitness = scriptWitness;
34 txSpend.vin[0].prevout.hash = txCredit.GetHash();
35 txSpend.vin[0].prevout.n = 0;
36 txSpend.vin[0].scriptSig = scriptSig;
37 txSpend.vin[0].nSequence = CTxIn::SEQUENCE_FINAL;
38 txSpend.vout[0].scriptPubKey = CScript();
39 txSpend.vout[0].nValue = txCredit.vout[0].nValue;
40
41 return txSpend;
42}
43
44std::vector<CMutableTransaction> SetupDummyInputs(FillableSigningProvider& keystoreRet, CCoinsViewCache& coinsRet, const std::array<CAmount,4>& nValues)
45{
46 std::vector<CMutableTransaction> dummyTransactions;
47 dummyTransactions.resize(2);
48
49 // Add some keys to the keystore:
50 CKey key[4];
51 for (int i = 0; i < 4; i++) {
52 key[i].MakeNewKey(i % 2);
53 keystoreRet.AddKey(key[i]);
54 }
55
56 // Create some dummy input transactions
57 dummyTransactions[0].vout.resize(2);
58 dummyTransactions[0].vout[0].nValue = nValues[0];
59 dummyTransactions[0].vout[0].scriptPubKey << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG;
60 dummyTransactions[0].vout[1].nValue = nValues[1];
61 dummyTransactions[0].vout[1].scriptPubKey << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG;
62 AddCoins(coinsRet, CTransaction(dummyTransactions[0]), 0);
63
64 dummyTransactions[1].vout.resize(2);
65 dummyTransactions[1].vout[0].nValue = nValues[2];
66 dummyTransactions[1].vout[0].scriptPubKey = GetScriptForDestination(PKHash(key[2].GetPubKey()));
67 dummyTransactions[1].vout[1].nValue = nValues[3];
68 dummyTransactions[1].vout[1].scriptPubKey = GetScriptForDestination(PKHash(key[3].GetPubKey()));
69 AddCoins(coinsRet, CTransaction(dummyTransactions[1]), 0);
70
71 return dummyTransactions;
72}
73
74void BulkTransaction(CMutableTransaction& tx, int32_t target_weight)
75{
76 tx.vout.emplace_back(0, CScript() << OP_RETURN);
77 auto unpadded_weight{GetTransactionWeight(CTransaction(tx))};
78 assert(target_weight >= unpadded_weight);
79
80 // determine number of needed padding bytes by converting weight difference to vbytes
81 auto dummy_vbytes = (target_weight - unpadded_weight + (WITNESS_SCALE_FACTOR - 1)) / WITNESS_SCALE_FACTOR;
82 // compensate for the increase of the compact-size encoded script length
83 // (note that the length encoding of the unpadded output script needs one byte)
84 dummy_vbytes -= GetSizeOfCompactSize(dummy_vbytes) - 1;
85
86 // pad transaction by repeatedly appending a dummy opcode to the output script
87 tx.vout[0].scriptPubKey.insert(tx.vout[0].scriptPubKey.end(), dummy_vbytes, OP_1);
88
89 // actual weight should be at most 3 higher than target weight
90 assert(GetTransactionWeight(CTransaction(tx)) >= target_weight);
91 assert(GetTransactionWeight(CTransaction(tx)) <= target_weight + 3);
92}
93
94bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType, SignatureData& sig_data)
95{
96 assert(nIn < txTo.vin.size());
97
98 MutableTransactionSignatureCreator creator(txTo, nIn, amount, nHashType);
99
100 bool ret = ProduceSignature(provider, creator, fromPubKey, sig_data);
101 UpdateInput(txTo.vin.at(nIn), sig_data);
102 return ret;
103}
104
105bool SignSignature(const SigningProvider &provider, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType, SignatureData& sig_data)
106{
107 assert(nIn < txTo.vin.size());
108 const CTxIn& txin = txTo.vin[nIn];
109 assert(txin.prevout.n < txFrom.vout.size());
110 const CTxOut& txout = txFrom.vout[txin.prevout.n];
111
112 return SignSignature(provider, txout.scriptPubKey, txTo, nIn, txout.nValue, nHashType, sig_data);
113}
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
int ret
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:363
An encapsulated private key.
Definition: key.h:35
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
Definition: key.cpp:161
uint32_t n
Definition: transaction.h:32
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:415
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:296
const std::vector< CTxOut > vout
Definition: transaction.h:307
const Txid & GetHash() const LIFETIMEBOUND
Definition: transaction.h:343
An input of a transaction.
Definition: transaction.h:67
static const uint32_t SEQUENCE_FINAL
Setting nSequence to this value for every input in a transaction disables nLockTime/IsFinalTx().
Definition: transaction.h:81
COutPoint prevout
Definition: transaction.h:69
An output of a transaction.
Definition: transaction.h:150
CScript scriptPubKey
Definition: transaction.h:153
CAmount nValue
Definition: transaction.h:152
Fillable signing provider that keeps keys in an address->secret map.
virtual bool AddKey(const CKey &key)
A signature creator for transactions.
Definition: sign.h:40
An interface to be implemented by keystores that support signing.
void AddCoins(CCoinsViewCache &cache, const CTransaction &tx, int nHeight, bool check_for_overwrite)
Utility function to add all of a transaction's outputs to a cache.
Definition: coins.cpp:119
static int32_t GetTransactionWeight(const CTransaction &tx)
Definition: validation.h:133
static const int WITNESS_SCALE_FACTOR
Definition: consensus.h:21
@ OP_CHECKSIG
Definition: script.h:190
@ OP_1
Definition: script.h:83
@ OP_RETURN
Definition: script.h:111
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:67
constexpr unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 byt...
Definition: serialize.h:295
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
Definition: sign.cpp:502
void UpdateInput(CTxIn &input, const SignatureData &data)
Definition: sign.cpp:675
static bool GetPubKey(const SigningProvider &provider, const SignatureData &sigdata, const CKeyID &address, CPubKey &pubkey)
Definition: sign.cpp:109
A mutable version of CTransaction.
Definition: transaction.h:378
std::vector< CTxOut > vout
Definition: transaction.h:380
std::vector< CTxIn > vin
Definition: transaction.h:379
CMutableTransaction BuildSpendingTransaction(const CScript &scriptSig, const CScriptWitness &scriptWitness, const CTransaction &txCredit)
void BulkTransaction(CMutableTransaction &tx, int32_t target_weight)
std::vector< CMutableTransaction > SetupDummyInputs(FillableSigningProvider &keystoreRet, CCoinsViewCache &coinsRet, const std::array< CAmount, 4 > &nValues)
bool SignSignature(const SigningProvider &provider, const CScript &fromPubKey, CMutableTransaction &txTo, unsigned int nIn, const CAmount &amount, int nHashType, SignatureData &sig_data)
Produce a satisfying script (scriptSig or witness).
CMutableTransaction BuildCreditingTransaction(const CScript &scriptPubKey, int nValue)
assert(!tx.IsCoinBase())