]> Git Repo - VerusCoin.git/blob - src/script/standard.cpp
Merge pull request #97 from miketout/dev
[VerusCoin.git] / src / script / standard.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/standard.h"
7
8 #include "pubkey.h"
9 #include "script/script.h"
10 #include "util.h"
11 #include "utilstrencodings.h"
12 #include "script/cc.h"
13 #include "key_io.h"
14 #include "keystore.h"
15 #include "pbaas/identity.h"
16 #include "pbaas/reserves.h"
17 #include "cc/eval.h"
18 #include "cc/CCinclude.h"
19
20 #include <boost/foreach.hpp>
21
22 using namespace std;
23
24 typedef vector<unsigned char> valtype;
25
26 unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY;
27
28 COptCCParams::COptCCParams(const std::vector<unsigned char> &vch)
29 {
30     CScript inScr = CScript(vch.begin(), vch.end());
31     if (inScr.size() > 1)
32     {
33         CScript::const_iterator pc = inScr.begin();
34         opcodetype opcode;
35         std::vector<std::vector<unsigned char>> data;
36         std::vector<unsigned char> param;
37         bool valid = true;
38
39         while (pc < inScr.end())
40         {
41             param.clear();
42             if (inScr.GetOp(pc, opcode, param))
43             {
44                 if (opcode == OP_0)
45                 {
46                     param.resize(1);
47                     param[0] = 0;
48                     data.push_back(param);
49                 }
50                 else if (opcode >= OP_1 && opcode <= OP_16)
51                 {
52                     param.resize(1);
53                     param[0] = (opcode - OP_1) + 1;
54                     data.push_back(param);
55                 }
56                 else if (opcode > 0 && opcode <= OP_PUSHDATA4 && param.size() > 0)
57                 {
58                     data.push_back(param);
59                 }
60                 else
61                 {
62                     valid = false;
63                     break;
64                 }
65             }
66         }
67
68         if (valid && pc == inScr.end() && data.size() > 0)
69         {
70             version = 0;
71             param = data[0];
72             if (param.size() == 4)
73             {
74                 version = param[0];
75                 evalCode = param[1];
76                 m = param[2];
77                 n = param[3];
78                 if (version == 0 || version > VERSION_V3 || m > n || ((version < VERSION_V3 && n < 1) || n > 4) || (version < VERSION_V3 ? data.size() <= n : data.size() < n))
79                 {
80                     // set invalid
81                     version = 0;
82                 }
83                 else
84                 {
85                     // load keys and data
86                     vKeys.clear();
87                     vData.clear();
88                     int i;
89                     for (i = 1; version != 0 && i <= n; i++)
90                     {
91                         std::vector<unsigned char> &keyVec = data[i];
92                         if (keyVec.size() == 20)
93                         {
94                             vKeys.push_back(CKeyID(uint160(keyVec)));
95                         }
96                         else if (keyVec.size() == 33)
97                         {
98                             CPubKey key(keyVec);
99                             if (key.IsValid())
100                             {
101                                 vKeys.push_back(CTxDestination(key));
102                             }
103                             else
104                             {
105                                 version = 0;
106                             }
107                         }
108                         else if (version > VERSION_V2 && (keyVec.size() == 21 || keyVec.size() == 34))
109                         {
110                             // the first byte is an indicator of type of destination, the
111                             // rest is either a hash of an ID or another type of address
112                             switch (keyVec[0])
113                             {
114                                 case ADDRTYPE_PK:
115                                 {
116                                     if (keyVec.size() == 34)
117                                     {
118                                         CPubKey key(std::vector<unsigned char>(keyVec.begin() + 1, keyVec.end()));
119                                         if (key.IsValid())
120                                         {
121                                             vKeys.push_back(CTxDestination(key));
122                                         }
123                                     }
124                                     else
125                                     {
126                                         version = 0;
127                                     }
128                                     break;
129                                 }
130                                 case ADDRTYPE_PKH:
131                                 {
132                                     if (keyVec.size() == 21)
133                                     {
134                                         vKeys.push_back(CKeyID(uint160(std::vector<unsigned char>(keyVec.begin() + 1, keyVec.end()))));
135                                     }
136                                     else
137                                     {
138                                         version = 0;
139                                     }
140                                     break;
141                                 }
142                                 case ADDRTYPE_SH:
143                                 {
144                                     if (keyVec.size() == 21)
145                                     {
146                                         vKeys.push_back(CScriptID(uint160(std::vector<unsigned char>(keyVec.begin() + 1, keyVec.end()))));
147                                     }
148                                     else
149                                     {
150                                         version = 0;
151                                     }
152                                     break;
153                                 }
154                                 case ADDRTYPE_ID:
155                                 {
156                                     if (keyVec.size() == 21)
157                                     {
158                                         vKeys.push_back(CIdentityID(uint160(std::vector<unsigned char>(keyVec.begin() + 1, keyVec.end()))));
159                                     }
160                                     else
161                                     {
162                                         version = 0;
163                                     }
164                                     break;
165                                 }
166                                 case ADDRTYPE_INDEX:
167                                 {
168                                     if (keyVec.size() == 21)
169                                     {
170                                         vKeys.push_back(CIndexID(uint160(std::vector<unsigned char>(keyVec.begin() + 1, keyVec.end()))));
171                                     }
172                                     else
173                                     {
174                                         version = 0;
175                                     }
176                                     break;
177                                 }
178                                 default:
179                                     version = 0;
180                             }
181                         }
182                         else
183                         {
184                             version = 0;
185                             break;
186                         }
187                     }
188                     if (version != 0)
189                     {
190                         // get the rest of the data
191                         for ( ; i < data.size(); i++)
192                         {
193                             vData.push_back(data[i]);
194                         }
195                     }
196                 }
197             }
198         }
199     }
200 }
201
202 std::vector<unsigned char> COptCCParams::AsVector() const
203 {
204     CScript cData = CScript();
205
206     cData << std::vector<unsigned char>({version, evalCode, m, n});
207     for (auto k : vKeys)
208     {
209         std::vector<unsigned char> keyBytes = GetDestinationBytes(k);
210         if (version > VERSION_V2 && k.which() != ADDRTYPE_PK && k.which() != ADDRTYPE_PKH)
211         {
212             keyBytes.insert(keyBytes.begin(), (uint8_t)k.which());
213         }
214         cData << keyBytes;
215     }
216     for (auto d : vData)
217     {
218         cData << std::vector<unsigned char>(d);
219     }
220     return std::vector<unsigned char>(cData.begin(), cData.end());
221 }
222
223 bool IsPayToCryptoCondition(const CScript &scr, COptCCParams &ccParams)
224 {
225     return scr.IsPayToCryptoCondition(ccParams);
226 }
227
228 CScriptID::CScriptID(const CScript& in) : uint160(Hash160(in.begin(), in.end())) {}
229
230 const char* GetTxnOutputType(txnouttype t)
231 {
232     switch (t)
233     {
234     case TX_NONSTANDARD: return "nonstandard";
235     case TX_PUBKEY: return "pubkey";
236     case TX_PUBKEYHASH: return "pubkeyhash";
237     case TX_SCRIPTHASH: return "scripthash";
238     case TX_MULTISIG: return "multisig";
239     case TX_NULL_DATA: return "nulldata";
240     case TX_CRYPTOCONDITION: return "cryptocondition";
241     default: return "invalid";
242     }
243     return NULL;
244 }
245
246 /**
247  * Return public keys or hashes from scriptPubKey, for 'standard' transaction types.
248  */
249 bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsigned char> >& vSolutionsRet)
250 {
251     if (IsCryptoConditionsEnabled()) {
252         // Shortcut for pay-to-crypto-condition
253         CScript ccSubScript = CScript();
254         std::vector<std::vector<unsigned char>> vParams;
255         COptCCParams cp;
256         if (scriptPubKey.IsPayToCryptoCondition(cp))
257         {
258             if (cp.IsValid() && cp.version >= cp.VERSION_V3)
259             {
260                 typeRet = TX_CRYPTOCONDITION;
261                 static std::set<int> VALID_EVAL_CODES({
262                     EVAL_NONE,
263                     EVAL_STAKEGUARD,
264                     EVAL_CURRENCY_DEFINITION,
265                     EVAL_NOTARY_EVIDENCE,
266                     EVAL_EARNEDNOTARIZATION,
267                     EVAL_ACCEPTEDNOTARIZATION,
268                     EVAL_FINALIZE_NOTARIZATION,
269                     EVAL_CURRENCYSTATE,
270                     EVAL_RESERVE_TRANSFER,
271                     EVAL_RESERVE_OUTPUT,
272                     EVAL_RESERVE_EXCHANGE,
273                     EVAL_RESERVE_DEPOSIT,
274                     EVAL_CROSSCHAIN_EXPORT,
275                     EVAL_CROSSCHAIN_IMPORT,
276                     EVAL_IDENTITY_PRIMARY,
277                     EVAL_IDENTITY_REVOKE,
278                     EVAL_IDENTITY_RECOVER,
279                     EVAL_IDENTITY_COMMITMENT,
280                     EVAL_IDENTITY_RESERVATION,
281                     EVAL_FINALIZE_EXPORT,
282                     EVAL_FEE_POOL
283                 });
284                 if (VALID_EVAL_CODES.count(cp.evalCode))
285                 {
286                     for (auto k : cp.vKeys)
287                     {
288                         if (k.which() == COptCCParams::ADDRTYPE_SH || k.which() == COptCCParams::ADDRTYPE_ID)
289                         {
290                             std::vector<unsigned char> vch(GetDestinationBytes(k));
291                             vch.insert(vch.begin(), (uint8_t)k.which());
292                             vSolutionsRet.push_back(vch);
293                         }
294                         else
295                         {
296                             vSolutionsRet.push_back(GetDestinationBytes(k));
297                         }
298                     }
299                     return true;
300                 }
301             }
302             else if (scriptPubKey.IsPayToCryptoCondition(&ccSubScript, vParams))
303             {
304                 typeRet = TX_CRYPTOCONDITION;
305
306                 if (cp.IsValid())
307                 {
308                     if (cp.evalCode != EVAL_STAKEGUARD)
309                     {
310                         LogPrintf("unrecognized smart transaction script type\n");
311                         return false;
312                     }
313                     for (auto k : cp.vKeys)
314                     {
315                         vSolutionsRet.push_back(GetDestinationBytes(k));
316                     }
317                 }
318
319                 uint160 scrHash; 
320                 scrHash = Hash160(ccSubScript);
321                 vSolutionsRet.push_back(std::vector<unsigned char>(scrHash.begin(), scrHash.end()));
322                 return true;
323             }
324             return false;
325         }
326     }
327
328     // Templates
329     static multimap<txnouttype, CScript> mTemplates;
330     if (mTemplates.empty())
331     {
332         // Standard tx, sender provides pubkey, receiver adds signature
333         mTemplates.insert(make_pair(TX_PUBKEY, CScript() << OP_PUBKEY << OP_CHECKSIG));
334
335         // Bitcoin address tx, sender provides hash of pubkey, receiver provides signature and pubkey
336         mTemplates.insert(make_pair(TX_PUBKEYHASH, CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG));
337
338         // Sender provides N pubkeys, receivers provides M signatures
339         mTemplates.insert(make_pair(TX_MULTISIG, CScript() << OP_SMALLINTEGER << OP_PUBKEYS << OP_SMALLINTEGER << OP_CHECKMULTISIG));
340
341         // Empty, provably prunable, data-carrying output
342         if (GetBoolArg("-datacarrier", true))
343             mTemplates.insert(make_pair(TX_NULL_DATA, CScript() << OP_RETURN << OP_SMALLDATA));
344         mTemplates.insert(make_pair(TX_NULL_DATA, CScript() << OP_RETURN));
345     }
346
347     // Shortcut for pay-to-script-hash, which are more constrained than the other types:
348     // it is always OP_HASH160 20 [20 byte hash] OP_EQUAL
349     if (scriptPubKey.IsPayToScriptHash())
350     {
351         typeRet = TX_SCRIPTHASH;
352         vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22);
353         vSolutionsRet.push_back(hashBytes);
354         return true;
355     }
356
357     // Scan templates
358     const CScript& script1 = scriptPubKey;
359     BOOST_FOREACH(const PAIRTYPE(txnouttype, CScript)& tplate, mTemplates)
360     {
361         const CScript& script2 = tplate.second;
362         vSolutionsRet.clear();
363
364         opcodetype opcode1, opcode2;
365         vector<unsigned char> vch1, vch2;
366
367         // Compare
368         CScript::const_iterator pc1 = script1.begin();
369         CScript::const_iterator pc2 = script2.begin();
370         while (true)
371         {
372             if (pc1 == script1.end() && pc2 == script2.end())
373             {
374                 // Found a match
375                 typeRet = tplate.first;
376                 if (typeRet == TX_MULTISIG)
377                 {
378                     // Additional checks for TX_MULTISIG:
379                     unsigned char m = vSolutionsRet.front()[0];
380                     unsigned char n = vSolutionsRet.back()[0];
381                     if (m < 1 || n < 1 || m > n || vSolutionsRet.size()-2 != n)
382                         return false;
383                 }
384                 return true;
385             }
386             if (!script1.GetOp(pc1, opcode1, vch1))
387                 break;
388             if (!script2.GetOp(pc2, opcode2, vch2))
389                 break;
390
391             // Template matching opcodes:
392             if (opcode2 == OP_PUBKEYS)
393             {
394                 while (vch1.size() >= 33 && vch1.size() <= 65)
395                 {
396                     vSolutionsRet.push_back(vch1);
397                     if (!script1.GetOp(pc1, opcode1, vch1))
398                         break;
399                 }
400                 if (!script2.GetOp(pc2, opcode2, vch2))
401                     break;
402                 // Normal situation is to fall through
403                 // to other if/else statements
404             }
405
406             if (opcode2 == OP_PUBKEY)
407             {
408                 if (vch1.size() < 33 || vch1.size() > 65)
409                     break;
410                 vSolutionsRet.push_back(vch1);
411             }
412             else if (opcode2 == OP_PUBKEYHASH)
413             {
414                 if (vch1.size() != sizeof(uint160))
415                     break;
416                 vSolutionsRet.push_back(vch1);
417             }
418             else if (opcode2 == OP_SMALLINTEGER)
419             {   // Single-byte small integer pushed onto vSolutions
420                 if (opcode1 == OP_0 ||
421                     (opcode1 >= OP_1 && opcode1 <= OP_16))
422                 {
423                     char n = (char)CScript::DecodeOP_N(opcode1);
424                     vSolutionsRet.push_back(valtype(1, n));
425                 }
426                 else
427                     break;
428             }
429             else if (opcode2 == OP_SMALLDATA)
430             {
431                 // small pushdata, <= nMaxDatacarrierBytes
432                 if (vch1.size() > nMaxDatacarrierBytes)
433                 {
434                     //fprintf(stderr,"size.%d > nMaxDatacarrier.%d\n",(int32_t)vch1.size(),(int32_t)nMaxDatacarrierBytes);
435                     break;
436                 }
437             }
438             else if (opcode1 != opcode2 || vch1 != vch2)
439             {
440                 // Others must match exactly
441                 break;
442             }
443         }
444     }
445
446     vSolutionsRet.clear();
447     typeRet = TX_NONSTANDARD;
448     return false;
449 }
450
451 int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions)
452 {
453     switch (t)
454     {
455     case TX_NONSTANDARD:
456     case TX_NULL_DATA:
457         return -1;
458     case TX_PUBKEY:
459         return 1;
460     case TX_PUBKEYHASH:
461         return 2;
462     case TX_MULTISIG:
463         if (vSolutions.size() < 1 || vSolutions[0].size() < 1)
464             return -1;
465         return vSolutions[0][0] + 1;
466     case TX_SCRIPTHASH:
467         return 1; // doesn't include args needed by the script
468     case TX_CRYPTOCONDITION:
469         return 1;
470     }
471     return -1;
472 }
473
474 bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType)
475 {
476     vector<valtype> vSolutions;
477     if (!Solver(scriptPubKey, whichType, vSolutions))
478     {
479         //int32_t i; uint8_t *ptr = (uint8_t *)scriptPubKey.data();
480         //for (i=0; i<scriptPubKey.size(); i++)
481         //    fprintf(stderr,"%02x",ptr[i]);
482         //fprintf(stderr," non-standard scriptPubKey\n");
483         return false;
484     }
485
486     if (whichType == TX_MULTISIG)
487     {
488         unsigned char m = vSolutions.front()[0];
489         unsigned char n = vSolutions.back()[0];
490         // Support up to x-of-9 multisig txns as standard
491         if (n < 1 || n > 9)
492             return false;
493         if (m < 1 || m > n)
494             return false;
495     }
496     return whichType != TX_NONSTANDARD;
497 }
498
499 bool ExtractDestination(const CScript& _scriptPubKey, CTxDestination& addressRet, bool returnPubKey)
500 {
501     vector<valtype> vSolutions;
502     txnouttype whichType;
503     CScript scriptPubKey = _scriptPubKey;
504
505     // if this is a CLTV script, get the destination after CLTV
506     if (scriptPubKey.IsCheckLockTimeVerify())
507     {
508         uint8_t pushOp = scriptPubKey[0];
509         uint32_t scriptStart = pushOp + 3;
510
511         // check post CLTV script
512         scriptPubKey = CScript(scriptPubKey.size() > scriptStart ? scriptPubKey.begin() + scriptStart : scriptPubKey.end(), scriptPubKey.end());
513     }
514
515     if (!Solver(scriptPubKey, whichType, vSolutions))
516         return false;
517
518     if (whichType == TX_PUBKEY)
519     {
520         CPubKey pubKey(vSolutions[0]);
521         if (!pubKey.IsValid())
522         {
523             fprintf(stderr,"TX_PUBKEY invalid pubkey\n");
524             return false;
525         }
526
527         if (returnPubKey)
528             addressRet = pubKey;
529         else
530             addressRet = pubKey.GetID();
531         return true;
532     }
533
534     else if (whichType == TX_PUBKEYHASH)
535     {
536         addressRet = CKeyID(uint160(vSolutions[0]));
537         return true;
538     }
539     else if (whichType == TX_SCRIPTHASH)
540     {
541         addressRet = CScriptID(uint160(vSolutions[0]));
542         return true;
543     }
544     
545     else if (IsCryptoConditionsEnabled() != 0 && whichType == TX_CRYPTOCONDITION)
546     {
547         COptCCParams p;
548         if (scriptPubKey.IsPayToCryptoCondition(p) && p.IsValid() && p.vKeys.size())
549         {
550             addressRet = p.vKeys[0];
551             return true;
552         }
553     }
554     // Multisig txns have more than one address...
555     return false;
556 }
557
558 bool ExtractDestinations(const CScript& scriptPubKey, 
559                          txnouttype& typeRet, 
560                          std::vector<CTxDestination>& addressRet, 
561                          int &nRequiredRet, 
562                          const CKeyStore *pKeyStore, 
563                          bool *pCanSign, 
564                          bool *pCanSpend,
565                          uint32_t nHeight,
566                          std::map<uint160, CKey> *pPrivKeys)
567 {
568     addressRet.clear();
569     typeRet = TX_NONSTANDARD;
570     vector<valtype> vSolutions;
571
572     // if this is a CLTV script, get the destinations after CLTV
573     if (scriptPubKey.IsCheckLockTimeVerify())
574     {
575         uint8_t pushOp = scriptPubKey[0];
576         uint32_t scriptStart = pushOp + 3;
577
578         // check post CLTV script
579         CScript postfix = CScript(scriptPubKey.size() > scriptStart ? scriptPubKey.begin() + scriptStart : scriptPubKey.end(), scriptPubKey.end());
580
581         // check again with only postfix subscript
582         return(ExtractDestinations(postfix, typeRet, addressRet, nRequiredRet, pKeyStore, pCanSign, pCanSpend, nHeight, pPrivKeys));
583     }
584
585     int canSpendCount = 0;
586     bool canSign = false;
587
588     if (pCanSign)
589     {
590         *pCanSign = false;
591     }
592     if (pCanSpend)
593     {
594         *pCanSpend = false;
595     }
596
597     COptCCParams master, p;
598     bool ccValid;
599     if (scriptPubKey.IsPayToCryptoCondition(p))
600     {
601         std::set<CScriptID> idSet;
602
603         if (p.IsValid() && 
604             p.n >= 1 && 
605             p.vKeys.size() >= p.n)
606         {
607             typeRet = TX_CRYPTOCONDITION;
608             if (p.version < p.VERSION_V3)
609             {
610                 for (auto dest : p.vKeys)
611                 {
612                     uint160 destId = GetDestinationID(dest);
613                     addressRet.push_back(dest);
614                     if (dest.which() == COptCCParams::ADDRTYPE_ID)
615                     {
616                         // 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
617                         // if revoked or undefined
618                         std::pair<CIdentityMapKey, CIdentityMapValue> identity;
619                         idSet.insert(destId);
620
621                         if (pKeyStore && pKeyStore->GetIdentity(destId, identity, std::max((uint32_t)1, nHeight - 1)) && identity.second.IsValidUnrevoked())
622                         {
623                             int canSignCount = 0;
624                             for (auto oneKey : identity.second.primaryAddresses)
625                             {
626                                 uint160 oneKeyID = GetDestinationID(oneKey);
627                                 CKey privKey;
628                                 if (pKeyStore->GetKey(oneKeyID, privKey))
629                                 {
630                                     canSign = true;
631                                     canSignCount++;
632                                     if (pPrivKeys)
633                                     {
634                                         (*pPrivKeys)[oneKeyID] = privKey;
635                                     }
636                                 }
637                             }
638                             if (canSignCount >= identity.second.minSigs)
639                             {
640                                 canSpendCount++;
641                             }
642                         }
643                     }
644                     else if (pKeyStore)
645                     {
646                         CKey privKey;
647                         if (pKeyStore->GetKey(destId, privKey))
648                         {
649                             canSign = true;
650                             canSpendCount++;
651                             if (pPrivKeys)
652                             {
653                                 (*pPrivKeys)[destId] = privKey;
654                             }
655                         }
656                     }
657                 }
658                 nRequiredRet = p.m;
659                 if (canSpendCount >= p.m && pCanSpend)
660                 {
661                     *pCanSpend = true;
662                 }
663                 if (canSign && pCanSign)
664                 {
665                     *pCanSign = true;
666                 }
667             }
668             else if (p.vData.size() && (ccValid = (master = COptCCParams(p.vData.back())).IsValid()))
669             {
670                 // always add the index keys to destinations, but that has nothing to do with whether or not
671                 // an ID present in that index represents an address that can sign or spend. ids in this block
672                 // are ignored, as all IDs in an output are always indexed in the address and unspent indexes.
673                 std::set<CTxDestination> indexSet;
674                 for (auto dest : master.vKeys)
675                 {
676                     // all but ID types
677                     if (dest.which() != COptCCParams::ADDRTYPE_ID)
678                     {
679                         // include all non-name addresses from master as destinations as well
680                         // name addresses can only be destinations if they are at least "cansign" on one of the subconditions
681                         if (!indexSet.count(dest))
682                         {
683                             addressRet.push_back(dest);
684                         }
685                         indexSet.insert(dest);
686                     }
687                 }
688
689                 // handle the case where we have no object in the params, but a valid transaction
690                 int loopEnd = p.vData.size() == 1 ? 1 : p.vData.size() - 1;
691                 for (int i = 0; ccValid && i < loopEnd; i++)
692                 {
693                     // first, process P, then any sub-conditions
694                     COptCCParams _oneP;
695                     COptCCParams &oneP = (i == 0) ? p : (_oneP = COptCCParams(p.vData[i]));
696
697                     if (ccValid = oneP.IsValid())
698                     {
699                         int canSpendOneCount = 0;
700
701                         for (auto dest : oneP.vKeys)
702                         {
703                             uint160 destId = GetDestinationID(dest);
704                             if (!indexSet.count(dest))
705                             {
706                                 addressRet.push_back(dest);
707                             }
708                             if (dest.which() == COptCCParams::ADDRTYPE_ID)
709                             {
710                                 // 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
711                                 // as if revoked or undefined
712                                 std::pair<CIdentityMapKey, CIdentityMapValue> identity;
713                                 idSet.insert(destId);
714
715                                 //printf("checking: %s\n", EncodeDestination(dest).c_str());
716
717                                 if (pKeyStore && pKeyStore->GetIdentity(destId, identity, std::max((uint32_t)1, nHeight - 1)) && identity.second.IsValidUnrevoked())
718                                 {
719                                     int canSignCount = 0;
720                                     for (auto oneKey : identity.second.primaryAddresses)
721                                     {
722                                         uint160 oneKeyID = GetDestinationID(oneKey);
723
724                                         CKey privKey;
725                                         if (pKeyStore->GetKey(oneKeyID, privKey))
726                                         {
727                                             canSign = true;
728                                             canSignCount++;
729                                             if (pPrivKeys)
730                                             {
731                                                 (*pPrivKeys)[oneKeyID] = privKey;
732                                             }
733                                         }
734                                     }
735                                     if (canSignCount >= identity.second.minSigs)
736                                     {
737                                         canSpendOneCount++;
738                                     }
739                                 }
740                             }
741                             else
742                             {
743                                 if (pKeyStore)
744                                 {
745                                     CKey privKey;
746                                     if (pKeyStore->GetKey(destId, privKey))
747                                     {
748                                         canSign = true;
749                                         canSpendOneCount++;
750                                         if (pPrivKeys)
751                                         {
752                                             (*pPrivKeys)[destId] = privKey;
753                                         }
754                                     }
755                                 }
756                             }
757                         }
758                         if (canSpendOneCount >= oneP.m)
759                         {
760                             canSpendCount++;
761                         }
762                     }
763                 }
764
765                 if (!ccValid)
766                 {
767                     LogPrintf("Invalid smart transaction %d\n", p.evalCode);
768                     //return false;
769                 }
770
771                 // if this is a compound cc, the master m of n is the top level as an m of n of the sub-conditions
772                 nRequiredRet = p.vData.size() > 2 ? master.m : p.m;
773                 if (canSpendCount >= nRequiredRet && pCanSpend)
774                 {
775                     *pCanSpend = true;
776                 }
777                 if (canSign && pCanSign)
778                 {
779                     *pCanSign = true;
780                 }
781             }
782             else
783             {
784                 CScript subScr;
785                 if (scriptPubKey.IsPayToCryptoCondition(&subScr))
786                 {
787                     // this kind of ID is defined as a CKeyID, since use of script hash type in CCs are reserved for IDs
788                     addressRet.push_back(CKeyID(Hash160(subScr)));
789                     nRequiredRet = 1;
790                     if (pCanSign)
791                     {
792                         *pCanSign = true;
793                     }
794                     if (pCanSpend)
795                     {
796                         *pCanSpend = true;
797                     }
798                 }
799                 else
800                 {
801                     return false;
802                 }
803             }
804         }
805         else
806         {
807             return false;
808         }
809     }
810     else
811     {
812         if (!Solver(scriptPubKey, typeRet, vSolutions))
813             return false;
814
815         if (typeRet == TX_NULL_DATA){
816             // This is data, not addresses
817             return false;
818         }
819
820         if (typeRet == TX_MULTISIG)
821         {
822             nRequiredRet = vSolutions.front()[0];
823             int nHaveKeys = 0;
824             for (unsigned int i = 1; i < vSolutions.size()-1; i++)
825             {
826                 CPubKey pubKey(vSolutions[i]);
827                 if (!pubKey.IsValid())
828                     continue;
829
830                 CTxDestination address = pubKey.GetID();
831                 addressRet.push_back(address);
832
833                 // if we were asked to see whether we can sign or spend, determine
834                 if ((pCanSign || pCanSpend) && pKeyStore)
835                 {
836                     if (pKeyStore->HaveKey(GetDestinationID(address)))
837                     {
838                         nHaveKeys++;
839                     }
840                 }
841             }
842
843             if (addressRet.empty())
844                 return false;
845
846             if (pCanSign && nHaveKeys)
847             {
848                 *pCanSign = true;
849             }
850             if (pCanSpend && nHaveKeys >= nRequiredRet)
851             {
852                 *pCanSpend = true;
853             }
854         }
855         else
856         {
857             nRequiredRet = 1;
858             CTxDestination address;
859             if (!ExtractDestination(scriptPubKey, address))
860             {
861                 return false;
862             }
863             addressRet.push_back(address);
864             if ((pCanSign || pCanSpend) && pKeyStore)
865             {
866                 if (pKeyStore->HaveKey(GetDestinationID(address)))
867                 {
868                     if (pCanSign)
869                     {
870                         *pCanSign = true;
871                     }
872                     if (pCanSpend)
873                     {
874                         *pCanSpend = true;
875                     }
876                 }
877             }
878         }
879     }
880     
881     return true;
882 }
883
884 namespace
885 {
886 class CScriptVisitor : public boost::static_visitor<bool>
887 {
888 private:
889     CScript *script;
890 public:
891     CScriptVisitor(CScript *scriptin) { script = scriptin; }
892
893     bool operator()(const CNoDestination &dest) const {
894         script->clear();
895         return false;
896     }
897
898     bool operator()(const CIndexID &dest) const {
899         script->clear();
900         return false;
901     }
902
903     bool operator()(const CQuantumID &dest) const {
904         script->clear();
905         return false;
906     }
907
908     bool operator()(const CPubKey &key) const {
909         script->clear();
910         *script << ToByteVector(key) << OP_CHECKSIG;
911         return true;
912     }
913
914     bool operator()(const CKeyID &keyID) const {
915         script->clear();
916         *script << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
917         return true;
918     }
919
920     bool operator()(const CIdentityID &idID) const {
921         *script = CIdentity::TransparentOutput(idID);
922         return true;
923     }
924
925     bool operator()(const CScriptID &scriptID) const {
926         script->clear();
927         *script << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
928         return true;
929     }
930 };
931 }
932
933 CScript GetScriptForDestination(const CTxDestination& dest)
934 {
935     CScript script;
936
937     boost::apply_visitor(CScriptVisitor(&script), dest);
938     return script;
939 }
940
941 CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys)
942 {
943     CScript script;
944
945     script << CScript::EncodeOP_N(nRequired);
946     BOOST_FOREACH(const CPubKey& key, keys)
947         script << ToByteVector(key);
948     script << CScript::EncodeOP_N(keys.size()) << OP_CHECKMULTISIG;
949     return script;
950 }
951
952 bool IsValidDestination(const CTxDestination& dest) {
953     return dest.which() != 0;
954 }
955
956 bool IsTransparentAddress(const CTxDestination& dest) {
957     return dest.which() == 1 || dest.which() == 2;
958 }
959
960 CTxDestination DestFromAddressHash(int scriptType, uint160& addressHash)
961 {
962     switch (scriptType) {
963     case CScript::P2PKH:
964         return CTxDestination(CKeyID(addressHash));
965     case CScript::P2ID:
966         return CTxDestination(CIdentityID(addressHash));
967     case CScript::P2SH:
968         return CTxDestination(CScriptID(addressHash));
969     case CScript::P2IDX:
970         return CTxDestination(CIndexID(addressHash));
971     case CScript::P2QRK:
972         return CTxDestination(CQuantumID(addressHash));
973     default:
974         // This probably won't ever happen, because it would mean that
975         // the addressindex contains a type (say, 3) that we (currently)
976         // don't recognize; maybe we "dropped support" for it?
977         return CNoDestination();
978     }
979 }
980
981 CScript::ScriptType AddressTypeFromDest(const CTxDestination &dest)
982 {
983     switch (dest.which()) {
984
985     case COptCCParams::ADDRTYPE_PK:
986     case COptCCParams::ADDRTYPE_PKH:
987         return CScript::P2PKH;
988     case COptCCParams::ADDRTYPE_SH:
989         return CScript::P2SH;
990     case COptCCParams::ADDRTYPE_ID:
991         return CScript::P2ID;
992     case COptCCParams::ADDRTYPE_INDEX:
993         return CScript::P2IDX;
994     case COptCCParams::ADDRTYPE_QUANTUM:
995         return CScript::P2QRK;
996     default:
997         // This probably won't ever happen, because it would mean that
998         // the addressindex contains a type (say, 3) that we (currently)
999         // don't recognize; maybe we "dropped support" for it?
1000         return CScript::UNKNOWN;
1001     }
1002 }
1003
This page took 0.082001 seconds and 4 git commands to generate.