/* * This file is part of the Flowee project * Copyright (C) 2009-2010 Satoshi Nakamoto * Copyright (C) 2009-2015 The Bitcoin Core developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "script/standard.h" #include #include #include #include "primitives/script.h" #include "util.h" #include "utilstrencodings.h" #include typedef std::vector valtype; bool fAcceptDatacarrier = Settings::DefaultAcceptDataCarrier; int nMaxDatacarrierBytes = Settings::MaxOpReturnRelay; bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) { std::vector vSolutions; Script::TxnOutType whichType; if (!Script::solver(scriptPubKey, whichType, vSolutions)) return false; if (whichType == Script::TX_PUBKEY) { PublicKey pubKey(vSolutions[0]); if (!pubKey.isValid()) return false; addressRet = pubKey.getKeyId(); return true; } else if (whichType == Script::TX_PUBKEYHASH) { addressRet = KeyId(uint160(vSolutions[0])); return true; } else if (whichType == Script::TX_SCRIPTHASH) { addressRet = CScriptID(uint160(vSolutions[0])); return true; } // Multisig txns have more than one address... return false; } bool ExtractDestinations(const CScript& scriptPubKey, Script::TxnOutType& typeRet, std::vector& addressRet, int& nRequiredRet) { addressRet.clear(); typeRet = Script::TX_NONSTANDARD; std::vector vSolutions; if (!Script::solver(scriptPubKey, typeRet, vSolutions)) return false; if (typeRet == Script::TX_NULL_DATA) { // This is data, not addresses return false; } if (typeRet == Script::TX_MULTISIG) { nRequiredRet = vSolutions.front()[0]; for (unsigned int i = 1; i < vSolutions.size()-1; i++) { PublicKey pubKey(vSolutions[i]); if (!pubKey.isValid()) continue; CTxDestination address = pubKey.getKeyId(); addressRet.push_back(address); } if (addressRet.empty()) return false; } else { nRequiredRet = 1; CTxDestination address; if (!ExtractDestination(scriptPubKey, address)) return false; addressRet.push_back(address); } return true; } namespace { class CScriptVisitor : public boost::static_visitor { private: CScript *script; public: CScriptVisitor(CScript *scriptin) { script = scriptin; } bool operator()(const CNoDestination &dest) const { script->clear(); return false; } bool operator()(const KeyId &keyID) const { script->clear(); *script << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG; return true; } bool operator()(const CScriptID &scriptID) const { script->clear(); *script << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL; return true; } }; } CScript GetScriptForDestination(const CTxDestination& dest) { CScript script; boost::apply_visitor(CScriptVisitor(&script), dest); return script; } CScript GetScriptForRawPubKey(const PublicKey& pubKey) { return CScript() << std::vector(pubKey.begin(), pubKey.end()) << OP_CHECKSIG; } CScript GetScriptForMultisig(int nRequired, const std::vector& keys) { CScript script; script << CScript::EncodeOP_N(nRequired); BOOST_FOREACH(const PublicKey& key, keys) script << ToByteVector(key); script << CScript::EncodeOP_N(keys.size()) << OP_CHECKMULTISIG; return script; }