PIVX Core  5.6.99
P2P Digital Currency
sign.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
3 // Copyright (c) 2016-2022 The PIVX Core developers
4 // Distributed under the MIT software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #include "script/sign.h"
8 
9 #include "key.h"
10 #include "keystore.h"
11 #include "policy/policy.h"
12 #include "primitives/transaction.h"
13 #include "script/standard.h"
14 #include "uint256.h"
15 #include "util/system.h"
16 
17 typedef std::vector<unsigned char> valtype;
18 
19 TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {}
20 
21 bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const
22 {
23  CKey key;
24  if (!keystore->GetKey(address, key))
25  return false;
26 
27  uint256 hash;
28  try {
29  hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion);
30  } catch (const std::logic_error& ex) {
31  return false;
32  }
33 
34  if (!key.Sign(hash, vchSig))
35  return false;
36  vchSig.push_back((unsigned char)nHashType);
37  return true;
38 }
39 
40 static bool Sign1(const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion)
41 {
42  std::vector<unsigned char> vchSig;
43  if (!creator.CreateSig(vchSig, address, scriptCode, sigversion))
44  return false;
45  ret.emplace_back(vchSig);
46  return true;
47 }
48 
49 static bool SignN(const std::vector<valtype>& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion)
50 {
51  int nSigned = 0;
52  int nRequired = multisigdata.front()[0];
53  for (unsigned int i = 1; i < multisigdata.size()-1 && nSigned < nRequired; i++)
54  {
55  const valtype& pubkey = multisigdata[i];
56  CKeyID keyID = CPubKey(pubkey).GetID();
57  if (Sign1(keyID, creator, scriptCode, ret, sigversion))
58  ++nSigned;
59  }
60  return nSigned==nRequired;
61 }
62 
69 static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptPubKey,
70  std::vector<valtype>& ret, txnouttype& whichTypeRet, SigVersion sigversion, bool fColdStake)
71 {
72  CScript scriptRet;
73  uint160 h160;
74  ret.clear();
75 
76  std::vector<valtype> vSolutions;
77  if (!Solver(scriptPubKey, whichTypeRet, vSolutions))
78  return false;
79 
80  CKeyID keyID;
81  switch (whichTypeRet)
82  {
83  case TX_NONSTANDARD:
84  case TX_NULL_DATA:
85  return false;
86  case TX_PUBKEY:
87  keyID = CPubKey(vSolutions[0]).GetID();
88  return Sign1(keyID, creator, scriptPubKey, ret, sigversion);
89  case TX_PUBKEYHASH:
90  case TX_EXCHANGEADDR:
91  keyID = CKeyID(uint160(vSolutions[0]));
92  if (!Sign1(keyID, creator, scriptPubKey, ret, sigversion))
93  return false;
94  else
95  {
96  CPubKey vch;
97  creator.KeyStore().GetPubKey(keyID, vch);
98  ret.push_back(ToByteVector(vch));
99  }
100  return true;
101  case TX_SCRIPTHASH:
102  if (creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptRet)) {
103  ret.emplace_back(scriptRet.begin(), scriptRet.end());
104  return true;
105  }
106  return false;
107 
108  case TX_MULTISIG:
109  ret.push_back(valtype()); // workaround CHECKMULTISIG bug
110  return (SignN(vSolutions, creator, scriptPubKey, ret, sigversion));
111 
112  case TX_COLDSTAKE:
113  if (fColdStake) {
114  // sign with the cold staker key
115  keyID = CKeyID(uint160(vSolutions[0]));
116  } else {
117  // sign with the owner key
118  keyID = CKeyID(uint160(vSolutions[1]));
119  }
120  if (!Sign1(keyID, creator, scriptPubKey, ret, sigversion))
121  return error("*** %s: failed to sign with the %s key.",
122  __func__, fColdStake ? "cold staker" : "owner");
123  CPubKey vch;
124  if (!creator.KeyStore().GetPubKey(keyID, vch))
125  return error("%s : Unable to get public key from keyID", __func__);
126 
127  valtype oper;
128  oper.reserve(4);
129  oper.emplace_back((fColdStake ? (int) OP_TRUE : OP_FALSE));
130  ret.emplace_back(oper);
131  ret.emplace_back(ToByteVector(vch));
132  return true;
133  }
134  LogPrintf("*** solver no case met \n");
135  return false;
136 }
137 
138 static CScript PushAll(const std::vector<valtype>& values)
139 {
140  CScript result;
141  for (const valtype& v : values) {
142  if (v.size() == 0) {
143  result << OP_0;
144  } else if (v.size() == 1 && v[0] >= 1 && v[0] <= 16) {
145  result << CScript::EncodeOP_N(v[0]);
146  } else {
147  result << v;
148  }
149  }
150  return result;
151 }
152 
153 bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata, SigVersion sigversion, bool fColdStake, ScriptError* serror)
154 {
155  CScript script = fromPubKey;
156  bool solved = true;
157  std::vector<valtype> result;
158  txnouttype whichType;
159  solved = SignStep(creator, script, result, whichType, sigversion, fColdStake);
160  CScript subscript;
161 
162  if (solved && whichType == TX_SCRIPTHASH)
163  {
164  // Solver returns the subscript that needs to be evaluated;
165  // the final scriptSig is the signatures from that
166  // and then the serialized subscript:
167  script = subscript = CScript(result[0].begin(), result[0].end());
168  solved = solved && SignStep(creator, script, result, whichType, sigversion, fColdStake) && whichType != TX_SCRIPTHASH;
169  result.emplace_back(subscript.begin(), subscript.end());
170  }
171 
172  sigdata.scriptSig = PushAll(result);
173 
174  // Test solution
175  return solved && VerifyScript(sigdata.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker(), sigversion, serror);
176 }
177 
179 {
180  SignatureData data;
181  assert(tx.vin.size() > nIn);
182  data.scriptSig = tx.vin[nIn].scriptSig;
183  return data;
184 }
185 
186 void UpdateTransaction(CMutableTransaction& tx, unsigned int nIn, const SignatureData& data)
187 {
188  assert(tx.vin.size() > nIn);
189  tx.vin[nIn].scriptSig = data.scriptSig;
190 }
191 
192 bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType, bool fColdStake)
193 {
194  assert(nIn < txTo.vin.size());
195 
196  CTransaction txToConst(txTo);
197  TransactionSignatureCreator creator(&keystore, &txToConst, nIn, amount, nHashType);
198 
199  SignatureData sigdata;
200  bool ret = ProduceSignature(creator, fromPubKey, sigdata, txToConst.GetRequiredSigVersion(), fColdStake);
201  UpdateTransaction(txTo, nIn, sigdata);
202  return ret;
203 }
204 
205 bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType, bool fColdStake)
206 {
207  assert(nIn < txTo.vin.size());
208  CTxIn& txin = txTo.vin[nIn];
209  assert(txin.prevout.n < txFrom.vout.size());
210  const CTxOut& txout = txFrom.vout[txin.prevout.n];
211 
212  return SignSignature(keystore, txout.scriptPubKey, txTo, nIn, txout.nValue, nHashType, fColdStake);
213 }
214 
215 static std::vector<valtype> CombineMultisig(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
216  const std::vector<valtype>& vSolutions,
217  const std::vector<valtype>& sigs1, const std::vector<valtype>& sigs2, SigVersion sigversion)
218 {
219  // Combine all the signatures we've got:
220  std::set<valtype> allsigs;
221  for (const valtype& v : sigs1)
222  {
223  if (!v.empty())
224  allsigs.insert(v);
225  }
226  for (const valtype& v : sigs2)
227  {
228  if (!v.empty())
229  allsigs.insert(v);
230  }
231 
232  // Build a map of pubkey -> signature by matching sigs to pubkeys:
233  assert(vSolutions.size() > 1);
234  unsigned int nSigsRequired = vSolutions.front()[0];
235  unsigned int nPubKeys = vSolutions.size()-2;
236  std::map<valtype, valtype> sigs;
237  for (const valtype& sig : allsigs)
238  {
239  for (unsigned int i = 0; i < nPubKeys; i++)
240  {
241  const valtype& pubkey = vSolutions[i+1];
242  if (sigs.count(pubkey))
243  continue; // Already got a sig for this pubkey
244 
245  if (checker.CheckSig(sig, pubkey, scriptPubKey, sigversion))
246  {
247  sigs[pubkey] = sig;
248  break;
249  }
250  }
251  }
252  // Now build a merged CScript:
253  unsigned int nSigsHave = 0;
254  std::vector<valtype> result; result.emplace_back(); // pop-one-too-many workaround
255  for (unsigned int i = 0; i < nPubKeys && nSigsHave < nSigsRequired; i++)
256  {
257  if (sigs.count(vSolutions[i+1]))
258  {
259  result.push_back(sigs[vSolutions[i+1]]);
260  ++nSigsHave;
261  }
262  }
263  // Fill any missing with OP_0:
264  for (unsigned int i = nSigsHave; i < nSigsRequired; i++)
265  result.push_back(valtype());
266 
267  return result;
268 }
269 
270 namespace
271 {
272 struct Stacks
273 {
274  std::vector<valtype> script;
275 
276  Stacks() {}
277  explicit Stacks(const std::vector<valtype>& scriptSigStack_) : script(scriptSigStack_) {}
278  explicit Stacks(const SignatureData& data, SigVersion sigversion) {
280  }
281 
282  SignatureData Output() const {
283  SignatureData result;
284  result.scriptSig = PushAll(script);
285  return result;
286  }
287 };
288 }
289 
290 static Stacks CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
291  const txnouttype txType, const std::vector<valtype>& vSolutions,
292  Stacks sigs1, Stacks sigs2, SigVersion sigversion)
293 {
294  switch (txType)
295  {
296  case TX_NONSTANDARD:
297  case TX_NULL_DATA:
298  // Don't know anything about this, assume bigger one is correct:
299  if (sigs1.script.size() >= sigs2.script.size())
300  return sigs1;
301  return sigs2;
302  case TX_PUBKEY:
303  case TX_PUBKEYHASH:
304  case TX_EXCHANGEADDR:
305  case TX_COLDSTAKE:
306  // Signatures are bigger than placeholders or empty scripts:
307  if (sigs1.script.empty() || sigs1.script[0].empty())
308  return sigs2;
309  return sigs1;
310  case TX_SCRIPTHASH:
311  if (sigs1.script.empty() || sigs1.script.back().empty())
312  return sigs2;
313  else if (sigs2.script.empty() || sigs2.script.back().empty())
314  return sigs1;
315  else
316  {
317  // Recur to combine:
318  valtype spk = sigs1.script.back();
319  CScript pubKey2(spk.begin(), spk.end());
320 
321  txnouttype txType2;
322  std::vector<std::vector<unsigned char> > vSolutions2;
323  Solver(pubKey2, txType2, vSolutions2);
324  sigs1.script.pop_back();
325  sigs2.script.pop_back();
326  Stacks result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2, sigversion);
327  result.script.push_back(spk);
328  return result;
329  }
330  case TX_MULTISIG:
331  return Stacks(CombineMultisig(scriptPubKey, checker, vSolutions, sigs1.script, sigs2.script, sigversion));
332  }
333 
334  return Stacks();
335 }
336 
337 SignatureData CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
338  const SignatureData& scriptSig1, const SignatureData& scriptSig2)
339 {
340  txnouttype txType;
341  std::vector<std::vector<unsigned char> > vSolutions;
342  Solver(scriptPubKey, txType, vSolutions);
343 
344  return CombineSignatures(scriptPubKey, checker, txType, vSolutions, Stacks(scriptSig1, SIGVERSION_BASE), Stacks(scriptSig2, SIGVERSION_BASE), SIGVERSION_BASE).Output();
345 }
346 
347 namespace {
349 class DummySignatureChecker : public BaseSignatureChecker
350 {
351 public:
352  DummySignatureChecker() {}
353 
354  bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const
355  {
356  return true;
357  }
358 };
359 const DummySignatureChecker dummyChecker;
360 }
361 
363 {
364  return dummyChecker;
365 }
366 
367 bool DummySignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const
368 {
369  // Create a dummy signature that is a valid DER-encoding
370  vchSig.assign(72, '\000');
371  vchSig[0] = 0x30;
372  vchSig[1] = 69;
373  vchSig[2] = 0x02;
374  vchSig[3] = 33;
375  vchSig[4] = 0x01;
376  vchSig[4 + 33] = 0x02;
377  vchSig[5 + 33] = 32;
378  vchSig[6 + 33] = 0x01;
379  vchSig[6 + 33 + 32] = SIGHASH_ALL;
380  return true;
381 }
382 
383 template<typename M, typename K, typename V>
384 bool LookupHelper(const M& map, const K& key, V& value)
385 {
386  auto it = map.find(key);
387  if (it != map.end()) {
388  value = it->second;
389  return true;
390  }
391  return false;
392 }
393 
394 bool IsSolvable(const CKeyStore& store, const CScript& script, bool fColdStaking)
395 {
396  // This check is to make sure that the script we created can actually be solved for and signed by us
397  // if we were to have the private keys. This is just to make sure that the script is valid and that,
398  // if found in a transaction, we would still accept and relay that transaction. In particular,
399  DummySignatureCreator creator(&store);
400  SignatureData sigs;
401  if (ProduceSignature(creator, script, sigs, SIGVERSION_BASE, fColdStaking)) {
402  // VerifyScript check is just defensive, and should never fail.
403  assert(VerifyScript(sigs.scriptSig, script, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker(), SIGVERSION_BASE));
404  return true;
405  }
406  return false;
407 }
408 
409 bool PublicOnlySigningProvider::GetCScript(const CScriptID &scriptid, CScript& script) const
410 {
411  return m_provider->GetCScript(scriptid, script);
412 }
413 
414 bool PublicOnlySigningProvider::GetPubKey(const CKeyID &address, CPubKey& pubkey) const
415 {
416  return m_provider->GetPubKey(address, pubkey);
417 }
418 
419 bool FlatSigningProvider::GetCScript(const CScriptID& scriptid, CScript& script) const { return LookupHelper(scripts, scriptid, script); }
420 bool FlatSigningProvider::GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const { return LookupHelper(pubkeys, keyid, pubkey); }
421 bool FlatSigningProvider::GetKey(const CKeyID& keyid, CKey& key) const { return LookupHelper(keys, keyid, key); }
422 
424 {
426  ret.scripts = a.scripts;
427  ret.scripts.insert(b.scripts.begin(), b.scripts.end());
428  ret.pubkeys = a.pubkeys;
429  ret.pubkeys.insert(b.pubkeys.begin(), b.pubkeys.end());
430  ret.keys = a.keys;
431  ret.keys.insert(b.keys.begin(), b.keys.end());
432  return ret;
433 }
int64_t CAmount
Amount in PIV (Can be negative)
Definition: amount.h:13
#define M(x)
uint32_t n
Definition: transaction.h:36
virtual bool CheckSig(const std::vector< unsigned char > &scriptSig, const std::vector< unsigned char > &vchPubKey, const CScript &scriptCode, SigVersion sigversion) const
Definition: interpreter.h:104
Virtual base class for signature creators.
Definition: sign.h:58
const CKeyStore & KeyStore() const
Definition: sign.h:64
virtual const BaseSignatureChecker & Checker() const =0
const CKeyStore * keystore
Definition: sign.h:60
virtual bool CreateSig(std::vector< unsigned char > &vchSig, const CKeyID &keyid, const CScript &scriptCode, SigVersion sigversion) const =0
Create a singular (non-script) signature.
An encapsulated private key.
Definition: key.h:30
bool Sign(const uint256 &hash, std::vector< unsigned char > &vchSig, uint32_t test_case=0) const
Create a DER-serialized signature.
Definition: key.cpp:200
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:21
A virtual base class for key stores.
Definition: keystore.h:23
virtual bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const =0
virtual bool GetKey(const CKeyID &address, CKey &keyOut) const =0
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const =0
An encapsulated public key.
Definition: pubkey.h:44
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:167
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:381
static opcodetype EncodeOP_N(int n)
Definition: script.h:575
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: standard.h:24
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:244
SigVersion GetRequiredSigVersion() const
Definition: transaction.h:347
std::vector< CTxOut > vout
Definition: transaction.h:271
An input of a transaction.
Definition: transaction.h:94
COutPoint prevout
Definition: transaction.h:96
An output of a transaction.
Definition: transaction.h:137
CScript scriptPubKey
Definition: transaction.h:140
CAmount nValue
Definition: transaction.h:139
A signature creator that just produces 72-byte empty signatyres.
Definition: sign.h:94
const BaseSignatureChecker & Checker() const
Definition: sign.cpp:362
bool CreateSig(std::vector< unsigned char > &vchSig, const CKeyID &keyid, const CScript &scriptCode, SigVersion sigversion) const
Create a singular (non-script) signature.
Definition: sign.cpp:367
bool GetCScript(const CScriptID &scriptid, CScript &script) const
Definition: sign.cpp:409
bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const
Definition: sign.cpp:414
const SigningProvider * m_provider
Definition: sign.h:36
virtual bool GetCScript(const CScriptID &scriptid, CScript &script) const
Definition: sign.h:26
virtual bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const
Definition: sign.h:27
A signature creator for transactions.
Definition: sign.h:73
unsigned int nIn
Definition: sign.h:75
bool CreateSig(std::vector< unsigned char > &vchSig, const CKeyID &keyid, const CScript &scriptCode, SigVersion sigversion) const
Create a singular (non-script) signature.
Definition: sign.cpp:21
const CTransaction * txTo
Definition: sign.h:74
TransactionSignatureCreator(const CKeyStore *keystoreIn, const CTransaction *txToIn, unsigned int nInIn, const CAmount &amountIn, int nHashTypeIn=SIGHASH_ALL)
Definition: sign.cpp:19
void emplace_back(Args &&... args)
Definition: prevector.h:426
iterator begin()
Definition: prevector.h:285
iterator end()
Definition: prevector.h:287
160-bit opaque blob.
Definition: uint256.h:127
256-bit opaque blob.
Definition: uint256.h:138
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, unsigned int flags, const BaseSignatureChecker &checker, SigVersion sigversion, ScriptError *serror)
bool EvalScript(std::vector< std::vector< unsigned char > > &stack, const CScript &script, unsigned int flags, const BaseSignatureChecker &checker, SigVersion sigversion, ScriptError *serror)
uint256 SignatureHash(const CScript &scriptCode, const CTransaction &txTo, unsigned int nIn, int nHashType, const CAmount &amount, SigVersion sigversion, const PrecomputedTransactionData *cache)
std::vector< unsigned char > valtype
Definition: interpreter.cpp:17
@ SCRIPT_VERIFY_STRICTENC
Definition: interpreter.h:41
@ SIGHASH_ALL
Definition: interpreter.h:24
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:43
@ OP_FALSE
Definition: script.h:53
@ OP_TRUE
Definition: script.h:60
@ OP_0
Definition: script.h:52
enum ScriptError_t ScriptError
void UpdateTransaction(CMutableTransaction &tx, unsigned int nIn, const SignatureData &data)
Definition: sign.cpp:186
FlatSigningProvider Merge(const FlatSigningProvider &a, const FlatSigningProvider &b)
Definition: sign.cpp:423
bool LookupHelper(const M &map, const K &key, V &value)
Definition: sign.cpp:384
SignatureData DataFromTransaction(const CMutableTransaction &tx, unsigned int nIn)
Extract signature data from a transaction, and insert it.
Definition: sign.cpp:178
SignatureData CombineSignatures(const CScript &scriptPubKey, const BaseSignatureChecker &checker, const SignatureData &scriptSig1, const SignatureData &scriptSig2)
Combine two script signatures using a generic signature checker, intelligently, possibly with OP_0 pl...
Definition: sign.cpp:337
bool IsSolvable(const CKeyStore &store, const CScript &script, bool fColdStaking)
Definition: sign.cpp:394
std::vector< unsigned char > valtype
Definition: sign.cpp:17
bool SignSignature(const CKeyStore &keystore, const CScript &fromPubKey, CMutableTransaction &txTo, unsigned int nIn, const CAmount &amount, int nHashType, bool fColdStake)
Produce a script signature for a transaction.
Definition: sign.cpp:192
bool ProduceSignature(const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata, SigVersion sigversion, bool fColdStake, ScriptError *serror)
Produce a script signature using a generic signature creator.
Definition: sign.cpp:153
bool Solver(const CScript &scriptPubKey, txnouttype &typeRet, std::vector< std::vector< unsigned char > > &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
Definition: standard.cpp:90
txnouttype
Definition: standard.h:46
@ TX_PUBKEYHASH
Definition: standard.h:50
@ TX_PUBKEY
Definition: standard.h:49
@ TX_NULL_DATA
Definition: standard.h:53
@ TX_COLDSTAKE
Definition: standard.h:54
@ TX_SCRIPTHASH
Definition: standard.h:51
@ TX_NONSTANDARD
Definition: standard.h:47
@ TX_MULTISIG
Definition: standard.h:52
@ TX_EXCHANGEADDR
Definition: standard.h:55
A mutable version of CTransaction.
Definition: transaction.h:409
std::vector< CTxIn > vin
Definition: transaction.h:410
bool GetPubKey(const CKeyID &keyid, CPubKey &pubkey) const override
Definition: sign.cpp:420
bool GetKey(const CKeyID &keyid, CKey &key) const override
Definition: sign.cpp:421
std::map< CKeyID, CPubKey > pubkeys
Definition: sign.h:47
std::map< CKeyID, CKey > keys
Definition: sign.h:48
std::map< CScriptID, CScript > scripts
Definition: sign.h:46
bool GetCScript(const CScriptID &scriptid, CScript &script) const override
Definition: sign.cpp:419
CScript scriptSig
Definition: sign.h:102
bool error(const char *fmt, const Args &... args)
Definition: system.h:77
SigVersion
Definition: transaction.h:26
@ SIGVERSION_BASE
Definition: transaction.h:27