Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

sign.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2015 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include <script/sign.h>
7 
8 #include <key.h>
9 #include <keystore.h>
10 #include <policy/policy.h>
11 #include <primitives/transaction.h>
12 #include <script/standard.h>
13 #include <uint256.h>
14 
15 
16 typedef std::vector<unsigned char> valtype;
17 
18 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) {}
19 
20 bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, SigVersion sigversion) const
21 {
22  CKey key;
23  if (!keystore->GetKey(address, key))
24  return false;
25 
26  uint256 hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion);
27  if (!key.Sign(hash, vchSig))
28  return false;
29  vchSig.push_back((unsigned char)nHashType);
30  return true;
31 }
32 
33 static bool Sign1(const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion)
34 {
35  std::vector<unsigned char> vchSig;
36  if (!creator.CreateSig(vchSig, address, scriptCode, sigversion))
37  return false;
38  ret.push_back(vchSig);
39  return true;
40 }
41 
42 static bool SignN(const std::vector<valtype>& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, SigVersion sigversion)
43 {
44  int nSigned = 0;
45  int nRequired = multisigdata.front()[0];
46  for (unsigned int i = 1; i < multisigdata.size()-1 && nSigned < nRequired; i++)
47  {
48  const valtype& pubkey = multisigdata[i];
49  CKeyID keyID = CPubKey(pubkey).GetID();
50  if (Sign1(keyID, creator, scriptCode, ret, sigversion))
51  ++nSigned;
52  }
53  return nSigned==nRequired;
54 }
55 
62 static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptPubKey,
63  std::vector<valtype>& ret, txnouttype& whichTypeRet, SigVersion sigversion)
64 {
65  CScript scriptRet;
66  uint160 h160;
67  ret.clear();
68 
69  std::vector<valtype> vSolutions;
70  if (!Solver(scriptPubKey, whichTypeRet, vSolutions))
71  return false;
72 
73  CKeyID keyID;
74  switch (whichTypeRet)
75  {
76  case TX_NONSTANDARD:
77  case TX_NULL_DATA:
78  return false;
79  case TX_PUBKEY:
80  keyID = CPubKey(vSolutions[0]).GetID();
81  return Sign1(keyID, creator, scriptPubKey, ret, sigversion);
82  case TX_PUBKEYHASH:
83  keyID = CKeyID(uint160(vSolutions[0]));
84  if (!Sign1(keyID, creator, scriptPubKey, ret, sigversion))
85  return false;
86  else
87  {
88  CPubKey vch;
89  creator.KeyStore().GetPubKey(keyID, vch);
90  ret.push_back(ToByteVector(vch));
91  }
92  return true;
93  case TX_SCRIPTHASH:
94  if (creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptRet)) {
95  ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
96  return true;
97  }
98  return false;
99 
100  case TX_MULTISIG:
101  ret.push_back(valtype()); // workaround CHECKMULTISIG bug
102  return (SignN(vSolutions, creator, scriptPubKey, ret, sigversion));
103 
104  default:
105  return false;
106  }
107 }
108 
109 static CScript PushAll(const std::vector<valtype>& values)
110 {
111  CScript result;
112  for(const valtype& v : values) {
113  if (v.size() == 0) {
114  result << OP_0;
115  } else if (v.size() == 1 && v[0] >= 1 && v[0] <= 16) {
116  result << CScript::EncodeOP_N(v[0]);
117  } else {
118  result << v;
119  }
120  }
121  return result;
122 }
123 
124 bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata)
125 {
126  CScript script = fromPubKey;
127  bool solved = true;
128  std::vector<valtype> result;
129  txnouttype whichType;
130  solved = SignStep(creator, script, result, whichType, SIGVERSION_BASE);
131  bool P2SH = false;
132  CScript subscript;
133 
134  if (solved && whichType == TX_SCRIPTHASH)
135  {
136  // Solver returns the subscript that needs to be evaluated;
137  // the final scriptSig is the signatures from that
138  // and then the serialized subscript:
139  script = subscript = CScript(result[0].begin(), result[0].end());
140  solved = solved && SignStep(creator, script, result, whichType, SIGVERSION_BASE) && whichType != TX_SCRIPTHASH;
141  P2SH = true;
142  }
143 
144  if (P2SH) {
145  result.push_back(std::vector<unsigned char>(subscript.begin(), subscript.end()));
146  }
147  sigdata.scriptSig = PushAll(result);
148 
149  // Test solution
150  return solved && VerifyScript(sigdata.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker());
151 }
152 
154 {
155  SignatureData data;
156  assert(tx.vin.size() > nIn);
157  data.scriptSig = tx.vin[nIn].scriptSig;
158  return data;
159 }
160 
161 void UpdateTransaction(CMutableTransaction& tx, unsigned int nIn, const SignatureData& data)
162 {
163  assert(tx.vin.size() > nIn);
164  tx.vin[nIn].scriptSig = data.scriptSig;
165 }
166 
167 bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType)
168 {
169  assert(nIn < txTo.vin.size());
170 
171  CTransaction txToConst(txTo);
172  TransactionSignatureCreator creator(&keystore, &txToConst, nIn, amount, nHashType);
173 
174  SignatureData sigdata;
175  bool ret = ProduceSignature(creator, fromPubKey, sigdata);
176  UpdateTransaction(txTo, nIn, sigdata);
177  return ret;
178 }
179 
180 bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
181 {
182  assert(nIn < txTo.vin.size());
183  CTxIn& txin = txTo.vin[nIn];
184  assert(txin.prevout.n < txFrom.vout.size());
185  const CTxOut& txout = txFrom.vout[txin.prevout.n];
186 
187  return SignSignature(keystore, txout.scriptPubKey, txTo, nIn, txout.nValue, nHashType);
188 }
189 
190 static std::vector<valtype> CombineMultisig(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
191  const std::vector<valtype>& vSolutions,
192  const std::vector<valtype>& sigs1, const std::vector<valtype>& sigs2, SigVersion sigversion)
193 {
194  // Combine all the signatures we've got:
195  std::set<valtype> allsigs;
196  for (const valtype& v : sigs1)
197  {
198  if (!v.empty())
199  allsigs.insert(v);
200  }
201  for (const valtype& v : sigs2)
202  {
203  if (!v.empty())
204  allsigs.insert(v);
205  }
206 
207  // Build a map of pubkey -> signature by matching sigs to pubkeys:
208  assert(vSolutions.size() > 1);
209  unsigned int nSigsRequired = vSolutions.front()[0];
210  unsigned int nPubKeys = vSolutions.size()-2;
211  std::map<valtype, valtype> sigs;
212  for (const valtype& sig : allsigs)
213  {
214  for (unsigned int i = 0; i < nPubKeys; i++)
215  {
216  const valtype& pubkey = vSolutions[i+1];
217  if (sigs.count(pubkey))
218  continue; // Already got a sig for this pubkey
219 
220  if (checker.CheckSig(sig, pubkey, scriptPubKey, sigversion))
221  {
222  sigs[pubkey] = sig;
223  break;
224  }
225  }
226  }
227  // Now build a merged CScript:
228  unsigned int nSigsHave = 0;
229  std::vector<valtype> result; result.push_back(valtype()); // pop-one-too-many workaround
230  for (unsigned int i = 0; i < nPubKeys && nSigsHave < nSigsRequired; i++)
231  {
232  if (sigs.count(vSolutions[i+1]))
233  {
234  result.push_back(sigs[vSolutions[i+1]]);
235  ++nSigsHave;
236  }
237  }
238  // Fill any missing with OP_0:
239  for (unsigned int i = nSigsHave; i < nSigsRequired; i++)
240  result.push_back(valtype());
241 
242  return result;
243 }
244 
245 namespace
246 {
247 struct Stacks
248 {
249  std::vector<valtype> script;
250 
251  Stacks() {}
252  explicit Stacks(const std::vector<valtype>& scriptSigStack_) : script(scriptSigStack_) {}
253  explicit Stacks(const SignatureData& data) {
255  }
256 
257  SignatureData Output() const {
258  SignatureData result;
259  result.scriptSig = PushAll(script);
260  return result;
261  }
262 };
263 }
264 
265 static Stacks CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
266  const txnouttype txType, const std::vector<valtype>& vSolutions,
267  Stacks sigs1, Stacks sigs2, SigVersion sigversion)
268 {
269  switch (txType)
270  {
271  case TX_NONSTANDARD:
272  case TX_NULL_DATA:
273  // Don't know anything about this, assume bigger one is correct:
274  if (sigs1.script.size() >= sigs2.script.size())
275  return sigs1;
276  return sigs2;
277  case TX_PUBKEY:
278  case TX_PUBKEYHASH:
279  // Signatures are bigger than placeholders or empty scripts:
280  if (sigs1.script.empty() || sigs1.script[0].empty())
281  return sigs2;
282  return sigs1;
283  case TX_SCRIPTHASH:
284  if (sigs1.script.empty() || sigs1.script.back().empty())
285  return sigs2;
286  else if (sigs2.script.empty() || sigs2.script.back().empty())
287  return sigs1;
288  else
289  {
290  // Recur to combine:
291  valtype spk = sigs1.script.back();
292  CScript pubKey2(spk.begin(), spk.end());
293 
294  txnouttype txType2;
295  std::vector<std::vector<unsigned char> > vSolutions2;
296  Solver(pubKey2, txType2, vSolutions2);
297  sigs1.script.pop_back();
298  sigs2.script.pop_back();
299  Stacks result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2, sigversion);
300  result.script.push_back(spk);
301  return result;
302  }
303  case TX_MULTISIG:
304  return Stacks(CombineMultisig(scriptPubKey, checker, vSolutions, sigs1.script, sigs2.script, sigversion));
305  default:
306  return Stacks();
307  }
308 }
309 
310 SignatureData CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
311  const SignatureData& scriptSig1, const SignatureData& scriptSig2)
312 {
313  txnouttype txType;
314  std::vector<std::vector<unsigned char> > vSolutions;
315  Solver(scriptPubKey, txType, vSolutions);
316 
317  return CombineSignatures(scriptPubKey, checker, txType, vSolutions, Stacks(scriptSig1), Stacks(scriptSig2), SIGVERSION_BASE).Output();
318 }
319 
320 namespace {
322 class DummySignatureChecker : public BaseSignatureChecker
323 {
324 public:
325  DummySignatureChecker() {}
326 
327  bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override
328  {
329  return true;
330  }
331 };
332 const DummySignatureChecker dummyChecker;
333 } // namespace
334 
336 {
337  return dummyChecker;
338 }
339 
340 bool DummySignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, SigVersion sigversion) const
341 {
342  // Create a dummy signature that is a valid DER-encoding
343  vchSig.assign(72, '\000');
344  vchSig[0] = 0x30;
345  vchSig[1] = 69;
346  vchSig[2] = 0x02;
347  vchSig[3] = 33;
348  vchSig[4] = 0x01;
349  vchSig[4 + 33] = 0x02;
350  vchSig[5 + 33] = 32;
351  vchSig[6 + 33] = 0x01;
352  vchSig[6 + 33 + 32] = SIGHASH_ALL;
353  return true;
354 }
void UpdateTransaction(CMutableTransaction &tx, unsigned int nIn, const SignatureData &data)
Definition: sign.cpp:161
SignatureData DataFromTransaction(const CMutableTransaction &tx, unsigned int nIn)
Extract signature data from a transaction, and insert it.
Definition: sign.cpp:153
unspendable OP_RETURN script that carries data
Definition: standard.h:64
static bool SignN(const std::vector< valtype > &multisigdata, const BaseSignatureCreator &creator, const CScript &scriptCode, std::vector< valtype > &ret, SigVersion sigversion)
Definition: sign.cpp:42
bool SignSignature(const CKeyStore &keystore, const CScript &fromPubKey, CMutableTransaction &txTo, unsigned int nIn, const CAmount &amount, int nHashType)
Produce a script signature for a transaction.
Definition: sign.cpp:167
static bool SignStep(const BaseSignatureCreator &creator, const CScript &scriptPubKey, std::vector< valtype > &ret, txnouttype &whichTypeRet, SigVersion sigversion)
Sign scriptPubKey using signature made with creator.
Definition: sign.cpp:62
CScript scriptSig
Definition: sign.h:63
std::vector< CTxIn > vin
Definition: transaction.h:293
Virtual base class for signature creators.
Definition: sign.h:19
static CScript PushAll(const std::vector< valtype > &values)
Definition: sign.cpp:109
A signature creator for transactions.
Definition: sign.h:34
bool ProduceSignature(const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
Definition: sign.cpp:124
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:149
bool Sign(const uint256 &hash, std::vector< unsigned char > &vchSig, uint32_t test_case=0) const
Create a DER-serialized signature.
Definition: key.cpp:192
unsigned int nIn
Definition: sign.h:36
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
static bool Sign1(const CKeyID &address, const BaseSignatureCreator &creator, const CScript &scriptCode, std::vector< valtype > &ret, SigVersion sigversion)
Definition: sign.cpp:33
const CKeyStore * keystore
Definition: sign.h:21
iterator end()
Definition: prevector.h:320
uint256 SignatureHash(const CScript &scriptCode, const CTransaction &txTo, unsigned int nIn, int nHashType, const CAmount &amount, SigVersion sigversion, const PrecomputedTransactionData *cache)
const BaseSignatureChecker & Checker() const override
Definition: sign.cpp:335
An input of a transaction.
Definition: transaction.h:70
virtual bool CreateSig(std::vector< unsigned char > &vchSig, const CKeyID &keyid, const CScript &scriptCode, SigVersion sigversion) const =0
Create a singular (non-script) signature.
const CKeyStore & KeyStore() const
Definition: sign.h:25
An encapsulated public key.
Definition: pubkey.h:30
const std::vector< CTxOut > vout
Definition: transaction.h:216
virtual bool GetKey(const CKeyID &address, CKey &keyOut) const =0
TransactionSignatureCreator(const CKeyStore *keystoreIn, const CTransaction *txToIn, unsigned int nInIn, const CAmount &amountIn, int nHashTypeIn=SIGHASH_ALL)
Definition: sign.cpp:18
bool CreateSig(std::vector< unsigned char > &vchSig, const CKeyID &keyid, const CScript &scriptCode, SigVersion sigversion) const override
Create a singular (non-script) signature.
Definition: sign.cpp:20
An output of a transaction.
Definition: transaction.h:144
bool EvalScript(std::vector< std::vector< unsigned char > > &stack, const CScript &script, unsigned int flags, const BaseSignatureChecker &checker, SigVersion sigversion, ScriptError *serror)
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
virtual bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const =0
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:35
txnouttype
Definition: standard.h:56
256-bit opaque blob.
Definition: uint256.h:123
static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS
Standard script verification flags that standard transactions will comply with.
Definition: policy.h:44
static opcodetype EncodeOP_N(int n)
Definition: script.h:583
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:389
A virtual base class for key stores.
Definition: keystore.h:19
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:20
static std::vector< valtype > CombineMultisig(const CScript &scriptPubKey, const BaseSignatureChecker &checker, const std::vector< valtype > &vSolutions, const std::vector< valtype > &sigs1, const std::vector< valtype > &sigs2, SigVersion sigversion)
Definition: sign.cpp:190
virtual bool CheckSig(const std::vector< unsigned char > &scriptSig, const std::vector< unsigned char > &vchPubKey, const CScript &scriptCode, SigVersion sigversion) const
Definition: interpreter.h:119
160-bit opaque blob.
Definition: uint256.h:112
std::vector< unsigned char > valtype
Definition: interpreter.cpp:15
std::vector< unsigned char > valtype
Definition: sign.cpp:16
static Stacks CombineSignatures(const CScript &scriptPubKey, const BaseSignatureChecker &checker, const txnouttype txType, const std::vector< valtype > &vSolutions, Stacks sigs1, Stacks sigs2, SigVersion sigversion)
Definition: sign.cpp:265
iterator begin()
Definition: prevector.h:318
A mutable version of CTransaction.
Definition: transaction.h:291
An encapsulated private key.
Definition: key.h:27
The basic transaction that is broadcasted on the network and contained in blocks. ...
Definition: transaction.h:198
bool CreateSig(std::vector< unsigned char > &vchSig, const CKeyID &keyid, const CScript &scriptCode, SigVersion sigversion) const override
Create a singular (non-script) signature.
Definition: sign.cpp:340
const CTransaction * txTo
Definition: sign.h:35
Definition: script.h:51
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const =0
virtual const BaseSignatureChecker & Checker() const =0
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:42
SigVersion
Definition: interpreter.h:109
Released under the MIT license