Coverage Report

Created: 2026-05-06 07:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/tmp/bitcoin/src/addresstype.cpp
Line
Count
Source
1
// Copyright (c) 2023-present 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
132k
ScriptHash::ScriptHash(const CScript& in) : BaseHash(Hash160(in)) {}
21
0
ScriptHash::ScriptHash(const CScriptID& in) : BaseHash{in} {}
22
23
724
PKHash::PKHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
24
147k
PKHash::PKHash(const CKeyID& pubkey_id) : BaseHash(pubkey_id) {}
25
26
570
WitnessV0KeyHash::WitnessV0KeyHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
27
1
WitnessV0KeyHash::WitnessV0KeyHash(const PKHash& pubkey_hash) : BaseHash{pubkey_hash} {}
28
29
CKeyID ToKeyID(const PKHash& key_hash)
30
199
{
31
199
    return CKeyID{uint160{key_hash}};
32
199
}
33
34
CKeyID ToKeyID(const WitnessV0KeyHash& key_hash)
35
882
{
36
882
    return CKeyID{uint160{key_hash}};
37
882
}
38
39
CScriptID ToScriptID(const ScriptHash& script_hash)
40
10.0k
{
41
10.0k
    return CScriptID{uint160{script_hash}};
42
10.0k
}
43
44
WitnessV0ScriptHash::WitnessV0ScriptHash(const CScript& in)
45
18.5k
{
46
18.5k
    CSHA256().Write(in.data(), in.size()).Finalize(begin());
47
18.5k
}
48
49
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
50
126k
{
51
126k
    std::vector<valtype> vSolutions;
52
126k
    TxoutType whichType = Solver(scriptPubKey, vSolutions);
53
54
126k
    switch (whichType) {
55
588
    case TxoutType::PUBKEY: {
56
588
        CPubKey pubKey(vSolutions[0]);
57
588
        if (!pubKey.IsValid()) {
58
0
            addressRet = CNoDestination(scriptPubKey);
59
588
        } else {
60
588
            addressRet = PubKeyDestination(pubKey);
61
588
        }
62
588
        return false;
63
0
    }
64
30.8k
    case TxoutType::PUBKEYHASH: {
65
30.8k
        addressRet = PKHash(uint160(vSolutions[0]));
66
30.8k
        return true;
67
0
    }
68
16.9k
    case TxoutType::SCRIPTHASH: {
69
16.9k
        addressRet = ScriptHash(uint160(vSolutions[0]));
70
16.9k
        return true;
71
0
    }
72
51.9k
    case TxoutType::WITNESS_V0_KEYHASH: {
73
51.9k
        WitnessV0KeyHash hash;
74
51.9k
        std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
75
51.9k
        addressRet = hash;
76
51.9k
        return true;
77
0
    }
78
734
    case TxoutType::WITNESS_V0_SCRIPTHASH: {
79
734
        WitnessV0ScriptHash hash;
80
734
        std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
81
734
        addressRet = hash;
82
734
        return true;
83
0
    }
84
19.9k
    case TxoutType::WITNESS_V1_TAPROOT: {
85
19.9k
        WitnessV1Taproot tap;
86
19.9k
        std::copy(vSolutions[0].begin(), vSolutions[0].end(), tap.begin());
87
19.9k
        addressRet = tap;
88
19.9k
        return true;
89
0
    }
90
49
    case TxoutType::ANCHOR: {
91
49
        addressRet = PayToAnchor();
92
49
        return true;
93
0
    }
94
54
    case TxoutType::WITNESS_UNKNOWN: {
95
54
        addressRet = WitnessUnknown{vSolutions[0][0], vSolutions[1]};
96
54
        return true;
97
0
    }
98
53
    case TxoutType::MULTISIG:
99
4.90k
    case TxoutType::NULL_DATA:
100
5.00k
    case TxoutType::NONSTANDARD:
101
5.00k
        addressRet = CNoDestination(scriptPubKey);
102
5.00k
        return false;
103
126k
    } // no default case, so the compiler can warn about missing cases
104
126k
    assert(false);
105
0
}
106
107
namespace {
108
class CScriptVisitor
109
{
110
public:
111
    CScript operator()(const CNoDestination& dest) const
112
75
    {
113
75
        return dest.GetScript();
114
75
    }
115
116
    CScript operator()(const PubKeyDestination& dest) const
117
28
    {
118
28
        return CScript() << ToByteVector(dest.GetPubKey()) << OP_CHECKSIG;
119
28
    }
120
121
    CScript operator()(const PKHash& keyID) const
122
183k
    {
123
183k
        return CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
124
183k
    }
125
126
    CScript operator()(const ScriptHash& scriptID) const
127
139k
    {
128
139k
        return CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
129
139k
    }
130
131
    CScript operator()(const WitnessV0KeyHash& id) const
132
409k
    {
133
409k
        return CScript() << OP_0 << ToByteVector(id);
134
409k
    }
135
136
    CScript operator()(const WitnessV0ScriptHash& id) const
137
18.8k
    {
138
18.8k
        return CScript() << OP_0 << ToByteVector(id);
139
18.8k
    }
140
141
    CScript operator()(const WitnessV1Taproot& tap) const
142
130k
    {
143
130k
        return CScript() << OP_1 << ToByteVector(tap);
144
130k
    }
145
146
    CScript operator()(const WitnessUnknown& id) const
147
122
    {
148
122
        return CScript() << CScript::EncodeOP_N(id.GetWitnessVersion()) << id.GetWitnessProgram();
149
122
    }
150
};
151
152
class ValidDestinationVisitor
153
{
154
public:
155
427
    bool operator()(const CNoDestination& dest) const { return false; }
156
0
    bool operator()(const PubKeyDestination& dest) const { return false; }
157
8.79k
    bool operator()(const PKHash& dest) const { return true; }
158
896
    bool operator()(const ScriptHash& dest) const { return true; }
159
12.7k
    bool operator()(const WitnessV0KeyHash& dest) const { return true; }
160
268
    bool operator()(const WitnessV0ScriptHash& dest) const { return true; }
161
1.10k
    bool operator()(const WitnessV1Taproot& dest) const { return true; }
162
41
    bool operator()(const WitnessUnknown& dest) const { return true; }
163
};
164
} // namespace
165
166
CScript GetScriptForDestination(const CTxDestination& dest)
167
881k
{
168
881k
    return std::visit(CScriptVisitor(), dest);
169
881k
}
170
171
24.2k
bool IsValidDestination(const CTxDestination& dest) {
172
24.2k
    return std::visit(ValidDestinationVisitor(), dest);
173
24.2k
}