Branch data Line data Source code
# 1 : : // Copyright (c) 2009-2010 Satoshi Nakamoto
# 2 : : // Copyright (c) 2009-2020 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 <crypto/sha256.h>
# 9 : : #include <pubkey.h>
# 10 : : #include <script/script.h>
# 11 : :
# 12 : : #include <string>
# 13 : :
# 14 : : typedef std::vector<unsigned char> valtype;
# 15 : :
# 16 : : bool fAcceptDatacarrier = DEFAULT_ACCEPT_DATACARRIER;
# 17 : : unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY;
# 18 : :
# 19 : 990768 : CScriptID::CScriptID(const CScript& in) : BaseHash(Hash160(in)) {}
# 20 : 2624 : CScriptID::CScriptID(const ScriptHash& in) : BaseHash(static_cast<uint160>(in)) {}
# 21 : :
# 22 : 106714 : ScriptHash::ScriptHash(const CScript& in) : BaseHash(Hash160(in)) {}
# 23 : 1252 : ScriptHash::ScriptHash(const CScriptID& in) : BaseHash(static_cast<uint160>(in)) {}
# 24 : :
# 25 : 33358 : PKHash::PKHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
# 26 : 131874 : PKHash::PKHash(const CKeyID& pubkey_id) : BaseHash(pubkey_id) {}
# 27 : :
# 28 : 12357 : WitnessV0KeyHash::WitnessV0KeyHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
# 29 : 1486 : WitnessV0KeyHash::WitnessV0KeyHash(const PKHash& pubkey_hash) : BaseHash(static_cast<uint160>(pubkey_hash)) {}
# 30 : :
# 31 : : CKeyID ToKeyID(const PKHash& key_hash)
# 32 : 636 : {
# 33 : 636 : return CKeyID{static_cast<uint160>(key_hash)};
# 34 : 636 : }
# 35 : :
# 36 : : CKeyID ToKeyID(const WitnessV0KeyHash& key_hash)
# 37 : 1665 : {
# 38 : 1665 : return CKeyID{static_cast<uint160>(key_hash)};
# 39 : 1665 : }
# 40 : :
# 41 : : WitnessV0ScriptHash::WitnessV0ScriptHash(const CScript& in)
# 42 : 14733 : {
# 43 : 14733 : CSHA256().Write(in.data(), in.size()).Finalize(begin());
# 44 : 14733 : }
# 45 : :
# 46 : : std::string GetTxnOutputType(TxoutType t)
# 47 : 24599 : {
# 48 [ - + ]: 24599 : switch (t) {
# 49 [ + + ]: 1377 : case TxoutType::NONSTANDARD: return "nonstandard";
# 50 [ + + ]: 2855 : case TxoutType::PUBKEY: return "pubkey";
# 51 [ + + ]: 1681 : case TxoutType::PUBKEYHASH: return "pubkeyhash";
# 52 [ + + ]: 1777 : case TxoutType::SCRIPTHASH: return "scripthash";
# 53 [ + + ]: 1552 : case TxoutType::MULTISIG: return "multisig";
# 54 [ + + ]: 2975 : case TxoutType::NULL_DATA: return "nulldata";
# 55 [ + + ]: 8091 : case TxoutType::WITNESS_V0_KEYHASH: return "witness_v0_keyhash";
# 56 [ + + ]: 1584 : case TxoutType::WITNESS_V0_SCRIPTHASH: return "witness_v0_scripthash";
# 57 [ + + ]: 1353 : case TxoutType::WITNESS_V1_TAPROOT: return "witness_v1_taproot";
# 58 [ + + ]: 1354 : case TxoutType::WITNESS_UNKNOWN: return "witness_unknown";
# 59 : 0 : } // no default case, so the compiler can warn about missing cases
# 60 : 0 : assert(false);
# 61 : 0 : }
# 62 : :
# 63 : : static bool MatchPayToPubkey(const CScript& script, valtype& pubkey)
# 64 : 2705012 : {
# 65 [ + + ][ + - ]: 2705012 : if (script.size() == CPubKey::SIZE + 2 && script[0] == CPubKey::SIZE && script.back() == OP_CHECKSIG) {
# [ + - ]
# 66 : 2078 : pubkey = valtype(script.begin() + 1, script.begin() + CPubKey::SIZE + 1);
# 67 : 2078 : return CPubKey::ValidSize(pubkey);
# 68 : 2078 : }
# 69 [ + + ][ + - ]: 2702934 : if (script.size() == CPubKey::COMPRESSED_SIZE + 2 && script[0] == CPubKey::COMPRESSED_SIZE && script.back() == OP_CHECKSIG) {
# [ + - ]
# 70 : 45537 : pubkey = valtype(script.begin() + 1, script.begin() + CPubKey::COMPRESSED_SIZE + 1);
# 71 : 45537 : return CPubKey::ValidSize(pubkey);
# 72 : 45537 : }
# 73 : 2657397 : return false;
# 74 : 2657397 : }
# 75 : :
# 76 : : static bool MatchPayToPubkeyHash(const CScript& script, valtype& pubkeyhash)
# 77 : 2657397 : {
# 78 [ + + ][ + - ]: 2657397 : if (script.size() == 25 && script[0] == OP_DUP && script[1] == OP_HASH160 && script[2] == 20 && script[23] == OP_EQUALVERIFY && script[24] == OP_CHECKSIG) {
# [ + + ][ + - ]
# [ + + ][ + + ]
# 79 : 2410874 : pubkeyhash = valtype(script.begin () + 3, script.begin() + 23);
# 80 : 2410874 : return true;
# 81 : 2410874 : }
# 82 : 246523 : return false;
# 83 : 246523 : }
# 84 : :
# 85 : : /** Test for "small positive integer" script opcodes - OP_1 through OP_16. */
# 86 : : static constexpr bool IsSmallInteger(opcodetype opcode)
# 87 : 22880 : {
# 88 [ + + ][ + + ]: 22880 : return opcode >= OP_1 && opcode <= OP_16;
# 89 : 22880 : }
# 90 : :
# 91 : : static constexpr bool IsPushdataOp(opcodetype opcode)
# 92 : 228 : {
# 93 [ + + ][ + + ]: 228 : return opcode > OP_FALSE && opcode <= OP_PUSHDATA4;
# 94 : 228 : }
# 95 : :
# 96 : : static constexpr bool IsValidMultisigKeyCount(int n_keys)
# 97 : 22864 : {
# 98 [ + - ][ + - ]: 22864 : return n_keys > 0 && n_keys <= MAX_PUBKEYS_PER_MULTISIG;
# 99 : 22864 : }
# 100 : :
# 101 : : static bool GetMultisigKeyCount(opcodetype opcode, valtype data, int& count)
# 102 : 22880 : {
# 103 [ + + ]: 22880 : if (IsSmallInteger(opcode)) {
# 104 : 22652 : count = CScript::DecodeOP_N(opcode);
# 105 : 22652 : return IsValidMultisigKeyCount(count);
# 106 : 22652 : }
# 107 : :
# 108 [ + + ]: 228 : if (IsPushdataOp(opcode)) {
# 109 [ + + ]: 220 : if (!CheckMinimalPush(data, opcode)) return false;
# 110 : 212 : try {
# 111 : 212 : count = CScriptNum(data, /* fRequireMinimal = */ true).getint();
# 112 : 212 : return IsValidMultisigKeyCount(count);
# 113 : 212 : } catch (const scriptnum_error&) {
# 114 : 0 : return false;
# 115 : 0 : }
# 116 : 8 : }
# 117 : :
# 118 : 8 : return false;
# 119 : 8 : }
# 120 : :
# 121 : : static bool MatchMultisig(const CScript& script, int& required_sigs, std::vector<valtype>& pubkeys)
# 122 : 246523 : {
# 123 : 246523 : opcodetype opcode;
# 124 : 246523 : valtype data;
# 125 : 246523 : int num_keys;
# 126 : :
# 127 : 246523 : CScript::const_iterator it = script.begin();
# 128 [ + + ][ + + ]: 246523 : if (script.size() < 1 || script.back() != OP_CHECKMULTISIG) return false;
# 129 : :
# 130 [ + + ][ - + ]: 11444 : if (!script.GetOp(it, opcode, data) || !GetMultisigKeyCount(opcode, data, required_sigs)) return false;
# [ + + ]
# 131 [ + - ][ + + ]: 36164 : while (script.GetOp(it, opcode, data) && CPubKey::ValidSize(data)) {
# 132 : 24728 : pubkeys.emplace_back(std::move(data));
# 133 : 24728 : }
# 134 [ + + ]: 11436 : if (!GetMultisigKeyCount(opcode, data, num_keys)) return false;
# 135 : :
# 136 [ + + ][ + + ]: 11428 : if (pubkeys.size() != static_cast<unsigned long>(num_keys) || num_keys < required_sigs) return false;
# 137 : :
# 138 : 11418 : return (it + 1 == script.end());
# 139 : 11418 : }
# 140 : :
# 141 : : TxoutType Solver(const CScript& scriptPubKey, std::vector<std::vector<unsigned char>>& vSolutionsRet)
# 142 : 5219947 : {
# 143 : 5219947 : vSolutionsRet.clear();
# 144 : :
# 145 : : // Shortcut for pay-to-script-hash, which are more constrained than the other types:
# 146 : : // it is always OP_HASH160 20 [20 byte hash] OP_EQUAL
# 147 [ + + ]: 5219947 : if (scriptPubKey.IsPayToScriptHash())
# 148 : 176139 : {
# 149 : 176139 : std::vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22);
# 150 : 176139 : vSolutionsRet.push_back(hashBytes);
# 151 : 176139 : return TxoutType::SCRIPTHASH;
# 152 : 176139 : }
# 153 : :
# 154 : 5043808 : int witnessversion;
# 155 : 5043808 : std::vector<unsigned char> witnessprogram;
# 156 [ + + ]: 5043808 : if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
# 157 [ + + ][ + + ]: 1970763 : if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_KEYHASH_SIZE) {
# 158 : 1911734 : vSolutionsRet.push_back(witnessprogram);
# 159 : 1911734 : return TxoutType::WITNESS_V0_KEYHASH;
# 160 : 1911734 : }
# 161 [ + + ][ + + ]: 59029 : if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_SCRIPTHASH_SIZE) {
# 162 : 39119 : vSolutionsRet.push_back(witnessprogram);
# 163 : 39119 : return TxoutType::WITNESS_V0_SCRIPTHASH;
# 164 : 39119 : }
# 165 [ + + ][ + + ]: 19910 : if (witnessversion == 1 && witnessprogram.size() == WITNESS_V1_TAPROOT_SIZE) {
# 166 : 18825 : vSolutionsRet.push_back(std::vector<unsigned char>{(unsigned char)witnessversion});
# 167 : 18825 : vSolutionsRet.push_back(std::move(witnessprogram));
# 168 : 18825 : return TxoutType::WITNESS_V1_TAPROOT;
# 169 : 18825 : }
# 170 [ + + ]: 1085 : if (witnessversion != 0) {
# 171 : 1082 : vSolutionsRet.push_back(std::vector<unsigned char>{(unsigned char)witnessversion});
# 172 : 1082 : vSolutionsRet.push_back(std::move(witnessprogram));
# 173 : 1082 : return TxoutType::WITNESS_UNKNOWN;
# 174 : 1082 : }
# 175 : 3 : return TxoutType::NONSTANDARD;
# 176 : 3 : }
# 177 : :
# 178 : : // Provably prunable, data-carrying output
# 179 : : //
# 180 : : // So long as script passes the IsUnspendable() test and all but the first
# 181 : : // byte passes the IsPushOnly() test we don't care what exactly is in the
# 182 : : // script.
# 183 [ + + ][ + + ]: 3073045 : if (scriptPubKey.size() >= 1 && scriptPubKey[0] == OP_RETURN && scriptPubKey.IsPushOnly(scriptPubKey.begin()+1)) {
# [ + + ][ + + ]
# 184 : 368042 : return TxoutType::NULL_DATA;
# 185 : 368042 : }
# 186 : :
# 187 : 2705003 : std::vector<unsigned char> data;
# 188 [ + + ]: 2705003 : if (MatchPayToPubkey(scriptPubKey, data)) {
# 189 : 47615 : vSolutionsRet.push_back(std::move(data));
# 190 : 47615 : return TxoutType::PUBKEY;
# 191 : 47615 : }
# 192 : :
# 193 [ + + ]: 2657388 : if (MatchPayToPubkeyHash(scriptPubKey, data)) {
# 194 : 2410874 : vSolutionsRet.push_back(std::move(data));
# 195 : 2410874 : return TxoutType::PUBKEYHASH;
# 196 : 2410874 : }
# 197 : :
# 198 : 246514 : int required;
# 199 : 246514 : std::vector<std::vector<unsigned char>> keys;
# 200 [ + + ]: 246514 : if (MatchMultisig(scriptPubKey, required, keys)) {
# 201 : 11418 : vSolutionsRet.push_back({static_cast<unsigned char>(required)}); // safe as required is in range 1..20
# 202 : 11418 : vSolutionsRet.insert(vSolutionsRet.end(), keys.begin(), keys.end());
# 203 : 11418 : vSolutionsRet.push_back({static_cast<unsigned char>(keys.size())}); // safe as size is in range 1..20
# 204 : 11418 : return TxoutType::MULTISIG;
# 205 : 11418 : }
# 206 : :
# 207 : 235096 : vSolutionsRet.clear();
# 208 : 235096 : return TxoutType::NONSTANDARD;
# 209 : 235096 : }
# 210 : :
# 211 : : bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
# 212 : 663760 : {
# 213 : 663760 : std::vector<valtype> vSolutions;
# 214 : 663760 : TxoutType whichType = Solver(scriptPubKey, vSolutions);
# 215 : :
# 216 [ - + ]: 663760 : switch (whichType) {
# 217 [ + + ]: 2952 : case TxoutType::PUBKEY: {
# 218 : 2952 : CPubKey pubKey(vSolutions[0]);
# 219 [ - + ]: 2952 : if (!pubKey.IsValid())
# 220 : 0 : return false;
# 221 : :
# 222 : 2952 : addressRet = PKHash(pubKey);
# 223 : 2952 : return true;
# 224 : 2952 : }
# 225 [ + + ]: 131539 : case TxoutType::PUBKEYHASH: {
# 226 : 131539 : addressRet = PKHash(uint160(vSolutions[0]));
# 227 : 131539 : return true;
# 228 : 2952 : }
# 229 [ + + ]: 11787 : case TxoutType::SCRIPTHASH: {
# 230 : 11787 : addressRet = ScriptHash(uint160(vSolutions[0]));
# 231 : 11787 : return true;
# 232 : 2952 : }
# 233 [ + + ]: 354964 : case TxoutType::WITNESS_V0_KEYHASH: {
# 234 : 354964 : WitnessV0KeyHash hash;
# 235 : 354964 : std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
# 236 : 354964 : addressRet = hash;
# 237 : 354964 : return true;
# 238 : 2952 : }
# 239 [ + + ]: 2952 : case TxoutType::WITNESS_V0_SCRIPTHASH: {
# 240 : 1778 : WitnessV0ScriptHash hash;
# 241 : 1778 : std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
# 242 : 1778 : addressRet = hash;
# 243 : 1778 : return true;
# 244 : 2952 : }
# 245 [ + + ]: 2952 : case TxoutType::WITNESS_UNKNOWN:
# 246 [ + + ]: 2517 : case TxoutType::WITNESS_V1_TAPROOT: {
# 247 : 2517 : WitnessUnknown unk;
# 248 : 2517 : unk.version = vSolutions[0][0];
# 249 : 2517 : std::copy(vSolutions[1].begin(), vSolutions[1].end(), unk.program);
# 250 : 2517 : unk.length = vSolutions[1].size();
# 251 : 2517 : addressRet = unk;
# 252 : 2517 : return true;
# 253 : 155 : }
# 254 [ + + ]: 359 : case TxoutType::MULTISIG:
# 255 [ + + ]: 156439 : case TxoutType::NULL_DATA:
# 256 [ + + ]: 158223 : case TxoutType::NONSTANDARD:
# 257 : 158223 : return false;
# 258 : 0 : } // no default case, so the compiler can warn about missing cases
# 259 : 0 : assert(false);
# 260 : 0 : }
# 261 : :
# 262 : : // TODO: from v23 ("addresses" and "reqSigs" deprecated) "ExtractDestinations" should be removed
# 263 : : bool ExtractDestinations(const CScript& scriptPubKey, TxoutType& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet)
# 264 : 10426 : {
# 265 : 10426 : addressRet.clear();
# 266 : 10426 : std::vector<valtype> vSolutions;
# 267 : 10426 : typeRet = Solver(scriptPubKey, vSolutions);
# 268 [ + + ]: 10426 : if (typeRet == TxoutType::NONSTANDARD) {
# 269 : 24 : return false;
# 270 [ + + ]: 10402 : } else if (typeRet == TxoutType::NULL_DATA) {
# 271 : : // This is data, not addresses
# 272 : 1624 : return false;
# 273 : 1624 : }
# 274 : :
# 275 [ + + ]: 8778 : if (typeRet == TxoutType::MULTISIG)
# 276 : 6 : {
# 277 : 6 : nRequiredRet = vSolutions.front()[0];
# 278 [ + + ]: 21 : for (unsigned int i = 1; i < vSolutions.size()-1; i++)
# 279 : 15 : {
# 280 : 15 : CPubKey pubKey(vSolutions[i]);
# 281 [ - + ]: 15 : if (!pubKey.IsValid())
# 282 : 0 : continue;
# 283 : :
# 284 : 15 : CTxDestination address = PKHash(pubKey);
# 285 : 15 : addressRet.push_back(address);
# 286 : 15 : }
# 287 : :
# 288 [ - + ]: 6 : if (addressRet.empty())
# 289 : 0 : return false;
# 290 : 8772 : }
# 291 : 8772 : else
# 292 : 8772 : {
# 293 : 8772 : nRequiredRet = 1;
# 294 : 8772 : CTxDestination address;
# 295 [ - + ]: 8772 : if (!ExtractDestination(scriptPubKey, address))
# 296 : 0 : return false;
# 297 : 8772 : addressRet.push_back(address);
# 298 : 8772 : }
# 299 : :
# 300 : 8778 : return true;
# 301 : 8778 : }
# 302 : :
# 303 : : namespace {
# 304 : : class CScriptVisitor
# 305 : : {
# 306 : : public:
# 307 : : CScript operator()(const CNoDestination& dest) const
# 308 : 35 : {
# 309 : 35 : return CScript();
# 310 : 35 : }
# 311 : :
# 312 : : CScript operator()(const PKHash& keyID) const
# 313 : 716087 : {
# 314 : 716087 : return CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
# 315 : 716087 : }
# 316 : :
# 317 : : CScript operator()(const ScriptHash& scriptID) const
# 318 : 109692 : {
# 319 : 109692 : return CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
# 320 : 109692 : }
# 321 : :
# 322 : : CScript operator()(const WitnessV0KeyHash& id) const
# 323 : 525100 : {
# 324 : 525100 : return CScript() << OP_0 << ToByteVector(id);
# 325 : 525100 : }
# 326 : :
# 327 : : CScript operator()(const WitnessV0ScriptHash& id) const
# 328 : 16347 : {
# 329 : 16347 : return CScript() << OP_0 << ToByteVector(id);
# 330 : 16347 : }
# 331 : :
# 332 : : CScript operator()(const WitnessUnknown& id) const
# 333 : 5036 : {
# 334 : 5036 : return CScript() << CScript::EncodeOP_N(id.version) << std::vector<unsigned char>(id.program, id.program + id.length);
# 335 : 5036 : }
# 336 : : };
# 337 : : } // namespace
# 338 : :
# 339 : : CScript GetScriptForDestination(const CTxDestination& dest)
# 340 : 1372297 : {
# 341 : 1372297 : return std::visit(CScriptVisitor(), dest);
# 342 : 1372297 : }
# 343 : :
# 344 : : CScript GetScriptForRawPubKey(const CPubKey& pubKey)
# 345 : 118553 : {
# 346 : 118553 : return CScript() << std::vector<unsigned char>(pubKey.begin(), pubKey.end()) << OP_CHECKSIG;
# 347 : 118553 : }
# 348 : :
# 349 : : CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys)
# 350 : 17306 : {
# 351 : 17306 : CScript script;
# 352 : :
# 353 : 17306 : script << nRequired;
# 354 [ + + ]: 17306 : for (const CPubKey& key : keys)
# 355 : 110402 : script << ToByteVector(key);
# 356 : 17306 : script << keys.size() << OP_CHECKMULTISIG;
# 357 : :
# 358 : 17306 : return script;
# 359 : 17306 : }
# 360 : :
# 361 : 31417 : bool IsValidDestination(const CTxDestination& dest) {
# 362 : 31417 : return dest.index() != 0;
# 363 : 31417 : }
|