Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto 2 : // Copyright (c) 2009-2021 The Bitcoin Core developers 3 : // Distributed under the MIT software license, see the accompanying 4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 5 : 6 : #include <script/standard.h> 7 : 8 : #include <pubkey.h> 9 : #include <script/script.h> 10 : 11 : #include <string> 12 : 13 : typedef std::vector<unsigned char> valtype; 14 : 15 : bool fAcceptDatacarrier = DEFAULT_ACCEPT_DATACARRIER; 16 : unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY; 17 : 18 149498 : CScriptID::CScriptID(const CScript& in) : BaseHash(Hash160(in)) {} 19 1784 : CScriptID::CScriptID(const ScriptHash& in) : BaseHash(static_cast<uint160>(in)) {} 20 : 21 136440 : ScriptHash::ScriptHash(const CScript& in) : BaseHash(Hash160(in)) {} 22 24 : ScriptHash::ScriptHash(const CScriptID& in) : BaseHash(static_cast<uint160>(in)) {} 23 : 24 142840 : PKHash::PKHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {} 25 902976 : PKHash::PKHash(const CKeyID& pubkey_id) : BaseHash(pubkey_id) {} 26 : 27 12465 : CKeyID ToKeyID(const PKHash& key_hash) 28 : { 29 12465 : return CKeyID{static_cast<uint160>(key_hash)}; 30 : } 31 : 32 69080 : std::string GetTxnOutputType(TxoutType t) 33 : { 34 69080 : switch (t) { 35 6237 : case TxoutType::NONSTANDARD: return "nonstandard"; 36 6539 : case TxoutType::PUBKEY: return "pubkey"; 37 26466 : case TxoutType::PUBKEYHASH: return "pubkeyhash"; 38 17112 : case TxoutType::SCRIPTHASH: return "scripthash"; 39 6272 : case TxoutType::MULTISIG: return "multisig"; 40 6454 : case TxoutType::NULL_DATA: return "nulldata"; 41 : } // no default case, so the compiler can warn about missing cases 42 0 : assert(false); 43 69080 : } 44 : 45 4275341 : static bool MatchPayToPubkey(const CScript& script, valtype& pubkey) 46 : { 47 4275341 : if (script.size() == CPubKey::SIZE + 2 && script[0] == CPubKey::SIZE && script.back() == OP_CHECKSIG) { 48 883 : pubkey = valtype(script.begin() + 1, script.begin() + CPubKey::SIZE + 1); 49 883 : return CPubKey::ValidSize(pubkey); 50 : } 51 4274458 : if (script.size() == CPubKey::COMPRESSED_SIZE + 2 && script[0] == CPubKey::COMPRESSED_SIZE && script.back() == OP_CHECKSIG) { 52 44012 : pubkey = valtype(script.begin() + 1, script.begin() + CPubKey::COMPRESSED_SIZE + 1); 53 44012 : return CPubKey::ValidSize(pubkey); 54 : } 55 4230446 : return false; 56 4275341 : } 57 : 58 4230442 : static bool MatchPayToPubkeyHash(const CScript& script, valtype& pubkeyhash) 59 : { 60 4230442 : if (script.size() == 25 && script[0] == OP_DUP && script[1] == OP_HASH160 && script[2] == 20 && script[23] == OP_EQUALVERIFY && script[24] == OP_CHECKSIG) { 61 4224095 : pubkeyhash = valtype(script.begin () + 3, script.begin() + 23); 62 4224095 : return true; 63 : } 64 6349 : return false; 65 4230444 : } 66 : 67 : /** Test for "small positive integer" script opcodes - OP_1 through OP_16. */ 68 3378 : static constexpr bool IsSmallInteger(opcodetype opcode) 69 : { 70 3378 : return opcode >= OP_1 && opcode <= OP_16; 71 : } 72 : 73 3370 : static constexpr bool IsValidMultisigKeyCount(int n_keys) 74 : { 75 3370 : return n_keys > 0 && n_keys <= MAX_PUBKEYS_PER_MULTISIG; 76 : } 77 : 78 3378 : static bool GetMultisigKeyCount(opcodetype opcode, valtype data, int& count) 79 : { 80 3378 : if (IsSmallInteger(opcode)) { 81 3370 : count = CScript::DecodeOP_N(opcode); 82 3370 : return IsValidMultisigKeyCount(count); 83 : } 84 : 85 8 : if (IsPushdataOp(opcode)) { 86 4 : if (!CheckMinimalPush(data, opcode)) return false; 87 : try { 88 0 : count = CScriptNum(data, /* fRequireMinimal = */ true).getint(); 89 0 : return IsValidMultisigKeyCount(count); 90 0 : } catch (const scriptnum_error&) { 91 0 : return false; 92 0 : } 93 0 : } 94 : 95 4 : return false; 96 3378 : } 97 : 98 6349 : static bool MatchMultisig(const CScript& script, int& required_sigs, std::vector<valtype>& pubkeys) 99 : { 100 : opcodetype opcode; 101 6349 : valtype data; 102 : int num_keys; 103 : 104 6349 : CScript::const_iterator it = script.begin(); 105 6349 : if (script.size() < 1 || script.back() != OP_CHECKMULTISIG) return false; 106 : 107 1691 : if (!script.GetOp(it, opcode, data) || !GetMultisigKeyCount(opcode, data, required_sigs)) return false; 108 7735 : while (script.GetOp(it, opcode, data) && CPubKey::ValidSize(data)) { 109 6048 : pubkeys.emplace_back(std::move(data)); 110 : } 111 1687 : if (!GetMultisigKeyCount(opcode, data, num_keys)) return false; 112 : 113 1683 : if (pubkeys.size() != static_cast<unsigned long>(num_keys) || num_keys < required_sigs) return false; 114 : 115 1678 : return (it + 1 == script.end()); 116 6349 : } 117 : 118 4568940 : TxoutType Solver(const CScript& scriptPubKey, std::vector<std::vector<unsigned char>>& vSolutionsRet) 119 : { 120 4568940 : vSolutionsRet.clear(); 121 : 122 : // Shortcut for pay-to-script-hash, which are more constrained than the other types: 123 : // it is always OP_HASH160 20 [20 byte hash] OP_EQUAL 124 4568940 : if (scriptPubKey.IsPayToScriptHash()) 125 : { 126 200174 : std::vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22); 127 200174 : vSolutionsRet.push_back(hashBytes); 128 200174 : return TxoutType::SCRIPTHASH; 129 200174 : } 130 : 131 : // Provably prunable, data-carrying output 132 : // 133 : // So long as script passes the IsUnspendable() test and all but the first 134 : // byte passes the IsPushOnly() test we don't care what exactly is in the 135 : // script. 136 4368766 : if (scriptPubKey.size() >= 1 && scriptPubKey[0] == OP_RETURN && scriptPubKey.IsPushOnly(scriptPubKey.begin()+1)) { 137 93424 : return TxoutType::NULL_DATA; 138 : } 139 : 140 4275342 : std::vector<unsigned char> data; 141 4275342 : if (MatchPayToPubkey(scriptPubKey, data)) { 142 44895 : vSolutionsRet.push_back(std::move(data)); 143 44895 : return TxoutType::PUBKEY; 144 : } 145 : 146 4230445 : if (MatchPayToPubkeyHash(scriptPubKey, data)) { 147 4224095 : vSolutionsRet.push_back(std::move(data)); 148 4224094 : return TxoutType::PUBKEYHASH; 149 : } 150 : 151 : int required; 152 6349 : std::vector<std::vector<unsigned char>> keys; 153 6349 : if (MatchMultisig(scriptPubKey, required, keys)) { 154 1678 : vSolutionsRet.push_back({static_cast<unsigned char>(required)}); // safe as required is in range 1..20 155 1678 : vSolutionsRet.insert(vSolutionsRet.end(), keys.begin(), keys.end()); 156 1678 : vSolutionsRet.push_back({static_cast<unsigned char>(keys.size())}); // safe as size is in range 1..20 157 1678 : return TxoutType::MULTISIG; 158 : } 159 : 160 4671 : vSolutionsRet.clear(); 161 4671 : return TxoutType::NONSTANDARD; 162 4568940 : } 163 : 164 313829 : bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) 165 : { 166 313829 : std::vector<valtype> vSolutions; 167 313829 : TxoutType whichType = Solver(scriptPubKey, vSolutions); 168 : 169 313829 : switch (whichType) { 170 : case TxoutType::PUBKEY: { 171 896 : CPubKey pubKey(vSolutions[0]); 172 896 : if (!pubKey.IsValid()) 173 0 : return false; 174 : 175 896 : addressRet = PKHash(pubKey); 176 896 : return true; 177 : } 178 : case TxoutType::PUBKEYHASH: { 179 261570 : addressRet = PKHash(uint160(vSolutions[0])); 180 261570 : return true; 181 : } 182 : case TxoutType::SCRIPTHASH: { 183 25757 : addressRet = ScriptHash(uint160(vSolutions[0])); 184 25757 : return true; 185 : } 186 : case TxoutType::MULTISIG: 187 : case TxoutType::NULL_DATA: 188 : case TxoutType::NONSTANDARD: 189 25606 : return false; 190 : } // no default case, so the compiler can warn about missing cases 191 0 : assert(false); 192 313829 : } 193 : 194 : namespace { 195 : class CScriptVisitor 196 : { 197 : public: 198 16 : CScript operator()(const CNoDestination& dest) const 199 : { 200 16 : return CScript(); 201 : } 202 : 203 575635 : CScript operator()(const PKHash& keyID) const 204 : { 205 575635 : return CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG; 206 0 : } 207 : 208 83469 : CScript operator()(const ScriptHash& scriptID) const 209 : { 210 83469 : return CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL; 211 0 : } 212 : }; 213 : } // namespace 214 : 215 659120 : CScript GetScriptForDestination(const CTxDestination& dest) 216 : { 217 659120 : return std::visit(CScriptVisitor(), dest); 218 : } 219 : 220 85197 : CScript GetScriptForRawPubKey(const CPubKey& pubKey) 221 : { 222 85197 : return CScript() << std::vector<unsigned char>(pubKey.begin(), pubKey.end()) << OP_CHECKSIG; 223 0 : } 224 : 225 30220 : CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys) 226 : { 227 30220 : CScript script; 228 : 229 30220 : script << nRequired; 230 168864 : for (const CPubKey& key : keys) 231 138644 : script << ToByteVector(key); 232 30220 : script << keys.size() << OP_CHECKMULTISIG; 233 : 234 30220 : return script; 235 30220 : } 236 : 237 70451 : bool IsValidDestination(const CTxDestination& dest) { 238 70451 : return dest.index() != 0; 239 : }