Coverage Report

Created: 2024-10-21 15:10

/root/bitcoin/src/addresstype.cpp
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2023 The Bitcoin Core developers
2
// Distributed under the MIT software license, see the accompanying
3
// file COPYING or https://www.opensource.org/licenses/mit-license.php.
4
5
#include <addresstype.h>
6
7
#include <crypto/sha256.h>
8
#include <hash.h>
9
#include <pubkey.h>
10
#include <script/script.h>
11
#include <script/solver.h>
12
#include <uint256.h>
13
#include <util/hash_type.h>
14
15
#include <cassert>
16
#include <vector>
17
18
typedef std::vector<unsigned char> valtype;
19
20
0
ScriptHash::ScriptHash(const CScript& in) : BaseHash(Hash160(in)) {}
21
0
ScriptHash::ScriptHash(const CScriptID& in) : BaseHash{in} {}
22
23
0
PKHash::PKHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
24
0
PKHash::PKHash(const CKeyID& pubkey_id) : BaseHash(pubkey_id) {}
25
26
0
WitnessV0KeyHash::WitnessV0KeyHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
27
0
WitnessV0KeyHash::WitnessV0KeyHash(const PKHash& pubkey_hash) : BaseHash{pubkey_hash} {}
28
29
CKeyID ToKeyID(const PKHash& key_hash)
30
0
{
31
0
    return CKeyID{uint160{key_hash}};
32
0
}
33
34
CKeyID ToKeyID(const WitnessV0KeyHash& key_hash)
35
0
{
36
0
    return CKeyID{uint160{key_hash}};
37
0
}
38
39
CScriptID ToScriptID(const ScriptHash& script_hash)
40
0
{
41
0
    return CScriptID{uint160{script_hash}};
42
0
}
43
44
WitnessV0ScriptHash::WitnessV0ScriptHash(const CScript& in)
45
0
{
46
0
    CSHA256().Write(in.data(), in.size()).Finalize(begin());
47
0
}
48
49
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
50
0
{
51
0
    std::vector<valtype> vSolutions;
52
0
    TxoutType whichType = Solver(scriptPubKey, vSolutions);
53
54
0
    switch (whichType) {
55
0
    case TxoutType::PUBKEY: {
56
0
        CPubKey pubKey(vSolutions[0]);
57
0
        if (!pubKey.IsValid()) {
58
0
            addressRet = CNoDestination(scriptPubKey);
59
0
        } else {
60
0
            addressRet = PubKeyDestination(pubKey);
61
0
        }
62
0
        return false;
63
0
    }
64
0
    case TxoutType::PUBKEYHASH: {
65
0
        addressRet = PKHash(uint160(vSolutions[0]));
66
0
        return true;
67
0
    }
68
0
    case TxoutType::SCRIPTHASH: {
69
0
        addressRet = ScriptHash(uint160(vSolutions[0]));
70
0
        return true;
71
0
    }
72
0
    case TxoutType::WITNESS_V0_KEYHASH: {
73
0
        WitnessV0KeyHash hash;
74
0
        std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
75
0
        addressRet = hash;
76
0
        return true;
77
0
    }
78
0
    case TxoutType::WITNESS_V0_SCRIPTHASH: {
79
0
        WitnessV0ScriptHash hash;
80
0
        std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
81
0
        addressRet = hash;
82
0
        return true;
83
0
    }
84
0
    case TxoutType::WITNESS_V1_TAPROOT: {
85
0
        WitnessV1Taproot tap;
86
0
        std::copy(vSolutions[0].begin(), vSolutions[0].end(), tap.begin());
87
0
        addressRet = tap;
88
0
        return true;
89
0
    }
90
0
    case TxoutType::ANCHOR: {
91
0
        addressRet = PayToAnchor();
92
0
        return true;
93
0
    }
94
0
    case TxoutType::WITNESS_UNKNOWN: {
95
0
        addressRet = WitnessUnknown{vSolutions[0][0], vSolutions[1]};
96
0
        return true;
97
0
    }
98
0
    case TxoutType::MULTISIG:
99
0
    case TxoutType::NULL_DATA:
100
0
    case TxoutType::NONSTANDARD:
101
0
        addressRet = CNoDestination(scriptPubKey);
102
0
        return false;
103
0
    } // no default case, so the compiler can warn about missing cases
104
0
    assert(false);
105
0
}
106
107
namespace {
108
class CScriptVisitor
109
{
110
public:
111
    CScript operator()(const CNoDestination& dest) const
112
0
    {
113
0
        return dest.GetScript();
114
0
    }
115
116
    CScript operator()(const PubKeyDestination& dest) const
117
0
    {
118
0
        return CScript() << ToByteVector(dest.GetPubKey()) << OP_CHECKSIG;
119
0
    }
120
121
    CScript operator()(const PKHash& keyID) const
122
0
    {
123
0
        return CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
124
0
    }
125
126
    CScript operator()(const ScriptHash& scriptID) const
127
0
    {
128
0
        return CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
129
0
    }
130
131
    CScript operator()(const WitnessV0KeyHash& id) const
132
0
    {
133
0
        return CScript() << OP_0 << ToByteVector(id);
134
0
    }
135
136
    CScript operator()(const WitnessV0ScriptHash& id) const
137
0
    {
138
0
        return CScript() << OP_0 << ToByteVector(id);
139
0
    }
140
141
    CScript operator()(const WitnessV1Taproot& tap) const
142
0
    {
143
0
        return CScript() << OP_1 << ToByteVector(tap);
144
0
    }
145
146
    CScript operator()(const WitnessUnknown& id) const
147
0
    {
148
0
        return CScript() << CScript::EncodeOP_N(id.GetWitnessVersion()) << id.GetWitnessProgram();
149
0
    }
150
};
151
152
class ValidDestinationVisitor
153
{
154
public:
155
0
    bool operator()(const CNoDestination& dest) const { return false; }
156
0
    bool operator()(const PubKeyDestination& dest) const { return false; }
157
0
    bool operator()(const PKHash& dest) const { return true; }
158
0
    bool operator()(const ScriptHash& dest) const { return true; }
159
0
    bool operator()(const WitnessV0KeyHash& dest) const { return true; }
160
0
    bool operator()(const WitnessV0ScriptHash& dest) const { return true; }
161
0
    bool operator()(const WitnessV1Taproot& dest) const { return true; }
162
0
    bool operator()(const WitnessUnknown& dest) const { return true; }
163
};
164
} // namespace
165
166
CScript GetScriptForDestination(const CTxDestination& dest)
167
0
{
168
0
    return std::visit(CScriptVisitor(), dest);
169
0
}
170
171
0
bool IsValidDestination(const CTxDestination& dest) {
172
0
    return std::visit(ValidDestinationVisitor(), dest);
173
0
}