aboutsummaryrefslogtreecommitdiff
path: root/src/addresstype.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/addresstype.cpp')
-rw-r--r--src/addresstype.cpp150
1 files changed, 150 insertions, 0 deletions
diff --git a/src/addresstype.cpp b/src/addresstype.cpp
new file mode 100644
index 0000000000..96428df846
--- /dev/null
+++ b/src/addresstype.cpp
@@ -0,0 +1,150 @@
+// Copyright (c) 2023 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or https://www.opensource.org/licenses/mit-license.php.
+
+#include <addresstype.h>
+#include <script/script.h>
+#include <script/standard.h>
+#include <hash.h>
+#include <pubkey.h>
+#include <uint256.h>
+#include <util/hash_type.h>
+
+#include <vector>
+
+typedef std::vector<unsigned char> valtype;
+
+ScriptHash::ScriptHash(const CScript& in) : BaseHash(Hash160(in)) {}
+ScriptHash::ScriptHash(const CScriptID& in) : BaseHash(static_cast<uint160>(in)) {}
+
+PKHash::PKHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
+PKHash::PKHash(const CKeyID& pubkey_id) : BaseHash(pubkey_id) {}
+
+WitnessV0KeyHash::WitnessV0KeyHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
+WitnessV0KeyHash::WitnessV0KeyHash(const PKHash& pubkey_hash) : BaseHash(static_cast<uint160>(pubkey_hash)) {}
+
+CKeyID ToKeyID(const PKHash& key_hash)
+{
+ return CKeyID{static_cast<uint160>(key_hash)};
+}
+
+CKeyID ToKeyID(const WitnessV0KeyHash& key_hash)
+{
+ return CKeyID{static_cast<uint160>(key_hash)};
+}
+
+CScriptID ToScriptID(const ScriptHash& script_hash)
+{
+ return CScriptID{static_cast<uint160>(script_hash)};
+}
+
+WitnessV0ScriptHash::WitnessV0ScriptHash(const CScript& in)
+{
+ CSHA256().Write(in.data(), in.size()).Finalize(begin());
+}
+
+bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
+{
+ std::vector<valtype> vSolutions;
+ TxoutType whichType = Solver(scriptPubKey, vSolutions);
+
+ switch (whichType) {
+ case TxoutType::PUBKEY: {
+ CPubKey pubKey(vSolutions[0]);
+ if (!pubKey.IsValid())
+ return false;
+
+ addressRet = PKHash(pubKey);
+ return true;
+ }
+ case TxoutType::PUBKEYHASH: {
+ addressRet = PKHash(uint160(vSolutions[0]));
+ return true;
+ }
+ case TxoutType::SCRIPTHASH: {
+ addressRet = ScriptHash(uint160(vSolutions[0]));
+ return true;
+ }
+ case TxoutType::WITNESS_V0_KEYHASH: {
+ WitnessV0KeyHash hash;
+ std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
+ addressRet = hash;
+ return true;
+ }
+ case TxoutType::WITNESS_V0_SCRIPTHASH: {
+ WitnessV0ScriptHash hash;
+ std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
+ addressRet = hash;
+ return true;
+ }
+ case TxoutType::WITNESS_V1_TAPROOT: {
+ WitnessV1Taproot tap;
+ std::copy(vSolutions[0].begin(), vSolutions[0].end(), tap.begin());
+ addressRet = tap;
+ return true;
+ }
+ case TxoutType::WITNESS_UNKNOWN: {
+ WitnessUnknown unk;
+ unk.version = vSolutions[0][0];
+ std::copy(vSolutions[1].begin(), vSolutions[1].end(), unk.program);
+ unk.length = vSolutions[1].size();
+ addressRet = unk;
+ return true;
+ }
+ case TxoutType::MULTISIG:
+ case TxoutType::NULL_DATA:
+ case TxoutType::NONSTANDARD:
+ return false;
+ } // no default case, so the compiler can warn about missing cases
+ assert(false);
+}
+
+namespace {
+class CScriptVisitor
+{
+public:
+ CScript operator()(const CNoDestination& dest) const
+ {
+ return CScript();
+ }
+
+ CScript operator()(const PKHash& keyID) const
+ {
+ return CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
+ }
+
+ CScript operator()(const ScriptHash& scriptID) const
+ {
+ return CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
+ }
+
+ CScript operator()(const WitnessV0KeyHash& id) const
+ {
+ return CScript() << OP_0 << ToByteVector(id);
+ }
+
+ CScript operator()(const WitnessV0ScriptHash& id) const
+ {
+ return CScript() << OP_0 << ToByteVector(id);
+ }
+
+ CScript operator()(const WitnessV1Taproot& tap) const
+ {
+ return CScript() << OP_1 << ToByteVector(tap);
+ }
+
+ CScript operator()(const WitnessUnknown& id) const
+ {
+ return CScript() << CScript::EncodeOP_N(id.version) << std::vector<unsigned char>(id.program, id.program + id.length);
+ }
+};
+} // namespace
+
+CScript GetScriptForDestination(const CTxDestination& dest)
+{
+ return std::visit(CScriptVisitor(), dest);
+}
+
+bool IsValidDestination(const CTxDestination& dest) {
+ return dest.index() != 0;
+}