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 .
8 #include "tinyformat.h"
9 #include "utilstrencodings.h"
10 #include "script/cc.h"
12 #include "cryptoconditions/include/cryptoconditions.h"
14 #include "pbaas/reserves.h"
17 #include "pbaas/identity.h"
22 inline std::string ValueString(const std::vector<unsigned char>& vch)
25 return strprintf("%d", CScriptNum(vch, false).getint());
31 const char* GetOpName(opcodetype opcode)
36 case OP_0 : return "0";
37 case OP_PUSHDATA1 : return "OP_PUSHDATA1";
38 case OP_PUSHDATA2 : return "OP_PUSHDATA2";
39 case OP_PUSHDATA4 : return "OP_PUSHDATA4";
40 case OP_1NEGATE : return "-1";
41 case OP_RESERVED : return "OP_RESERVED";
42 case OP_1 : return "1";
43 case OP_2 : return "2";
44 case OP_3 : return "3";
45 case OP_4 : return "4";
46 case OP_5 : return "5";
47 case OP_6 : return "6";
48 case OP_7 : return "7";
49 case OP_8 : return "8";
50 case OP_9 : return "9";
51 case OP_10 : return "10";
52 case OP_11 : return "11";
53 case OP_12 : return "12";
54 case OP_13 : return "13";
55 case OP_14 : return "14";
56 case OP_15 : return "15";
57 case OP_16 : return "16";
60 case OP_NOP : return "OP_NOP";
61 case OP_VER : return "OP_VER";
62 case OP_IF : return "OP_IF";
63 case OP_NOTIF : return "OP_NOTIF";
64 case OP_VERIF : return "OP_VERIF";
65 case OP_VERNOTIF : return "OP_VERNOTIF";
66 case OP_ELSE : return "OP_ELSE";
67 case OP_ENDIF : return "OP_ENDIF";
68 case OP_VERIFY : return "OP_VERIFY";
69 case OP_RETURN : return "OP_RETURN";
72 case OP_TOALTSTACK : return "OP_TOALTSTACK";
73 case OP_FROMALTSTACK : return "OP_FROMALTSTACK";
74 case OP_2DROP : return "OP_2DROP";
75 case OP_2DUP : return "OP_2DUP";
76 case OP_3DUP : return "OP_3DUP";
77 case OP_2OVER : return "OP_2OVER";
78 case OP_2ROT : return "OP_2ROT";
79 case OP_2SWAP : return "OP_2SWAP";
80 case OP_IFDUP : return "OP_IFDUP";
81 case OP_DEPTH : return "OP_DEPTH";
82 case OP_DROP : return "OP_DROP";
83 case OP_DUP : return "OP_DUP";
84 case OP_NIP : return "OP_NIP";
85 case OP_OVER : return "OP_OVER";
86 case OP_PICK : return "OP_PICK";
87 case OP_ROLL : return "OP_ROLL";
88 case OP_ROT : return "OP_ROT";
89 case OP_SWAP : return "OP_SWAP";
90 case OP_TUCK : return "OP_TUCK";
93 case OP_CAT : return "OP_CAT";
94 case OP_SUBSTR : return "OP_SUBSTR";
95 case OP_LEFT : return "OP_LEFT";
96 case OP_RIGHT : return "OP_RIGHT";
97 case OP_SIZE : return "OP_SIZE";
100 case OP_INVERT : return "OP_INVERT";
101 case OP_AND : return "OP_AND";
102 case OP_OR : return "OP_OR";
103 case OP_XOR : return "OP_XOR";
104 case OP_EQUAL : return "OP_EQUAL";
105 case OP_EQUALVERIFY : return "OP_EQUALVERIFY";
106 case OP_RESERVED1 : return "OP_RESERVED1";
107 case OP_RESERVED2 : return "OP_RESERVED2";
110 case OP_1ADD : return "OP_1ADD";
111 case OP_1SUB : return "OP_1SUB";
112 case OP_2MUL : return "OP_2MUL";
113 case OP_2DIV : return "OP_2DIV";
114 case OP_NEGATE : return "OP_NEGATE";
115 case OP_ABS : return "OP_ABS";
116 case OP_NOT : return "OP_NOT";
117 case OP_0NOTEQUAL : return "OP_0NOTEQUAL";
118 case OP_ADD : return "OP_ADD";
119 case OP_SUB : return "OP_SUB";
120 case OP_MUL : return "OP_MUL";
121 case OP_DIV : return "OP_DIV";
122 case OP_MOD : return "OP_MOD";
123 case OP_LSHIFT : return "OP_LSHIFT";
124 case OP_RSHIFT : return "OP_RSHIFT";
125 case OP_BOOLAND : return "OP_BOOLAND";
126 case OP_BOOLOR : return "OP_BOOLOR";
127 case OP_NUMEQUAL : return "OP_NUMEQUAL";
128 case OP_NUMEQUALVERIFY : return "OP_NUMEQUALVERIFY";
129 case OP_NUMNOTEQUAL : return "OP_NUMNOTEQUAL";
130 case OP_LESSTHAN : return "OP_LESSTHAN";
131 case OP_GREATERTHAN : return "OP_GREATERTHAN";
132 case OP_LESSTHANOREQUAL : return "OP_LESSTHANOREQUAL";
133 case OP_GREATERTHANOREQUAL : return "OP_GREATERTHANOREQUAL";
134 case OP_MIN : return "OP_MIN";
135 case OP_MAX : return "OP_MAX";
136 case OP_WITHIN : return "OP_WITHIN";
139 case OP_RIPEMD160 : return "OP_RIPEMD160";
140 case OP_SHA1 : return "OP_SHA1";
141 case OP_SHA256 : return "OP_SHA256";
142 case OP_HASH160 : return "OP_HASH160";
143 case OP_HASH256 : return "OP_HASH256";
144 case OP_CODESEPARATOR : return "OP_CODESEPARATOR";
145 case OP_CHECKSIG : return "OP_CHECKSIG";
146 case OP_CHECKSIGVERIFY : return "OP_CHECKSIGVERIFY";
147 case OP_CHECKMULTISIG : return "OP_CHECKMULTISIG";
148 case OP_CHECKMULTISIGVERIFY : return "OP_CHECKMULTISIGVERIFY";
149 case OP_CHECKCRYPTOCONDITION : return "OP_CHECKCRYPTOCONDITION";
150 case OP_CHECKCRYPTOCONDITIONVERIFY
151 : return "OP_CHECKCRYPTOCONDITIONVERIFY";
154 case OP_NOP1 : return "OP_NOP1";
155 case OP_NOP2 : return "OP_NOP2";
156 case OP_NOP3 : return "OP_NOP3";
157 case OP_NOP4 : return "OP_NOP4";
158 case OP_NOP5 : return "OP_NOP5";
159 case OP_NOP6 : return "OP_NOP6";
160 case OP_NOP7 : return "OP_NOP7";
161 case OP_NOP8 : return "OP_NOP8";
162 case OP_NOP9 : return "OP_NOP9";
163 case OP_NOP10 : return "OP_NOP10";
165 case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE";
168 // The template matching params OP_SMALLDATA/etc are defined in opcodetype enum
169 // as kind of implementation hack, they are *NOT* real opcodes. If found in real
170 // Script, just let the default: case deal with them.
177 uint160 GetConditionID(uint160 cid, int32_t condition)
179 CHashWriter hw(SER_GETHASH, PROTOCOL_VERSION);
182 uint256 chainHash = hw.GetHash();
183 return Hash160(chainHash.begin(), chainHash.end());
186 CTxDestination TransferDestinationToDestination(const CTransferDestination &transferDest)
188 CTxDestination retDest;
189 switch (transferDest.type)
191 case CTransferDestination::DEST_PKH:
192 retDest = CKeyID(uint160(transferDest.destination));
195 case CTransferDestination::DEST_PK:
198 pk.Set(transferDest.destination.begin(), transferDest.destination.end());
203 case CTransferDestination::DEST_SH:
204 retDest = CScriptID(uint160(transferDest.destination));
207 case CTransferDestination::DEST_ID:
208 retDest = CIdentityID(uint160(transferDest.destination));
211 case CTransferDestination::DEST_FULLID:
212 retDest = CIdentityID(CIdentity(transferDest.destination).GetID());
215 case CTransferDestination::DEST_QUANTUM:
216 retDest = CQuantumID(uint160(transferDest.destination));
222 CTransferDestination DestinationToTransferDestination(const CTxDestination &dest)
224 CTransferDestination retDest;
225 switch (dest.which())
227 case CTransferDestination::DEST_PKH:
228 case CTransferDestination::DEST_PK:
229 case CTransferDestination::DEST_SH:
230 case CTransferDestination::DEST_ID:
231 case CTransferDestination::DEST_QUANTUM:
232 retDest = CTransferDestination(dest.which(), GetDestinationBytes(dest));
238 CTransferDestination IdentityToTransferDestination(const CIdentity &identity)
240 return CTransferDestination(CTransferDestination::DEST_FULLID, ::AsVector(identity));
243 CIdentity TransferDestinationToIdentity(const CTransferDestination &dest)
245 CIdentity retIdentity;
248 case CTransferDestination::DEST_FULLID:
250 ::FromVector(dest.destination, retIdentity);
257 std::vector<CTxDestination> TransferDestinationsToDestinations(const std::vector<CTransferDestination> &transferDests)
259 std::vector<CTxDestination> retDests;
260 for (auto &dest : transferDests)
262 retDests.push_back(TransferDestinationToDestination(dest));
267 std::vector<CTransferDestination> DestinationsToTransferDestinations(const std::vector<CTxDestination> &dests)
269 std::vector<CTransferDestination> retDests;
270 for (auto &dest : dests)
272 retDests.push_back(DestinationToTransferDestination(dest));
277 CStakeInfo::CStakeInfo(std::vector<unsigned char> vch)
279 ::FromVector(vch, *this);
282 std::vector<unsigned char> CStakeInfo::AsVector() const
284 return ::AsVector(*this);
287 unsigned int CScript::MAX_SCRIPT_ELEMENT_SIZE = MAX_SCRIPT_ELEMENT_SIZE_V2;
289 unsigned int CScript::GetSigOpCount(bool fAccurate) const
292 const_iterator pc = begin();
293 opcodetype lastOpcode = OP_INVALIDOPCODE;
297 if (!GetOp(pc, opcode))
299 if (opcode == OP_CHECKSIG || opcode == OP_CHECKSIGVERIFY)
301 else if (opcode == OP_CHECKMULTISIG || opcode == OP_CHECKMULTISIGVERIFY)
303 if (fAccurate && lastOpcode >= OP_1 && lastOpcode <= OP_16)
304 n += DecodeOP_N(lastOpcode);
313 unsigned int CScript::GetSigOpCount(const CScript& scriptSig) const
315 if (!IsPayToScriptHash())
316 return GetSigOpCount(true);
318 // This is a pay-to-script-hash scriptPubKey;
319 // get the last item that the scriptSig
320 // pushes onto the stack:
321 const_iterator pc = scriptSig.begin();
322 vector<unsigned char> data;
323 while (pc < scriptSig.end())
326 if (!scriptSig.GetOp(pc, opcode, data))
332 /// ... and return its opcount:
333 CScript subscript(data.begin(), data.end());
334 return subscript.GetSigOpCount(true);
337 bool CScript::IsPayToPublicKeyHash() const
339 // Extra-fast test for pay-to-pubkey-hash CScripts:
340 return (this->size() == 25 &&
341 (*this)[0] == OP_DUP &&
342 (*this)[1] == OP_HASH160 &&
343 (*this)[2] == 0x14 &&
344 (*this)[23] == OP_EQUALVERIFY &&
345 (*this)[24] == OP_CHECKSIG);
348 bool CScript::IsPayToPublicKey() const
350 // Extra-fast test for pay-to-pubkey CScripts:
351 return (this->size() == 35 &&
353 (*this)[34] == OP_CHECKSIG);
356 bool CScript::IsPayToScriptHash() const
358 // Extra-fast test for pay-to-script-hash CScripts:
359 return (this->size() == 23 &&
360 (*this)[0] == OP_HASH160 &&
361 (*this)[1] == 0x14 &&
362 (*this)[22] == OP_EQUAL);
365 // this returns true if either there is nothing left and pc points at the end, or
366 // all instructions from the pc to the end of the script are balanced pushes and pops
367 // if there is data, it also returns all the values as byte vectors in a list of vectors
368 bool CScript::GetBalancedData(const_iterator& pc, std::vector<std::vector<unsigned char>>& vSolutions) const
375 vector<unsigned char> data;
377 if (this->GetOp(pc, opcode, data))
379 if (opcode == OP_DROP)
381 // this should never pop what it hasn't pushed (like a success code)
393 vSolutions.push_back(data);
395 else if (opcode >= OP_1 && opcode <= OP_16)
398 data[0] = (opcode - OP_1) + 1;
399 vSolutions.push_back(data);
401 else if (opcode > 0 && opcode <= OP_PUSHDATA4 && data.size() > 0)
403 vSolutions.push_back(data);
412 return netPushes == 0;
415 // this returns true if either there is nothing left and pc points at the end
416 // if there is data, it also returns all the values as byte vectors in a list of vectors
417 bool CScript::GetPushedData(CScript::const_iterator pc, std::vector<std::vector<unsigned char>>& vData) const
419 vector<unsigned char> data;
421 std::vector<unsigned char> vch1 = std::vector<unsigned char>(1);
427 if (GetOp(pc, opcode, data))
432 vData.push_back(vch1);
434 else if (opcode >= OP_1 && opcode <= OP_16)
436 vch1[0] = (opcode - OP_1) + 1;
437 vData.push_back(vch1);
439 else if (opcode > 0 && opcode <= OP_PUSHDATA4 && data.size() > 0)
441 vData.push_back(data);
447 return vData.size() != 0;
450 // this returns true if either there is nothing left and pc points at the end
451 // if there is data, it also returns all the values as byte vectors in a list of vectors
452 bool CScript::GetOpretData(std::vector<std::vector<unsigned char>>& vData) const
454 vector<unsigned char> data;
456 CScript::const_iterator pc = this->begin();
458 if (GetOp(pc, opcode, data) && opcode == OP_RETURN)
460 return GetPushedData(pc, vData);
465 bool CScript::IsPayToCryptoCondition(CScript *pCCSubScript, std::vector<std::vector<unsigned char>>& vParams) const
467 const_iterator pc = begin();
468 vector<unsigned char> firstParam;
469 vector<unsigned char> data;
471 if (this->GetOp(pc, opcode, firstParam))
472 // Sha256 conditions are <76 bytes
473 if (opcode > OP_0 && opcode < OP_PUSHDATA1)
474 if (this->GetOp(pc, opcode, data))
475 if (opcode == OP_CHECKCRYPTOCONDITION)
477 const_iterator pcCCEnd = pc;
478 if (GetBalancedData(pc, vParams))
481 *pCCSubScript = CScript(begin(), pcCCEnd);
482 vParams.push_back(firstParam);
489 bool CScript::IsPayToCryptoCondition(CScript *pCCSubScript) const
491 std::vector<std::vector<unsigned char>> vParams;
492 return IsPayToCryptoCondition(pCCSubScript, vParams);
495 bool CScript::IsPayToCryptoCondition() const
497 return IsPayToCryptoCondition((CScript *)NULL);
500 extern uint160 ASSETCHAINS_CHAINID, VERUS_CHAINID;
502 bool CScript::IsInstantSpend() const
505 bool isInstantSpend = false;
506 if (!_IsVerusActive() && IsPayToCryptoCondition(p) && p.IsValid())
508 // instant spends must be to expected instant spend crypto conditions and to the right address as well
509 if ((p.evalCode == EVAL_EARNEDNOTARIZATION && GetDestinationID(p.vKeys[0]) == GetConditionID(VERUS_CHAINID, p.evalCode)) ||
510 (p.evalCode == EVAL_CURRENCYSTATE && GetDestinationID(p.vKeys[0]) == GetConditionID(ASSETCHAINS_CHAINID, p.evalCode)) ||
511 (p.evalCode == EVAL_CROSSCHAIN_IMPORT && GetDestinationID(p.vKeys[0]) == GetConditionID(VERUS_CHAINID, p.evalCode)) ||
512 (p.evalCode == EVAL_CROSSCHAIN_EXPORT && GetDestinationID(p.vKeys[0]) == GetConditionID(VERUS_CHAINID, p.evalCode)))
514 isInstantSpend = true;
517 return isInstantSpend;
520 bool CScript::IsPayToCryptoCondition(COptCCParams &ccParams) const
523 std::vector<std::vector<unsigned char>> vParams;
525 if (IsPayToCryptoCondition(&subScript, vParams))
527 if (!vParams.empty())
529 ccParams = COptCCParams(vParams[0]);
530 for (int i = 1; i < vParams.size(); i++)
532 ccParams.vData.push_back(vParams[i]);
537 // make sure that we return it in a consistent and known state
538 ccParams = COptCCParams();
542 ccParams = COptCCParams();
546 bool CScript::IsPayToCryptoCondition(CScript *ccSubScript, std::vector<std::vector<unsigned char>> &vParams, COptCCParams &optParams) const
548 if (IsPayToCryptoCondition(ccSubScript, vParams))
550 if (vParams.size() > 0)
552 optParams = COptCCParams(vParams[0]);
553 return optParams.IsValid();
559 bool CScript::IsPayToCryptoCondition(uint32_t *ecode) const
562 std::vector<std::vector<unsigned char>> vParams;
564 if (IsPayToCryptoCondition(&sub, vParams, p))
572 CScript &CScript::ReplaceCCParams(const COptCCParams ¶ms)
575 std::vector<std::vector<unsigned char>> vParams;
577 if (this->IsPayToCryptoCondition(&subScript, vParams, p) || p.evalCode != params.evalCode)
579 // add the object to the end of the script
581 *this << params.AsVector() << OP_DROP;
586 bool CScript::IsSpendableOutputType(const COptCCParams &p) const
588 bool isSpendable = true;
595 case EVAL_CURRENCYSTATE:
596 case EVAL_RESERVE_TRANSFER:
597 case EVAL_RESERVE_EXCHANGE:
598 case EVAL_CROSSCHAIN_IMPORT:
607 bool CScript::IsSpendableOutputType() const
610 if (IsPayToCryptoCondition(p))
612 return IsSpendableOutputType(p);
614 // default for non-CC outputs is true, this is to protect from accidentally spending specific CC output types,
615 // even though they could be spent
619 CCurrencyValueMap CScript::ReserveOutValue(COptCCParams &p, bool spendableOnly) const
621 CCurrencyValueMap retVal;
623 // already validated above
624 if (IsPayToCryptoCondition(p) && p.IsValid() && (!spendableOnly || IsSpendableOutputType(p)))
628 case EVAL_RESERVE_OUTPUT:
630 CTokenOutput ro(p.vData[0]);
633 retVal.valueMap[ro.currencyID] = ro.nValue;
638 case EVAL_RESERVE_DEPOSIT:
640 CTokenOutput ro(p.vData[0]);
643 retVal.valueMap[ro.currencyID] = ro.nValue;
648 case EVAL_CURRENCYSTATE:
650 CCoinbaseCurrencyState cbcs(p.vData[0]);
651 for (int i = 0; i < cbcs.currencies.size(); i++)
653 if (cbcs.reserveOut[i])
655 retVal.valueMap[cbcs.currencies[i]] = cbcs.reserveOut[i];
661 case EVAL_RESERVE_TRANSFER:
663 CReserveTransfer rt(p.vData[0]);
664 // this currency can only be present as native
665 if (!(rt.flags & (rt.MINT_CURRENCY | rt.PREALLOCATE)) && rt.currencyID != ASSETCHAINS_CHAINID)
667 retVal.valueMap[rt.currencyID] = rt.nValue + rt.nFees;
672 case EVAL_RESERVE_EXCHANGE:
674 CReserveExchange re(p.vData[0]);
675 // reserve out amount when converting to reserve is 0, since the amount cannot be calculated in isolation as an input
676 // if reserve in, we can consider the output the same reserve value as the input
677 if (!(re.flags & re.TO_RESERVE))
679 retVal.valueMap[re.currencyID] = re.nValue;
683 case EVAL_CROSSCHAIN_IMPORT:
685 CCrossChainImport cci(p.vData[0]);
686 // reserve out amount when converting to reserve is 0, since the amount cannot be calculated in isolation as an input
687 // if reserve in, we can consider the output the same reserve value as the input
688 retVal = cci.totalReserveOutMap;
696 CCurrencyValueMap CScript::ReserveOutValue() const
699 return ReserveOutValue(p);
702 bool CScript::SetReserveOutValue(const CCurrencyValueMap &newValues)
707 // already validated above
708 if (::IsPayToCryptoCondition(*this, p) && p.IsValid())
712 case EVAL_RESERVE_OUTPUT:
714 if (newValues.valueMap.size() != 1)
718 CTokenOutput ro(p.vData[0]);
719 ro.currencyID = newValues.valueMap.begin()->first;
720 ro.nValue = newValues.valueMap.begin()->second;
721 p.vData[0] = ro.AsVector();
724 case EVAL_RESERVE_TRANSFER:
726 if (newValues.valueMap.size() != 1)
730 CReserveTransfer rt(p.vData[0]);
731 rt.currencyID = newValues.valueMap.begin()->first;
732 rt.nValue = newValues.valueMap.begin()->second;
733 p.vData[0] = rt.AsVector();
736 case EVAL_RESERVE_EXCHANGE:
738 if (newValues.valueMap.size() != 1)
742 CReserveExchange re(p.vData[0]);
743 re.currencyID = newValues.valueMap.begin()->first;
744 re.nValue = newValues.valueMap.begin()->second;
745 p.vData[0] = re.AsVector();
748 case EVAL_CROSSCHAIN_IMPORT:
750 CCrossChainImport cci(p.vData[0]);
751 cci.importValue = newValues;
752 p.vData[0] = cci.AsVector();
755 // cross chain import thread holds the original conversion amounts
756 case EVAL_CURRENCYSTATE:
758 CCoinbaseCurrencyState cbcs(p.vData[0]);
759 for (int i = 0; i < cbcs.currencies.size(); i++)
761 auto it = newValues.valueMap.find(cbcs.currencies[i]);
762 if (it != newValues.valueMap.end())
764 cbcs.reserveOut[i] = it->second;
767 p.vData[0] = cbcs.AsVector();
774 *this = ReplaceCCParams(p);
780 bool CScript::MayAcceptCryptoCondition() const
782 // Get the type mask of the condition
783 const_iterator pc = this->begin();
784 vector<unsigned char> data;
786 if (!this->GetOp(pc, opcode, data)) return false;
787 if (!(opcode > OP_0 && opcode < OP_PUSHDATA1)) return false;
788 CC *cond = cc_readConditionBinary(data.data(), data.size());
789 if (!cond) return false;
792 if (!IsPayToCryptoCondition(&eCode))
797 bool out = IsSupportedCryptoCondition(cond, eCode);
803 // also checks if the eval code is consistent
804 bool CScript::MayAcceptCryptoCondition(int evalCode) const
806 // Get the type mask of the condition
807 const_iterator pc = this->begin();
808 vector<unsigned char> data;
810 if (!this->GetOp(pc, opcode, data)) return false;
811 if (!(opcode > OP_0 && opcode < OP_PUSHDATA1)) return false;
812 CC *cond = cc_readConditionBinary(data.data(), data.size());
813 if (!cond) return false;
815 bool out = IsSupportedCryptoCondition(cond, evalCode);
821 bool CScript::IsCoinImport() const
823 const_iterator pc = this->begin();
824 vector<unsigned char> data;
826 if (this->GetOp(pc, opcode, data))
827 if (opcode > OP_0 && opcode <= OP_PUSHDATA4)
828 return data.begin()[0] == EVAL_IMPORTCOIN;
832 bool CScript::IsPushOnly() const
834 const_iterator pc = begin();
838 if (!GetOp(pc, opcode))
840 // Note that IsPushOnly() *does* consider OP_RESERVED to be a
841 // push-type opcode, however execution of OP_RESERVED fails, so
842 // it's not relevant to P2SH/BIP62 as the scriptSig would fail prior to
843 // the P2SH special validation code being executed.
850 // if the front of the script has check lock time verify. this is a fairly simple check.
851 // accepts NULL as parameter if unlockTime is not needed.
852 bool CScript::IsCheckLockTimeVerify(int64_t *unlockTime) const
855 std::vector<unsigned char> unlockTimeParam = std::vector<unsigned char>();
856 CScript::const_iterator it = this->begin();
858 if (this->GetOp2(it, op, &unlockTimeParam))
860 if (unlockTimeParam.size() >= 0 && unlockTimeParam.size() < 6 &&
861 (*this)[unlockTimeParam.size() + 1] == OP_CHECKLOCKTIMEVERIFY)
863 int i = unlockTimeParam.size() - 1;
864 for (*unlockTime = 0; i >= 0; i--)
867 *unlockTime |= *((unsigned char *)unlockTimeParam.data() + i);
875 bool CScript::IsCheckLockTimeVerify() const
878 return this->IsCheckLockTimeVerify(&ult);
881 std::string CScript::ToString() const
885 std::vector<unsigned char> vch;
886 const_iterator pc = begin();
891 if (!GetOp(pc, opcode, vch))
896 if (0 <= opcode && opcode <= OP_PUSHDATA4)
897 str += ValueString(vch);
899 str += GetOpName(opcode);
904 CScript::ScriptType CScript::GetType() const
906 if (this->IsPayToPublicKeyHash())
908 return CScript::P2PKH;
910 else if (this->IsPayToScriptHash())
912 return CScript::P2SH;
914 else if (this->IsPayToPublicKey())
916 return CScript::P2PK;
918 else if (this->IsPayToCryptoCondition())
920 return CScript::P2CC;
923 // We don't know this script type
924 return CScript::UNKNOWN;
927 uint160 CScript::AddressHash() const
931 if (this->IsPayToScriptHash()) {
932 addressHash = uint160(std::vector<unsigned char>(this->begin()+2, this->begin()+22));
934 else if (this->IsPayToPublicKeyHash())
936 addressHash = uint160(std::vector<unsigned char>(this->begin()+3, this->begin()+23));
938 else if (this->IsPayToPublicKey())
940 std::vector<unsigned char> hashBytes(this->begin()+1, this->begin()+34);
941 addressHash = Hash160(hashBytes);
943 else if (this->IsPayToCryptoCondition(p)) {
944 if (p.IsValid() && (p.vKeys.size()))
947 if (p.version >= p.VERSION_V3 && p.vData.size() > 1 && (master = COptCCParams(p.vData.back())).IsValid() && master.vKeys.size())
949 addressHash = GetDestinationID(master.vKeys[0]);
953 addressHash = GetDestinationID(p.vKeys[0]);
958 vector<unsigned char> hashBytes(this->begin(), this->end());
959 addressHash = Hash160(hashBytes);
965 std::vector<CTxDestination> CScript::GetDestinations() const
967 std::vector<CTxDestination> destinations;
969 if (this->IsPayToCryptoCondition(p))
971 if (p.IsValid() && (p.vKeys.size()))
973 destinations = p.GetDestinations();
977 vector<unsigned char> hashBytes(this->begin(), this->end());
978 destinations.push_back(CKeyID(Hash160(hashBytes)));
981 else if (this->IsPayToScriptHash()) {
982 destinations.push_back(CScriptID(uint160(std::vector<unsigned char>(this->begin()+2, this->begin()+22))));
984 else if (this->IsPayToPublicKeyHash())
986 destinations.push_back(CKeyID(uint160(std::vector<unsigned char>(this->begin()+3, this->begin()+23))));
988 else if (this->IsPayToPublicKey())
990 std::vector<unsigned char> hashBytes(this->begin()+1, this->begin()+34);
991 destinations.push_back(CPubKey(hashBytes));
996 uint160 GetNameID(const std::string &Name, const uint160 &parent)
998 uint160 writeable = parent;
999 return CIdentity::GetID(Name, writeable);
1002 CAmount AmountFromValueNoErr(const UniValue& value)
1007 if (!value.isNum() && !value.isStr())
1011 else if (!ParseFixedPoint(value.getValStr(), 8, &amount))
1015 else if (!MoneyRange(amount))
1021 catch(const std::exception& e)
1027 CCurrencyValueMap::CCurrencyValueMap(const std::vector<uint160> ¤cyIDs, const std::vector<CAmount> &amounts)
1029 int commonNum = currencyIDs.size() >= amounts.size() ? amounts.size() : currencyIDs.size();
1030 for (int i = 0; i < commonNum; i++)
1032 valueMap[currencyIDs[i]] = amounts[i];
1036 bool operator<(const CCurrencyValueMap& a, const CCurrencyValueMap& b)
1038 // to be less than means, in this order:
1039 // 1. To have fewer non-zero currencies.
1040 // 2. If not fewer currencies, to be unable to be subtracted from the one being checked
1041 // without creating negative values
1042 if (!a.valueMap.size() && !b.valueMap.size())
1046 bool isaltb = false;
1048 for (auto &oneVal : b.valueMap)
1052 auto it = a.valueMap.find(oneVal.first);
1053 if (it == a.valueMap.end() || it->second < oneVal.second)
1062 bool operator>(const CCurrencyValueMap& a, const CCurrencyValueMap& b)
1067 bool operator==(const CCurrencyValueMap& a, const CCurrencyValueMap& b)
1069 if (a.valueMap.size() != b.valueMap.size())
1075 for (auto &oneVal : a.valueMap)
1077 auto it = b.valueMap.find(oneVal.first);
1078 if (it == b.valueMap.end() || it->second != oneVal.second)
1087 bool operator!=(const CCurrencyValueMap& a, const CCurrencyValueMap& b)
1092 bool operator<=(const CCurrencyValueMap& a, const CCurrencyValueMap& b)
1094 return (a < b) || (a == b);
1097 bool operator>=(const CCurrencyValueMap& a, const CCurrencyValueMap& b)
1102 CCurrencyValueMap operator+(const CCurrencyValueMap& a, const CCurrencyValueMap& b)
1104 CCurrencyValueMap retVal = a;
1105 if (a.valueMap.size() || b.valueMap.size())
1107 for (auto &oneVal : b.valueMap)
1109 auto it = retVal.valueMap.find(oneVal.first);
1110 if (it == retVal.valueMap.end())
1112 retVal.valueMap[oneVal.first] = oneVal.second;
1116 it->second += oneVal.second;
1123 CCurrencyValueMap operator-(const CCurrencyValueMap& a, const CCurrencyValueMap& b)
1125 CCurrencyValueMap retVal = a;
1126 if (a.valueMap.size() || b.valueMap.size())
1128 for (auto &oneVal : b.valueMap)
1130 auto it = retVal.valueMap.find(oneVal.first);
1131 if (it == retVal.valueMap.end())
1133 retVal.valueMap[oneVal.first] = -oneVal.second;
1137 it->second -= oneVal.second;
1144 CCurrencyValueMap operator+(const CCurrencyValueMap& a, int b)
1146 CCurrencyValueMap retVal = a;
1147 for (auto &oneVal : retVal.valueMap)
1154 CCurrencyValueMap operator-(const CCurrencyValueMap& a, int b)
1156 CCurrencyValueMap retVal = a;
1157 for (auto &oneVal : retVal.valueMap)
1164 CCurrencyValueMap operator*(const CCurrencyValueMap& a, int b)
1166 CCurrencyValueMap retVal = a;
1167 for (auto &oneVal : retVal.valueMap)
1174 const CCurrencyValueMap &CCurrencyValueMap::operator-=(const CCurrencyValueMap& operand)
1176 return *this = *this - operand;
1179 const CCurrencyValueMap &CCurrencyValueMap::operator+=(const CCurrencyValueMap& operand)
1181 return *this = *this + operand;
1184 // determine if the operand intersects this map
1185 bool CCurrencyValueMap::Intersects(const CCurrencyValueMap& operand) const
1187 bool retVal = false;
1189 if (valueMap.size() && operand.valueMap.size())
1191 for (auto &oneVal : valueMap)
1193 auto it = operand.valueMap.find(oneVal.first);
1194 if (it != operand.valueMap.end())
1196 if (it->second > 0 && oneVal.second > 0)
1207 CCurrencyValueMap CCurrencyValueMap::IntersectingValues(const CCurrencyValueMap& operand) const
1209 CCurrencyValueMap retVal;
1211 if (valueMap.size() && operand.valueMap.size())
1213 for (auto &oneVal : valueMap)
1215 auto it = operand.valueMap.find(oneVal.first);
1216 if (it != operand.valueMap.end() &&
1220 retVal.valueMap[oneVal.first] = oneVal.second;
1227 CCurrencyValueMap CCurrencyValueMap::CanonicalMap() const
1229 CCurrencyValueMap retVal;
1230 for (auto valPair : valueMap)
1232 if (valPair.second != 0)
1234 retVal.valueMap.insert(valPair);
1240 CCurrencyValueMap CCurrencyValueMap::NonIntersectingValues(const CCurrencyValueMap& operand) const
1242 CCurrencyValueMap retVal = operand;
1244 if (valueMap.size() && operand.valueMap.size())
1246 for (auto &oneVal : valueMap)
1248 auto it = operand.valueMap.find(oneVal.first);
1249 if (it != operand.valueMap.end())
1251 if (it->second > 0 && oneVal.second > 0)
1253 retVal.valueMap.erase(it);
1261 bool CCurrencyValueMap::IsValid() const
1263 for (auto &oneVal : valueMap)
1265 if (oneVal.first.IsNull())
1273 bool CCurrencyValueMap::HasNegative() const
1275 for (auto &oneVal : valueMap)
1277 if (oneVal.second < 0)
1285 // subtract, but do not subtract to negative values
1286 CCurrencyValueMap CCurrencyValueMap::SubtractToZero(const CCurrencyValueMap& operand) const
1288 CCurrencyValueMap retVal = *this;
1289 std::vector<uint160> toRemove;
1290 if (valueMap.size() && operand.valueMap.size())
1292 for (auto &oneVal : retVal.valueMap)
1294 auto it = operand.valueMap.find(oneVal.first);
1295 if (it != operand.valueMap.end())
1297 oneVal.second = oneVal.second - it->second;
1298 if (oneVal.second <= 0)
1300 toRemove.push_back(oneVal.first);
1305 for (auto &toErase : toRemove)
1307 retVal.valueMap.erase(toErase);
1312 std::vector<CAmount> CCurrencyValueMap::AsCurrencyVector(const std::vector<uint160> ¤cies) const
1314 std::vector<CAmount> retVal(currencies.size());
1315 for (int i = 0; i < currencies.size(); i++)
1317 auto it = valueMap.find(currencies[i]);
1318 retVal[i] = it != valueMap.end() ? it->second : 0;