PRCYCoin  2.0.0.7rc1
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 // 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 
9 #include "key.h"
10 #include "keystore.h"
11 #include "script/standard.h"
12 #include "uint256.h"
13 #include "util.h"
14 
15 
16 typedef std::vector<unsigned char> valtype;
17 
18 bool Sign1(const CKeyID &address, const CKeyStore &keystore, uint256 hash, int nHashType, CScript &scriptSigRet) {
19  CKey key;
20  if (!keystore.GetKey(address, key))
21  return false;
22 
23  std::vector<unsigned char> vchSig;
24  if (!key.Sign(hash, vchSig))
25  return false;
26  vchSig.push_back((unsigned char) nHashType);
27  scriptSigRet << vchSig;
28 
29  return true;
30 }
31 
32 bool SignN(const std::vector<valtype>& multisigdata, const CKeyStore& keystore, uint256 hash, int nHashType, CScript& scriptSigRet) {
33  int nSigned = 0;
34  int nRequired = multisigdata.front()[0];
35  for (unsigned int i = 1; i < multisigdata.size() - 1 && nSigned < nRequired; i++) {
36  const valtype &pubkey = multisigdata[i];
37  CKeyID keyID = CPubKey(pubkey).GetID();
38  if (Sign1(keyID, keystore, hash, nHashType, scriptSigRet))
39  ++nSigned;
40  }
41  return nSigned == nRequired;
42 }
43 
50 bool Solver(const CKeyStore &keystore, const CScript &scriptPubKey, uint256 hash, int nHashType,
51  CScript &scriptSigRet, txnouttype &whichTypeRet) {
52  scriptSigRet.clear();
53 
54  std::vector<valtype> vSolutions;
55  if (!Solver(scriptPubKey, whichTypeRet, vSolutions)) {
56  LogPrintf("*** solver solver failed \n");
57  return false;
58  }
59 
60  CKeyID keyID;
61  switch (whichTypeRet) {
62  case TX_NONSTANDARD:
63  case TX_NULL_DATA: {
64  LogPrintf("*** null data \n");
65  return false;
66  }
67  case TX_PUBKEY:
68  keyID = CPubKey(vSolutions[0]).GetID();
69  if (!Sign1(keyID, keystore, hash, nHashType, scriptSigRet)) {
70  LogPrintf("*** Sign1 failed \n");
71  return false;
72  }
73  return true;
74  case TX_PUBKEYHASH:
75  keyID = CKeyID(uint160(vSolutions[0]));
76  if (!Sign1(keyID, keystore, hash, nHashType, scriptSigRet)) {
77  LogPrintf("*** solver failed to sign \n");
78  return false;
79  } else {
80  CPubKey vch;
81  keystore.GetPubKey(keyID, vch);
82  scriptSigRet << ToByteVector(vch);
83  }
84  return true;
85  case TX_SCRIPTHASH:
86  return keystore.GetCScript(uint160(vSolutions[0]), scriptSigRet);
87 
88  case TX_MULTISIG:
89  scriptSigRet << OP_0; // workaround CHECKMULTISIG bug
90  return (SignN(vSolutions, keystore, hash, nHashType, scriptSigRet));
91  }
92  LogPrintf("*** solver no case met \n");
93  return false;
94 }
95 
96 bool SignSignature(const CKeyStore &keystore, const CScript &fromPubKey, CMutableTransaction &txTo, unsigned int nIn,
97  int nHashType) {
98  assert(nIn < txTo.vin.size());
99  CTxIn &txin = txTo.vin[nIn];
100 
101  // Leave out the signature from the hash, since a signature can't sign itself.
102  // The checksig op will also drop the signatures from its hash.
103  uint256 hash = SignatureHash(fromPubKey, txTo, nIn, nHashType);
104 
105  txnouttype whichType;
106  if (!Solver(keystore, fromPubKey, hash, nHashType, txin.scriptSig, whichType))
107  return false;
108 
109  if (whichType == TX_SCRIPTHASH) {
110  // Solver returns the subscript that need to be evaluated;
111  // the final scriptSig is the signatures from that
112  // and then the serialized subscript:
113  CScript subscript = txin.scriptSig;
114 
115  // Recompute txn hash using subscript in place of scriptPubKey:
116  uint256 hash2 = SignatureHash(subscript, txTo, nIn, nHashType);
117 
118  txnouttype subType;
119  bool fSolved =
120  Solver(keystore, subscript, hash2, nHashType, txin.scriptSig, subType) && subType != TX_SCRIPTHASH;
121  // Append serialized subscript whether or not it is completely signed:
122  txin.scriptSig << valtype(subscript.begin(), subscript.end());
123  if (!fSolved) return false;
124  }
125 
126  // Test solution
127  if (VerifyScript(txin.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS,
128  MutableTransactionSignatureChecker(&txTo, nIn))) {
129  LogPrintf("%s: successfully verified scriptSig=%s, fromPubKey=%s, txTo=%s\n", __func__, txin.scriptSig.ToString(), fromPubKey.ToString(), txTo.GetHash().GetHex());
130  return true;
131  }
132  return false;
133 }
134 
135 bool SignSignature(const CKeyStore &keystore, const CTransaction &txFrom, CMutableTransaction &txTo, unsigned int nIn,
136  int nHashType) {
137  assert(nIn < txTo.vin.size());
138  CTxIn &txin = txTo.vin[nIn];
139  assert(txin.prevout.n < txFrom.vout.size());
140  const CTxOut &txout = txFrom.vout[txin.prevout.n];
141 
142  bool ret = SignSignature(keystore, txout.scriptPubKey, txTo, nIn, nHashType);
143  return ret;
144 }
145 
146 static CScript PushAll(const std::vector<valtype>& values) {
147  CScript result;
148  for (const valtype &v : values)
149  result << v;
150  return result;
151 }
152 
153 static CScript CombineMultisig(const CScript &scriptPubKey, const CTransaction &txTo, unsigned int nIn,
154  const std::vector<valtype>& vSolutions,
155  const std::vector<valtype>& sigs1, const std::vector<valtype>& sigs2) {
156  // Combine all the signatures we've got:
157  std::set<valtype> allsigs;
158  for (const valtype &v : sigs1)
159  {
160  if (!v.empty())
161  allsigs.insert(v);
162  }
163  for (const valtype &v : sigs2)
164  {
165  if (!v.empty())
166  allsigs.insert(v);
167  }
168 
169  // Build a map of pubkey -> signature by matching sigs to pubkeys:
170  assert(vSolutions.size() > 1);
171  unsigned int nSigsRequired = vSolutions.front()[0];
172  unsigned int nPubKeys = vSolutions.size() - 2;
173  std::map<valtype, valtype> sigs;
174  for (const valtype &sig : allsigs)
175  {
176  for (unsigned int i = 0; i < nPubKeys; i++) {
177  const valtype &pubkey = vSolutions[i + 1];
178  if (sigs.count(pubkey))
179  continue; // Already got a sig for this pubkey
180 
181  if (TransactionSignatureChecker(&txTo, nIn).CheckSig(sig, pubkey, scriptPubKey)) {
182  sigs[pubkey] = sig;
183  break;
184  }
185  }
186  }
187  // Now build a merged CScript:
188  unsigned int nSigsHave = 0;
189  CScript result;
190  result << OP_0; // pop-one-too-many workaround
191  for (unsigned int i = 0; i < nPubKeys && nSigsHave < nSigsRequired; i++) {
192  if (sigs.count(vSolutions[i + 1])) {
193  result << sigs[vSolutions[i + 1]];
194  ++nSigsHave;
195  }
196  }
197  // Fill any missing with OP_0:
198  for (unsigned int i = nSigsHave; i < nSigsRequired; i++)
199  result << OP_0;
200 
201  return result;
202 }
203 
204 static CScript CombineSignatures(const CScript &scriptPubKey, const CTransaction &txTo, unsigned int nIn,
205  const txnouttype txType, const std::vector<valtype>& vSolutions,
206  std::vector<valtype>& sigs1, std::vector<valtype>& sigs2) {
207  switch (txType) {
208  case TX_NONSTANDARD:
209  case TX_NULL_DATA:
213  // Don't know anything about this, assume bigger one is correct:
214  if (sigs1.size() >= sigs2.size())
215  return PushAll(sigs1);
216  return PushAll(sigs2);
217  case TX_PUBKEY:
218  case TX_PUBKEYHASH:
219  // Signatures are bigger than placeholders or empty scripts:
220  if (sigs1.empty() || sigs1[0].empty())
221  return PushAll(sigs2);
222  return PushAll(sigs1);
223  case TX_SCRIPTHASH:
224  if (sigs1.empty() || sigs1.back().empty())
225  return PushAll(sigs2);
226  else if (sigs2.empty() || sigs2.back().empty())
227  return PushAll(sigs1);
228  else {
229  // Recur to combine:
230  valtype spk = sigs1.back();
231  CScript pubKey2(spk.begin(), spk.end());
232 
233  txnouttype txType2;
234  std::vector<std::vector<unsigned char> > vSolutions2;
235  Solver(pubKey2, txType2, vSolutions2);
236  sigs1.pop_back();
237  sigs2.pop_back();
238  CScript result = CombineSignatures(pubKey2, txTo, nIn, txType2, vSolutions2, sigs1, sigs2);
239  result << spk;
240  return result;
241  }
242  case TX_MULTISIG:
243  return CombineMultisig(scriptPubKey, txTo, nIn, vSolutions, sigs1, sigs2);
244  }
245 
246  return CScript();
247 }
248 
249 CScript CombineSignatures(const CScript &scriptPubKey, const CTransaction &txTo, unsigned int nIn,
250  const CScript &scriptSig1, const CScript &scriptSig2) {
251  txnouttype txType;
252  std::vector<std::vector<unsigned char> > vSolutions;
253  Solver(scriptPubKey, txType, vSolutions);
254 
255  std::vector<valtype> stack1;
257  std::vector<valtype> stack2;
259 
260  return CombineSignatures(scriptPubKey, txTo, nIn, txType, vSolutions, stack1, stack2);
261 }
CTxIn
An input of a transaction.
Definition: transaction.h:83
CKeyStore
A virtual base class for key stores.
Definition: keystore.h:21
CMutableTransaction::vin
std::vector< CTxIn > vin
Definition: transaction.h:387
OP_0
@ OP_0
Definition: script.h:41
Sign1
bool Sign1(const CKeyID &address, const CKeyStore &keystore, uint256 hash, int nHashType, CScript &scriptSigRet)
Definition: sign.cpp:18
prevector::insert
iterator insert(iterator pos, const T &value)
Definition: prevector.h:343
transaction.h
base_uint::GetHex
std::string GetHex() const
Definition: arith_uint256.cpp:155
uint256.h
ToByteVector
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:32
BaseSignatureChecker
Definition: interpreter.h:88
CKeyStore::GetPubKey
virtual bool GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
Definition: keystore.cpp:13
CKeyID
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:29
TX_NONSTANDARD
@ TX_NONSTANDARD
Definition: standard.h:59
CScript::clear
void clear()
Definition: script.h:634
MutableTransactionSignatureChecker
Definition: interpreter.h:119
CTransaction
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:269
TX_PUBKEYHASH
@ TX_PUBKEYHASH
Definition: standard.h:62
prevector::end
iterator end()
Definition: prevector.h:292
TX_MULTISIG
@ TX_MULTISIG
Definition: standard.h:64
TransactionSignatureChecker
Definition: interpreter.h:104
CKeyStore::GetCScript
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const =0
CTxOut
An output of a transaction.
Definition: transaction.h:164
CTransaction::vout
std::vector< CTxOut > vout
Definition: transaction.h:286
CTxOut::scriptPubKey
CScript scriptPubKey
Definition: transaction.h:168
TX_PUBKEY
@ TX_PUBKEY
Definition: standard.h:61
TX_SCRIPTHASH
@ TX_SCRIPTHASH
Definition: standard.h:63
SignatureHash
uint256 SignatureHash(const CScript &scriptCode, const CTransaction &txTo, unsigned int nIn, int nHashType)
Definition: interpreter.cpp:1077
sign.h
LogPrintf
#define LogPrintf(...)
Definition: logging.h:147
standard.h
keystore.h
uint256
256-bit unsigned big integer.
Definition: uint256.h:38
TX_NULL_DATA
@ TX_NULL_DATA
Definition: standard.h:65
CScript
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:363
EvalScript
bool EvalScript(std::vector< std::vector< unsigned char > > &stack, const CScript &script, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
Definition: interpreter.cpp:241
VerifyScript
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
Definition: interpreter.cpp:1163
SignN
bool SignN(const std::vector< valtype > &multisigdata, const CKeyStore &keystore, uint256 hash, int nHashType, CScript &scriptSigRet)
Definition: sign.cpp:32
key.h
CKeyStore::GetKey
virtual bool GetKey(const CKeyID &address, CKey &keyOut) const =0
uint160
160-bit unsigned big integer.
Definition: uint256.h:27
CPubKey
An encapsulated public key.
Definition: pubkey.h:37
CKey
An encapsulated private key.
Definition: key.h:39
COutPoint::n
uint32_t n
Definition: transaction.h:40
Solver
bool Solver(const CKeyStore &keystore, const CScript &scriptPubKey, uint256 hash, int nHashType, CScript &scriptSigRet, txnouttype &whichTypeRet)
Sign scriptPubKey with private keys stored in keystore, given transaction hash and hash type.
Definition: sign.cpp:50
key
CKey key
Definition: bip38tooldialog.cpp:173
CScript::ToString
std::string ToString() const
Definition: script.cpp:266
CKey::Sign
bool Sign(const uint256 &hash, std::vector< unsigned char > &vchSig, uint32_t test_case=0) const
Create a DER-serialized signature.
Definition: key.cpp:91
CTxIn::prevout
COutPoint prevout
Definition: transaction.h:86
SignSignature
bool SignSignature(const CKeyStore &keystore, const CScript &fromPubKey, CMutableTransaction &txTo, unsigned int nIn, int nHashType)
Definition: sign.cpp:96
CTxIn::scriptSig
CScript scriptSig
Definition: transaction.h:87
prevector::begin
iterator begin()
Definition: prevector.h:290
SCRIPT_VERIFY_STRICTENC
@ SCRIPT_VERIFY_STRICTENC
Definition: interpreter.h:41
valtype
std::vector< unsigned char > valtype
Definition: interpreter.cpp:19
txnouttype
txnouttype
Definition: standard.h:57
CMutableTransaction::GetHash
uint256 GetHash() const
Compute the hash of this CMutableTransaction.
Definition: transaction.cpp:93
CMutableTransaction
A mutable version of CTransaction.
Definition: transaction.h:384
CombineSignatures
CScript CombineSignatures(const CScript &scriptPubKey, const CTransaction &txTo, unsigned int nIn, const CScript &scriptSig1, const CScript &scriptSig2)
Given two sets of signatures for scriptPubKey, possibly with OP_0 placeholders, combine them intellig...
Definition: sign.cpp:249
valtype
std::vector< unsigned char > valtype
Definition: sign.cpp:16
CPubKey::GetID
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:143