]> Git Repo - VerusCoin.git/blob - src/script/sign.cpp
Currency launch and chain import/export updates
[VerusCoin.git] / src / script / sign.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or https://www.opensource.org/licenses/mit-license.php .
5
6 #include "script/sign.h"
7
8 #include "primitives/transaction.h"
9 #include "key.h"
10 #include "keystore.h"
11 #include "script/standard.h"
12 #include "uint256.h"
13 #include "cc/CCinclude.h"
14 #include "cc/eval.h"
15 #include "key_io.h"
16 #include "pbaas/identity.h"
17
18 #include <boost/foreach.hpp>
19
20 using namespace std;
21
22 typedef std::vector<unsigned char> valtype;
23
24 TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, const CScript &scriptPubKey, uint32_t spendHeight, int nHashTypeIn) 
25     : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn, &scriptPubKey, keystoreIn, spendHeight) {}
26
27 TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) 
28     : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {}
29
30 bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char> &vchSig, const CKeyID& address, const CScript& scriptCode, uint32_t consensusBranchId, CKey *pprivKey, void *extraData) const
31 {
32     CKey key;
33     if (pprivKey)
34         key = *pprivKey;
35     else if (!keystore || !keystore->GetKey(address, key))
36         return false;
37
38     uint256 hash;
39     try {
40         hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, consensusBranchId);
41     } catch (logic_error ex) {
42         return false;
43     }
44
45     COptCCParams p;
46     if (scriptCode.IsPayToCryptoCondition(p))
47     {
48         if (p.IsValid() && p.version >= p.VERSION_V3)
49         {
50             CSmartTransactionSignatures signatures(nHashType, std::map<uint160, CSmartTransactionSignature>());
51             if (vchSig.size())
52             {
53                 signatures = CSmartTransactionSignatures(vchSig);
54                 if (!signatures.IsValid())
55                 {
56                     return false;
57                 }
58             }
59             unsigned char *onesig;
60             if (!cc_MakeSecp256k1Signature(hash.begin(), key.begin(), &onesig))
61             {
62                 return false;
63             }
64             CSmartTransactionSignature signature(CSmartTransactionSignature::SIGTYPE_SECP256K1, key.GetPubKey(), std::vector<unsigned char>(onesig, onesig + CSmartTransactionSignature::SIGTYPE_SECP256K1_LEN));
65             free(onesig);
66             signatures.AddSignature(signature);
67             vchSig = signatures.AsVector();
68
69
70             /*
71             printf("signatures: %s\n", signatures.ToUniValue().write().c_str());
72             CC *cc = (CC *)extraData;
73             if (!cc || cc_signTreeSecp256k1Msg32(cc, key.begin(), hash.begin()) == 0)
74                 return false;
75             char *jsonCondStr = cc_conditionToJSONString(cc);
76             if (jsonCondStr)
77             {
78                 printf("Signed condition: %s\n", jsonCondStr);
79                 cJSON_free(jsonCondStr);
80             }
81             */
82         }
83         else
84         {
85             CC *cc = (CC *)extraData;
86
87             if (!cc || cc_signTreeSecp256k1Msg32(cc, key.begin(), hash.begin()) == 0)
88                 return false;
89             vchSig = CCSigVec(cc);
90         }
91         return true;
92     }
93     else
94     {
95         if (!key.Sign(hash, vchSig))
96             return false;
97     }
98     vchSig.push_back((unsigned char)nHashType);
99     return true;
100 }
101
102 static bool Sign1(const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, uint32_t consensusBranchId)
103 {
104     vector<unsigned char> vchSig;
105     if (!creator.CreateSig(vchSig, address, scriptCode, consensusBranchId))
106         return false;
107     ret.push_back(vchSig);
108     return true;
109 }
110
111 static bool SignN(const vector<valtype>& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector<valtype>& ret, uint32_t consensusBranchId)
112 {
113     int nSigned = 0;
114     int nRequired = multisigdata.front()[0];
115     for (unsigned int i = 1; i < multisigdata.size()-1 && nSigned < nRequired; i++)
116     {
117         const valtype& pubkey = multisigdata[i];
118         CKeyID keyID = CPubKey(pubkey).GetID();
119         if (Sign1(keyID, creator, scriptCode, ret, consensusBranchId))
120             ++nSigned;
121     }
122     return nSigned==nRequired;
123 }
124
125 CC *CCcond1of2(uint8_t evalcode,CPubKey pk1,CPubKey pk2)
126 {
127     std::vector<CC*> pks;
128     pks.push_back(CCNewSecp256k1(pk1));
129     pks.push_back(CCNewSecp256k1(pk2));
130     CC *condCC = CCNewEval(E_MARSHAL(ss << evalcode));
131     CC *Sig = CCNewThreshold(1, pks);
132     return CCNewThreshold(2, {condCC, Sig});
133 }
134
135 CC *CCcond1(uint8_t evalcode,CPubKey pk)
136 {
137     std::vector<CC*> pks;
138     pks.push_back(CCNewSecp256k1(pk));
139     CC *condCC = CCNewEval(E_MARSHAL(ss << evalcode));
140     CC *Sig = CCNewThreshold(1, pks);
141     return CCNewThreshold(2, {condCC, Sig});
142 }
143
144 CC *CCcond1(uint8_t evalcode, CTxDestination dest)
145 {
146     CPubKey pk = boost::apply_visitor<GetPubKeyForPubKey>(GetPubKeyForPubKey(), dest);
147     std::vector<CC*> pks;
148     if (pk.IsValid())
149     {
150         pks.push_back(CCNewSecp256k1(pk));
151     }
152     else
153     {
154         pks.push_back(CCNewHashedSecp256k1(CKeyID(GetDestinationID(dest))));
155     }
156     CC *condCC = CCNewEval(E_MARSHAL(ss << evalcode));
157     CC *Sig = CCNewThreshold(1, pks);
158     return CCNewThreshold(2, {condCC, Sig});
159 }
160
161 CC *CCcondAny(uint8_t evalcode, std::vector<CTxDestination> dests)
162 {
163     std::vector<CC*> pks;
164     for (auto dest : dests)
165     {
166         CPubKey pk = boost::apply_visitor<GetPubKeyForPubKey>(GetPubKeyForPubKey(), dest);
167         if (pk.IsValid())
168         {
169             pks.push_back(CCNewSecp256k1(pk));
170         }
171         else
172         {
173             pks.push_back(CCNewHashedSecp256k1(CKeyID(GetDestinationID(dest))));
174         }
175     }
176
177     CC *condCC = CCNewEval(E_MARSHAL(ss << evalcode));
178     CC *Sig = CCNewThreshold(1, pks);
179     return CCNewThreshold(2, {condCC, Sig});
180 }
181
182 CC *MakeCCcondMofN(uint8_t evalcode, const std::vector<CTxDestination> &dests, int M)
183 {
184     std::vector<CC*> pks;
185     for (auto dest : dests)
186     {
187         CPubKey pk = boost::apply_visitor<GetPubKeyForPubKey>(GetPubKeyForPubKey(), dest);
188         if (pk.IsValid())
189         {
190             pks.push_back(CCNewSecp256k1(pk));
191         }
192         else
193         {
194             pks.push_back(CCNewHashedSecp256k1(CKeyID(GetDestinationID(dest))));
195         }
196     }
197
198     if (M > pks.size())
199     {
200         M = pks.size();
201     }
202
203     CC *condCC = CCNewEval(E_MARSHAL(ss << evalcode));
204     CC *Sig = CCNewThreshold(M, pks);
205     return CCNewThreshold(2, {condCC, Sig});
206 }
207
208 CC *MakeCCcondOneSig(const CTxDestination &dest)
209 {
210     //printf("making condition with ID: %s\n", GetDestinationID(dest).GetHex().c_str());
211
212     CPubKey pk = boost::apply_visitor<GetPubKeyForPubKey>(GetPubKeyForPubKey(), dest);
213     if (pk.IsValid())
214     {
215         return CCNewSecp256k1(pk);
216     }
217     else
218     {
219         return CCNewHashedSecp256k1(CKeyID(GetDestinationID(dest)));
220     }
221 }
222
223 CC *MakeCCcondMofN(const std::vector<CTxDestination> &dests, int M)
224 {
225     std::vector<CC*> pks;
226     for (auto dest : dests)
227     {
228         pks.push_back(MakeCCcondOneSig(dest));
229         if (!pks.back())
230         {
231             pks.pop_back();
232         }
233     }
234
235     if (M > pks.size())
236     {
237         M = pks.size();
238     }
239     return CCNewThreshold(M, pks);
240 }
241
242 CC *MakeCCcondMofN(const std::vector<CC*> &conditions, int M)
243 {
244     if (M > conditions.size())
245     {
246         M = conditions.size();
247     }
248
249     return CCNewThreshold(M, conditions);
250 }
251
252 CC *MakeCCcondMofN(uint8_t evalcode, const std::vector<CC*> &conditions, int M)
253 {
254     if (evalcode == EVAL_NONE)
255     {
256         return MakeCCcondMofN(conditions, M);
257     }
258
259     if (M > conditions.size())
260     {
261         M = conditions.size();
262     }
263
264     CC *condCC = CCNewEval(E_MARSHAL(ss << evalcode));
265     CC *Sig = CCNewThreshold(M, conditions);
266     return CCNewThreshold(2, {condCC, Sig});
267 }
268
269 // TOBJ is CConditionObj of a CC output type
270 template <typename TOBJ>
271 CC *MakeMofNCC(TOBJ &conditionObj)
272 {
273     return MakeCCcondMofN(conditionObj.evalCode, conditionObj.dests, conditionObj.m);
274 }
275
276 template <typename TOBJ1, typename TOBJ2>
277 CC *MakeMofNCC(int M, TOBJ1 &condition1, TOBJ2 &condition2)
278 {
279     if (M > 2) M = 2;
280     std::vector<CC*> conditions({MakeCCcondMofN(condition1.evalCode, condition1.dests, condition1.m), MakeCCcondMofN(condition2.evalCode, condition2.dests, condition2.m)});
281     return CCNewThreshold(M, conditions);
282 }
283
284 template <typename TOBJ1, typename TOBJ2, typename TOBJ3>
285 CC *MakeMofNCC(int M, TOBJ1 &condition1, TOBJ2 &condition2, TOBJ3 &condition3)
286 {
287     if (M > 3) M = 3;
288     std::vector<CC*> conditions({MakeCCcondMofN(condition1.evalCode, condition1.dests, condition1.m), MakeCCcondMofN(condition2.evalCode, condition2.dests, condition2.m), MakeCCcondMofN(condition3.evalCode, condition3.dests, condition3.m)});
289     return CCNewThreshold(M, conditions);
290 }
291
292 template <typename TOBJ1, typename TOBJ2, typename TOBJ3, typename TOBJ4>
293 CC *MakeMofNCC(int M, TOBJ1 &condition1, TOBJ2 &condition2, TOBJ3 &condition3, TOBJ4 &condition4)
294 {
295     if (M > 4) M = 4;
296     std::vector<CC*> conditions({MakeCCcondMofN(condition1.evalCode, condition1.dests, condition1.m), 
297                                  MakeCCcondMofN(condition2.evalCode, condition2.dests, condition2.m), 
298                                  MakeCCcondMofN(condition3.evalCode, condition3.dests, condition3.m), 
299                                  MakeCCcondMofN(condition4.evalCode, condition4.dests, condition4.m)});
300     return CCNewThreshold(M, conditions);
301 }
302
303 CScript _CCPubKey(const CC *cond)
304 {
305     unsigned char buf[2000];
306     size_t len = cc_conditionBinary(cond, buf, 2000);
307     return CScript() << std::vector<unsigned char>(buf, buf+len) << OP_CHECKCRYPTOCONDITION;
308 }
309
310 CIdentity LookupIdentity(const BaseSignatureCreator& creator, const CIdentityID &idID)
311 {
312     std::pair<CIdentityMapKey, CIdentityMapValue> identity;
313     COptCCParams p;
314     //printf("Looking up %s identity\n", EncodeDestination(CTxDestination(idID)).c_str());
315     if (creator.IsKeystoreValid() && 
316         creator.KeyStore().GetIdentity(idID, identity) && 
317         identity.second.IsValidUnrevoked())
318     {
319         return identity.second;
320     }
321     return CIdentity();
322 }
323
324 static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scriptPubKey, vector<valtype> &vSolutions,
325                        vector<valtype>& ret, uint32_t consensusBranchId)
326 {
327     CScript subScript;
328     std::vector<CTxDestination> vPK;
329     std::vector<valtype> vParams = std::vector<valtype>();
330     COptCCParams p;
331
332     // get information to sign with
333     CCcontract_info C;
334
335     if (scriptPubKey.IsPayToCryptoCondition(p) && p.IsValid() && p.n >= 1 && p.vKeys.size() >= p.n)
336     {
337         if (p.version >= p.VERSION_V3 && p.vData.size())
338         {
339             // decode the entire crypto-condition
340             COptCCParams master = COptCCParams(p.vData.back());
341             bool ccValid = master.IsValid();
342             std::vector<CConditionObj<COptCCParams>> conditions;
343             std::map<uint160, CTxDestination> destMap;  // all destinations
344             std::map<uint160, CKey> privKeyMap;         // private keys located for each id
345             std::vector<CC*> ccs;
346
347             CIdentity identity;
348             bool identitySpend = false;
349             uint160 idID;
350             if (p.evalCode == EVAL_IDENTITY_PRIMARY)
351             {
352                 identity = CIdentity(p.vData[0]);
353                 identitySpend = identity.IsValid();
354                 idID = identity.GetID();
355             }
356
357             // if we are sign-only, "p" will have no data object of its own, so we do not have to subtract 1
358             int loopMax = p.evalCode ? p.vData.size() - 1 : p.vData.size();
359
360             for (int i = 0; ccValid && i < loopMax; i++)
361             {
362                 // "p", our first COptCCParams object will be considered first, then nested objects after
363                 COptCCParams oneP = i ? COptCCParams(p.vData[i]) : p;
364                 ccValid = oneP.IsValid();
365                 std::vector<CC*> vCC;
366                 if (ccValid)
367                 {
368                     conditions.push_back(CConditionObj<COptCCParams>(oneP.evalCode, oneP.vKeys, oneP.m));
369
370                     CCcontract_info C;
371                     if (p.evalCode && CCinit(&C, p.evalCode))
372                     {
373                         CPubKey evalPK(ParseHex(C.CChexstr));
374                         CKey priv;
375                         std::vector<unsigned char> vch(&(C.CCpriv[0]), C.CCpriv + sizeof(C.CCpriv));
376                         priv.Set(vch.begin(), vch.end(), true);
377                         privKeyMap[evalPK.GetID()] = priv;
378                     }
379                     else
380                     {
381                         if (p.evalCode)
382                         {
383                             return false;
384                         }
385                     }
386
387                     for (auto &dest : oneP.vKeys)
388                     {
389                         uint160 destId = GetDestinationID(dest);
390                         if (dest.which() == COptCCParams::ADDRTYPE_ID)
391                         {
392                             // lookup identity, we must have all registered target identity scripts in our keystore, or we try as if they are a keyID, which will be the same
393                             // if revoked or undefined
394                             CIdentity id;
395
396                             // if this is an identity self spend, we always use the absolute latest version to control it ,mcf 
397                             if (destId == idID)
398                             {
399                                 id = identity;
400                             }
401
402                             if ((!id.IsValid() && !(id = LookupIdentity(creator, CIdentityID(destId))).IsValid()) || id.IsRevoked())
403                             {
404                                 destMap[destId] = dest;
405                                 vCC.push_back(MakeCCcondOneSig(CKeyID(GetDestinationID(dest))));
406                             }
407                             else
408                             {
409                                 for (auto oneKey : id.primaryAddresses)
410                                 {
411                                     destMap[GetDestinationID(oneKey)] = oneKey;
412                                 }
413                                 if (id.primaryAddresses.size() == 1)
414                                 {
415                                     vCC.push_back(MakeCCcondOneSig(CKeyID(GetDestinationID(id.primaryAddresses[0]))));
416                                 }
417                                 else
418                                 {
419                                     vCC.push_back(MakeCCcondMofN(id.primaryAddresses, id.minSigs));
420                                 }
421                             }
422                         }
423                         else
424                         {
425                             destMap[destId] = dest;
426                             vCC.push_back(MakeCCcondOneSig(dest));
427                         }
428                     }
429
430                     if (oneP.evalCode != EVAL_NONE)
431                     {
432                         ccs.push_back(MakeCCcondMofN(oneP.evalCode, vCC, oneP.m ? oneP.m : 1));
433                     }
434                     else
435                     {
436                         if (vCC.size() == 1)
437                         {
438                             ccs.push_back(vCC[0]);
439                         }
440                         else
441                         {
442                             ccs.push_back(MakeCCcondMofN(vCC, oneP.m));
443                         }
444                     }
445                 }
446             }
447
448             CC *outputCC = nullptr;
449
450             if (ccValid)
451             {
452                 assert(ccs.size() == conditions.size());
453                 if (ccs.size() == 1)
454                 {
455                     if (master.evalCode)
456                     {
457                         outputCC = MakeCCcondMofN(master.evalCode, ccs, master.m);
458                     }
459                     else
460                     {
461                         outputCC = ccs[0];
462                     }
463                 }
464                 else
465                 {
466                     if (master.evalCode)
467                     {
468                         outputCC = MakeCCcondMofN(master.evalCode, ccs, master.m);
469                     }
470                     else
471                     {
472                         outputCC = MakeCCcondMofN(ccs, master.m);
473                     }
474                 }
475             }
476
477             // loop through all private keys we have and sign with each of them
478             if (outputCC)
479             {
480                 // loop through keys and sign with all that we have
481                 std::map<CKeyID, CKey> privKeys;
482                 for (auto destPair : destMap)
483                 {
484                     //printf("Checking for private key of destination: %s ", EncodeDestination(destPair.second).c_str());
485
486                     CKey privKey;
487                     auto dit = privKeyMap.find(destPair.first);
488                     if (dit != privKeyMap.end())
489                     {
490                         privKeys[dit->first] = dit->second;
491                         //printf("...using key for crypto condition\n");
492                     }
493                     else if (creator.IsKeystoreValid() && creator.KeyStore().GetKey(destPair.first, privKey))
494                     {
495                         privKeys[destPair.first] = privKey;
496                         //printf("...using key from wallet\n");
497                     }
498                 }
499
500                 vector<unsigned char> vch = ret.size() ? ret[0] : vector<unsigned char>();
501                 bool error = false;
502                 CScript signScript = _CCPubKey(outputCC);
503                 // loop and sign
504                 for (auto privKey : privKeys)
505                 {
506                     // if we have an error or can't sign and it isn't fulfilled, fail, if we have no error, can't sign again, and we have a fulfilled sig, it must be optimized and OK
507                     if (error || (!creator.CreateSig(vch, privKey.first, scriptPubKey, consensusBranchId, &privKey.second, (void *)outputCC)))
508                     {
509                         error = true;
510                         //CPubKey errKey = privKey.second.GetPubKey();
511                         //fprintf(stderr,"vin has MofN CC signing error with pubkey: %s, ID: %s\n", HexBytes(&(std::vector<unsigned char>(errKey.begin(), errKey.end())[0]), errKey.size()).c_str(), errKey.GetID().GetHex().c_str());
512                     }
513                 }
514
515                 if (!error && vch.size())
516                 {
517                     ret.push_back(vch);
518                 }
519
520                 cc_free(outputCC);
521                 return !error && ret.size() != 0;
522             }
523         }
524         else
525         {
526             bool is0ofAny = (p.m == 0 && p.n >= 1);
527             bool is1ofn = (p.m == 1 && p.n >= 2);
528             CKey privKey;
529
530             // must be a valid cc eval code
531             if (CCinit(&C, p.evalCode))
532             {
533                 // pay to cc address is a valid tx
534                 if (is0ofAny)
535                 {
536                     CPubKey pubk = CPubKey(ParseHex(C.CChexstr));
537                     CKeyID keyID = pubk.GetID();
538                     bool havePriv = false;
539
540                     // loop through and sign with the first of either the private key or a match on the CCs private key, otherwise, fail
541                     for (auto dest : p.vKeys)
542                     {
543                         uint160 keyID = GetDestinationID(dest);
544                         if (creator.IsKeystoreValid() && creator.KeyStore().GetKey(keyID, privKey))
545                         {
546                             havePriv = true;
547                             break;
548                         }
549                         CPubKey tempPub = boost::apply_visitor<GetPubKeyForPubKey>(GetPubKeyForPubKey(), dest);
550                         if ((tempPub.IsValid() && tempPub == pubk) || (keyID == tempPub.GetID()))
551                         {
552                             // found the pub key for this crypto condition, so use the private key
553                             std::vector<unsigned char> vch(&(C.CCpriv[0]), C.CCpriv + sizeof(C.CCpriv));
554                             privKey.Set(vch.begin(), vch.end(), true);
555                             havePriv = true;
556                             break;
557                         }
558                     }
559
560                     if (!havePriv)
561                     {
562                         fprintf(stderr,"Do not have or cannot locate private key for %s\n", EncodeDestination(p.vKeys[0]).c_str());
563                         return false;
564                     }
565
566                     CC *cc = CCcondAny(p.evalCode, p.vKeys);
567
568                     if (cc)
569                     {
570                         vector<unsigned char> vch;
571                         if (creator.CreateSig(vch, GetDestinationID(p.vKeys[0]), _CCPubKey(cc), consensusBranchId, &privKey, (void *)cc))
572                         {
573                             ret.push_back(vch);
574                         }
575                         else
576                         {
577                             fprintf(stderr,"vin has 1ofAny CC signing error with address.(%s)\n", EncodeDestination(p.vKeys[0]).c_str());
578                         }
579
580                         cc_free(cc);
581                         return ret.size() != 0;
582                     }
583                 }
584                 else if (!is1ofn)
585                 {
586                     uint160 keyID = GetDestinationID(p.vKeys[0]);
587                     bool havePriv = creator.IsKeystoreValid() && creator.KeyStore().GetKey(keyID, privKey);
588                     CPubKey pubk;
589
590                     // if we don't have the private key, it must be the unspendable address
591                     if (havePriv)
592                     {
593                         std::vector<unsigned char> vkch = GetDestinationBytes(p.vKeys[0]);
594                         if (vkch.size() == 33)
595                         {
596                             pubk = CPubKey(vkch);
597                         }
598                         else
599                         {
600                             creator.KeyStore().GetPubKey(keyID, pubk);
601                         }
602                     }
603                     else
604                     {
605                         privKey = CKey();
606                         std::vector<unsigned char> vch(&(C.CCpriv[0]), C.CCpriv + sizeof(C.CCpriv));
607
608                         privKey.Set(vch.begin(), vch.end(), true);
609                         pubk = CPubKey(ParseHex(C.CChexstr));
610                     }
611
612                     CC *cc = CCcond1(p.evalCode, pubk);
613
614                     if (cc)
615                     {
616                         vector<unsigned char> vch;
617                         if (creator.CreateSig(vch, GetDestinationID(p.vKeys[0]), _CCPubKey(cc), consensusBranchId, &privKey, (void *)cc))
618                         {
619                             ret.push_back(vch);
620                         }
621                         else
622                         {
623                             fprintf(stderr,"vin has 1of1 CC signing error with address.(%s)\n", keyID.ToString().c_str());
624                         }
625
626                         cc_free(cc);
627                         return ret.size() != 0;
628                     }
629                 }
630                 else
631                 {
632                     // first of priv key in our key store or contract address is what we sign with if we have it
633                     std::vector<CPubKey> keys;
634                     for (auto pk : p.vKeys)
635                     {
636                         uint160 keyID = GetDestinationID(pk);
637                         CPubKey foundKey;
638                         if (!(creator.IsKeystoreValid() && creator.KeyStore().GetPubKey(keyID, foundKey)))
639                         {
640                             std::vector<unsigned char> vkch = GetDestinationBytes(pk);
641                             if (vkch.size() == 33)
642                             {
643                                 foundKey = CPubKey(vkch);
644                             }
645                         }
646
647                         if (foundKey.IsFullyValid())
648                         {
649                             keys.push_back(foundKey);
650                         }
651                     }
652
653                     // if we only have one key, and this is version 2, add the cc pub key
654                     if (keys.size() <= 1 && p.version == p.VERSION_V2)
655                     {
656                         keys.push_back(CPubKey(ParseHex(C.CChexstr)));
657                     }
658
659                     // we need something to sign with
660                     if (!keys.size())
661                     {
662                         return false;
663                     }
664
665                     for (auto pk : keys)
666                     {
667                         if (creator.IsKeystoreValid() && creator.KeyStore().GetKey(pk.GetID(), privKey) && privKey.IsValid())
668                         {
669                             break;
670                         }
671
672                         if (pk == CPubKey(ParseHex(C.CChexstr)))
673                         {
674                             privKey = CKey();
675                             std::vector<unsigned char> vch(&(C.CCpriv[0]), C.CCpriv + sizeof(C.CCpriv));
676                             privKey.Set(vch.begin(), vch.end(), true);
677                             break;
678                         }
679                     }
680
681                     if (!privKey.IsValid())
682                         return false;
683
684                     CC *cc;
685                     if (keys.size() > 1)
686                     {
687                         cc = CCcond1of2(p.evalCode, keys[0], keys[1]);
688                     }
689                     else
690                     {
691                         cc = CCcond1(p.evalCode, keys[0]);
692                     }
693
694                     if (cc)
695                     {
696                         vector<unsigned char> vch;
697                         if (creator.CreateSig(vch, keys[0].GetID(), _CCPubKey(cc), consensusBranchId, &privKey, (void *)cc))
698                         {
699                             ret.push_back(vch);
700                         }
701                         else
702                         {
703                             fprintf(stderr,"vin has 1ofn CC signing error with addresses.(%s)\n(%s)\n", keys[0].GetID().ToString().c_str(), keys[1].GetID().ToString().c_str());
704                         }
705
706                         cc_free(cc);
707                         return ret.size() != 0;
708                     }
709                 }
710             }
711         }
712     }
713     return false;
714 }
715
716 /**
717  * Sign scriptPubKey using signature made with creator.
718  * Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed),
719  * unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script.
720  * Returns false if scriptPubKey could not be completely satisfied.
721  */
722 static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptPubKey,
723                      std::vector<valtype>& ret, txnouttype& whichTypeRet, uint32_t consensusBranchId)
724 {
725     CScript scriptRet;
726     uint160 h160;
727     ret.clear();
728
729     vector<valtype> vSolutions;
730
731     if (!Solver(scriptPubKey, whichTypeRet, vSolutions))
732     {
733         // if this is a CLTV script, solve for the destination after CLTV
734         if (scriptPubKey.IsCheckLockTimeVerify())
735         {
736             uint8_t pushOp = scriptPubKey[0];
737             uint32_t scriptStart = pushOp + 3;
738
739             // check post CLTV script
740             CScript postfix = CScript(scriptPubKey.size() > scriptStart ? scriptPubKey.begin() + scriptStart : scriptPubKey.end(), scriptPubKey.end());
741
742             // check again with only postfix subscript
743             if (!Solver(postfix, whichTypeRet, vSolutions))
744                 return false;
745         }
746         else
747             return false;
748     }
749
750     CKeyID keyID;
751
752     switch (whichTypeRet)
753     {
754     case TX_NONSTANDARD:
755     case TX_NULL_DATA:
756         return false;
757     case TX_PUBKEY:
758         keyID = CPubKey(vSolutions[0]).GetID();
759         return Sign1(keyID, creator, scriptPubKey, ret, consensusBranchId);
760     case TX_PUBKEYHASH:
761         keyID = CKeyID(uint160(vSolutions[0]));
762         if (!Sign1(keyID, creator, scriptPubKey, ret, consensusBranchId))
763             return false;
764         else
765         {
766             CPubKey vch;
767             creator.KeyStore().GetPubKey(keyID, vch);
768             ret.push_back(ToByteVector(vch));
769         }
770         return true;
771     case TX_SCRIPTHASH:
772         if (creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptRet)) {
773             ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
774             return true;
775         }
776         return false;
777     
778     case TX_CRYPTOCONDITION:
779         return SignStepCC(creator, scriptPubKey, vSolutions, ret, consensusBranchId);
780
781     case TX_MULTISIG:
782         ret.push_back(valtype()); // workaround CHECKMULTISIG bug
783         return (SignN(vSolutions, creator, scriptPubKey, ret, consensusBranchId));
784
785     default:
786         return false;
787     }
788 }
789
790 static CScript PushAll(const vector<valtype>& values)
791 {
792     CScript result;
793     BOOST_FOREACH(const valtype& v, values) {
794         if (v.size() == 0) {
795             result << OP_0;
796         } else if (v.size() == 1 && v[0] >= 1 && v[0] <= 16) {
797             result << CScript::EncodeOP_N(v[0]);
798         } else {
799             result << v;
800         }
801     }
802     return result;
803 }
804
805 bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata, uint32_t consensusBranchId)
806 {
807     CScript script = fromPubKey;
808     bool solved;
809     std::vector<valtype> result;
810     txnouttype whichType;
811     solved = SignStep(creator, script, result, whichType, consensusBranchId);
812     CScript subscript;
813
814     if (solved && whichType == TX_SCRIPTHASH)
815     {
816         // Solver returns the subscript that needs to be evaluated;
817         // the final scriptSig is the signatures from that
818         // and then the serialized subscript:
819         script = subscript = CScript(result[0].begin(), result[0].end());
820         solved = solved && SignStep(creator, script, result, whichType, consensusBranchId) && whichType != TX_SCRIPTHASH;
821         result.push_back(std::vector<unsigned char>(subscript.begin(), subscript.end()));
822     }
823
824     sigdata.scriptSig = PushAll(result);
825
826     // Test solution
827     return solved && VerifyScript(sigdata.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker(), consensusBranchId);
828 }
829
830 SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn)
831 {
832     SignatureData data;
833     assert(tx.vin.size() > nIn);
834     data.scriptSig = tx.vin[nIn].scriptSig;
835     return data;
836 }
837
838 void UpdateTransaction(CMutableTransaction& tx, unsigned int nIn, const SignatureData& data)
839 {
840     assert(tx.vin.size() > nIn);
841     tx.vin[nIn].scriptSig = data.scriptSig;
842 }
843
844 bool SignSignature(
845     const CKeyStore &keystore,
846     const CScript& fromPubKey,
847     CMutableTransaction& txTo,
848     unsigned int nIn,
849     const CAmount& amount,
850     int nHashType,
851     uint32_t consensusBranchId)
852 {
853     assert(nIn < txTo.vin.size());
854
855     CTransaction txToConst(txTo);
856     TransactionSignatureCreator creator(&keystore, &txToConst, nIn, amount, nHashType);
857
858     SignatureData sigdata;
859     bool ret = ProduceSignature(creator, fromPubKey, sigdata, consensusBranchId);
860     UpdateTransaction(txTo, nIn, sigdata);
861     return ret;
862 }
863
864 bool SignSignature(
865     const CKeyStore &keystore,
866     const CTransaction& txFrom,
867     CMutableTransaction& txTo,
868     unsigned int nIn,
869     int nHashType,
870     uint32_t consensusBranchId)
871 {
872     assert(nIn < txTo.vin.size());
873     CTxIn& txin = txTo.vin[nIn];
874     assert(txin.prevout.n < txFrom.vout.size());
875     const CTxOut& txout = txFrom.vout[txin.prevout.n];
876
877     return SignSignature(keystore, txout.scriptPubKey, txTo, nIn, txout.nValue, nHashType, consensusBranchId);
878 }
879
880 static vector<valtype> CombineMultisig(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
881                                const vector<valtype>& vSolutions,
882                                const vector<valtype>& sigs1, const vector<valtype>& sigs2, uint32_t consensusBranchId)
883 {
884     // Combine all the signatures we've got:
885     set<valtype> allsigs;
886     BOOST_FOREACH(const valtype& v, sigs1)
887     {
888         if (!v.empty())
889             allsigs.insert(v);
890     }
891     BOOST_FOREACH(const valtype& v, sigs2)
892     {
893         if (!v.empty())
894             allsigs.insert(v);
895     }
896
897     // Build a map of pubkey -> signature by matching sigs to pubkeys:
898     assert(vSolutions.size() > 1);
899     unsigned int nSigsRequired = vSolutions.front()[0];
900     unsigned int nPubKeys = vSolutions.size()-2;
901     map<valtype, valtype> sigs;
902     BOOST_FOREACH(const valtype& sig, allsigs)
903     {
904         for (unsigned int i = 0; i < nPubKeys; i++)
905         {
906             const valtype& pubkey = vSolutions[i+1];
907             if (sigs.count(pubkey))
908                 continue; // Already got a sig for this pubkey
909
910             if (checker.CheckSig(sig, pubkey, scriptPubKey, consensusBranchId))
911             {
912                 sigs[pubkey] = sig;
913                 break;
914             }
915         }
916     }
917     // Now build a merged CScript:
918     unsigned int nSigsHave = 0;
919     std::vector<valtype> result; result.push_back(valtype()); // pop-one-too-many workaround
920     for (unsigned int i = 0; i < nPubKeys && nSigsHave < nSigsRequired; i++)
921     {
922         if (sigs.count(vSolutions[i+1]))
923         {
924             result.push_back(sigs[vSolutions[i+1]]);
925             ++nSigsHave;
926         }
927     }
928     // Fill any missing with OP_0:
929     for (unsigned int i = nSigsHave; i < nSigsRequired; i++)
930         result.push_back(valtype());
931
932     return result;
933 }
934
935 namespace
936 {
937 struct Stacks
938 {
939     std::vector<valtype> script;
940
941     Stacks() {}
942     explicit Stacks(const std::vector<valtype>& scriptSigStack_) : script(scriptSigStack_) {}
943     explicit Stacks(const SignatureData& data, uint32_t consensusBranchId) {
944         EvalScript(script, data.scriptSig, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), consensusBranchId);
945     }
946
947     SignatureData Output() const {
948         SignatureData result;
949         result.scriptSig = PushAll(script);
950         return result;
951     }
952 };
953 }
954
955 static Stacks CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
956                                  const txnouttype txType, const vector<valtype>& vSolutions,
957                                  Stacks sigs1, Stacks sigs2, uint32_t consensusBranchId)
958 {
959     switch (txType)
960     {
961     case TX_NONSTANDARD:
962     case TX_NULL_DATA:
963         // Don't know anything about this, assume bigger one is correct:
964         if (sigs1.script.size() >= sigs2.script.size())
965             return sigs1;
966         return sigs2;
967     case TX_PUBKEY:
968     case TX_PUBKEYHASH:
969     case TX_CRYPTOCONDITION:
970         // Signatures are bigger than placeholders or empty scripts:
971         if (sigs1.script.empty() || sigs1.script[0].empty())
972             return sigs2;
973         return sigs1;
974     case TX_SCRIPTHASH:
975         if (sigs1.script.empty() || sigs1.script.back().empty())
976             return sigs2;
977         else if (sigs2.script.empty() || sigs2.script.back().empty())
978             return sigs1;
979         else
980         {
981             // Recur to combine:
982             valtype spk = sigs1.script.back();
983             CScript pubKey2(spk.begin(), spk.end());
984
985             txnouttype txType2;
986             vector<vector<unsigned char> > vSolutions2;
987             Solver(pubKey2, txType2, vSolutions2);
988             sigs1.script.pop_back();
989             sigs2.script.pop_back();
990             Stacks result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2, consensusBranchId);
991             result.script.push_back(spk);
992             return result;
993         }
994     case TX_MULTISIG:
995         return Stacks(CombineMultisig(scriptPubKey, checker, vSolutions, sigs1.script, sigs2.script, consensusBranchId));
996     default:
997         return Stacks();
998     }
999 }
1000
1001 SignatureData CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
1002                           const SignatureData& scriptSig1, const SignatureData& scriptSig2,
1003                           uint32_t consensusBranchId)
1004 {
1005     txnouttype txType;
1006     vector<vector<unsigned char> > vSolutions;
1007     Solver(scriptPubKey, txType, vSolutions);
1008
1009     return CombineSignatures(
1010         scriptPubKey, checker, txType, vSolutions,
1011         Stacks(scriptSig1, consensusBranchId),
1012         Stacks(scriptSig2, consensusBranchId),
1013         consensusBranchId).Output();
1014 }
1015
1016 namespace {
1017 /** Dummy signature checker which accepts all signatures. */
1018 class DummySignatureChecker : public BaseSignatureChecker
1019 {
1020 public:
1021     DummySignatureChecker() {}
1022
1023     bool CheckSig(
1024         const std::vector<unsigned char>& scriptSig,
1025         const std::vector<unsigned char>& vchPubKey,
1026         const CScript& scriptCode,
1027         uint32_t consensusBranchId) const
1028     {
1029         return true;
1030     }
1031
1032     int CheckCryptoCondition(
1033             const std::vector<unsigned char>& condBin,
1034             const std::vector<unsigned char>& ffillBin,
1035             const CScript& scriptCode,
1036             uint32_t consensusBranchId) const
1037     {
1038         return true;
1039     }
1040 };
1041 const DummySignatureChecker dummyChecker;
1042 }
1043
1044 const BaseSignatureChecker& DummySignatureCreator::Checker() const
1045 {
1046     return dummyChecker;
1047 }
1048
1049 bool DummySignatureCreator::CreateSig(
1050     std::vector<unsigned char>& vchSig,
1051     const CKeyID& keyid,
1052     const CScript& scriptCode,
1053     uint32_t consensusBranchId, 
1054     CKey *key,
1055     void *extraData) const
1056 {
1057     if (scriptCode.IsPayToCryptoCondition())
1058     {
1059         vchSig = CCPartialSigVec(MakeCCcondOneSig(keyid));
1060     }
1061     else
1062     {
1063         // Create a dummy signature that is a valid DER-encoding
1064         vchSig.assign(72, '\000');
1065         vchSig[0] = 0x30;
1066         vchSig[1] = 69;
1067         vchSig[2] = 0x02;
1068         vchSig[3] = 33;
1069         vchSig[4] = 0x01;
1070         vchSig[4 + 33] = 0x02;
1071         vchSig[5 + 33] = 32;
1072         vchSig[6 + 33] = 0x01;
1073         vchSig[6 + 33 + 32] = SIGHASH_ALL;
1074     }
1075     return true;
1076 }
This page took 0.085256 seconds and 4 git commands to generate.