Bitcoin Core  21.99.0
P2P Digital Currency
standard.cpp
Go to the documentation of this file.
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 
18 
20 CScriptID::CScriptID(const ScriptHash& in) : BaseHash(static_cast<uint160>(in)) {}
21 
23 ScriptHash::ScriptHash(const CScriptID& in) : BaseHash(static_cast<uint160>(in)) {}
24 
25 PKHash::PKHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
26 PKHash::PKHash(const CKeyID& pubkey_id) : BaseHash(pubkey_id) {}
27 
28 WitnessV0KeyHash::WitnessV0KeyHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
29 WitnessV0KeyHash::WitnessV0KeyHash(const PKHash& pubkey_hash) : BaseHash(static_cast<uint160>(pubkey_hash)) {}
30 
31 CKeyID ToKeyID(const PKHash& key_hash)
32 {
33  return CKeyID{static_cast<uint160>(key_hash)};
34 }
35 
37 {
38  return CKeyID{static_cast<uint160>(key_hash)};
39 }
40 
42 {
43  CSHA256().Write(in.data(), in.size()).Finalize(begin());
44 }
45 
47 {
48  switch (t) {
49  case TxoutType::NONSTANDARD: return "nonstandard";
50  case TxoutType::PUBKEY: return "pubkey";
51  case TxoutType::PUBKEYHASH: return "pubkeyhash";
52  case TxoutType::SCRIPTHASH: return "scripthash";
53  case TxoutType::MULTISIG: return "multisig";
54  case TxoutType::NULL_DATA: return "nulldata";
55  case TxoutType::WITNESS_V0_KEYHASH: return "witness_v0_keyhash";
56  case TxoutType::WITNESS_V0_SCRIPTHASH: return "witness_v0_scripthash";
57  case TxoutType::WITNESS_V1_TAPROOT: return "witness_v1_taproot";
58  case TxoutType::WITNESS_UNKNOWN: return "witness_unknown";
59  } // no default case, so the compiler can warn about missing cases
60  assert(false);
61 }
62 
63 static bool MatchPayToPubkey(const CScript& script, valtype& pubkey)
64 {
65  if (script.size() == CPubKey::SIZE + 2 && script[0] == CPubKey::SIZE && script.back() == OP_CHECKSIG) {
66  pubkey = valtype(script.begin() + 1, script.begin() + CPubKey::SIZE + 1);
67  return CPubKey::ValidSize(pubkey);
68  }
69  if (script.size() == CPubKey::COMPRESSED_SIZE + 2 && script[0] == CPubKey::COMPRESSED_SIZE && script.back() == OP_CHECKSIG) {
70  pubkey = valtype(script.begin() + 1, script.begin() + CPubKey::COMPRESSED_SIZE + 1);
71  return CPubKey::ValidSize(pubkey);
72  }
73  return false;
74 }
75 
76 static bool MatchPayToPubkeyHash(const CScript& script, valtype& pubkeyhash)
77 {
78  if (script.size() == 25 && script[0] == OP_DUP && script[1] == OP_HASH160 && script[2] == 20 && script[23] == OP_EQUALVERIFY && script[24] == OP_CHECKSIG) {
79  pubkeyhash = valtype(script.begin () + 3, script.begin() + 23);
80  return true;
81  }
82  return false;
83 }
84 
86 static constexpr bool IsSmallInteger(opcodetype opcode)
87 {
88  return opcode >= OP_1 && opcode <= OP_16;
89 }
90 
91 static bool MatchMultisig(const CScript& script, unsigned int& required, std::vector<valtype>& pubkeys)
92 {
93  opcodetype opcode;
94  valtype data;
95  CScript::const_iterator it = script.begin();
96  if (script.size() < 1 || script.back() != OP_CHECKMULTISIG) return false;
97 
98  if (!script.GetOp(it, opcode, data) || !IsSmallInteger(opcode)) return false;
99  required = CScript::DecodeOP_N(opcode);
100  while (script.GetOp(it, opcode, data) && CPubKey::ValidSize(data)) {
101  pubkeys.emplace_back(std::move(data));
102  }
103  if (!IsSmallInteger(opcode)) return false;
104  unsigned int keys = CScript::DecodeOP_N(opcode);
105  if (pubkeys.size() != keys || keys < required) return false;
106  return (it + 1 == script.end());
107 }
108 
109 TxoutType Solver(const CScript& scriptPubKey, std::vector<std::vector<unsigned char>>& vSolutionsRet)
110 {
111  vSolutionsRet.clear();
112 
113  // Shortcut for pay-to-script-hash, which are more constrained than the other types:
114  // it is always OP_HASH160 20 [20 byte hash] OP_EQUAL
115  if (scriptPubKey.IsPayToScriptHash())
116  {
117  std::vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22);
118  vSolutionsRet.push_back(hashBytes);
119  return TxoutType::SCRIPTHASH;
120  }
121 
122  int witnessversion;
123  std::vector<unsigned char> witnessprogram;
124  if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
125  if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_KEYHASH_SIZE) {
126  vSolutionsRet.push_back(witnessprogram);
128  }
129  if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_SCRIPTHASH_SIZE) {
130  vSolutionsRet.push_back(witnessprogram);
132  }
133  if (witnessversion == 1 && witnessprogram.size() == WITNESS_V1_TAPROOT_SIZE) {
134  vSolutionsRet.push_back(std::vector<unsigned char>{(unsigned char)witnessversion});
135  vSolutionsRet.push_back(std::move(witnessprogram));
137  }
138  if (witnessversion != 0) {
139  vSolutionsRet.push_back(std::vector<unsigned char>{(unsigned char)witnessversion});
140  vSolutionsRet.push_back(std::move(witnessprogram));
142  }
143  return TxoutType::NONSTANDARD;
144  }
145 
146  // Provably prunable, data-carrying output
147  //
148  // So long as script passes the IsUnspendable() test and all but the first
149  // byte passes the IsPushOnly() test we don't care what exactly is in the
150  // script.
151  if (scriptPubKey.size() >= 1 && scriptPubKey[0] == OP_RETURN && scriptPubKey.IsPushOnly(scriptPubKey.begin()+1)) {
152  return TxoutType::NULL_DATA;
153  }
154 
155  std::vector<unsigned char> data;
156  if (MatchPayToPubkey(scriptPubKey, data)) {
157  vSolutionsRet.push_back(std::move(data));
158  return TxoutType::PUBKEY;
159  }
160 
161  if (MatchPayToPubkeyHash(scriptPubKey, data)) {
162  vSolutionsRet.push_back(std::move(data));
163  return TxoutType::PUBKEYHASH;
164  }
165 
166  unsigned int required;
167  std::vector<std::vector<unsigned char>> keys;
168  if (MatchMultisig(scriptPubKey, required, keys)) {
169  vSolutionsRet.push_back({static_cast<unsigned char>(required)}); // safe as required is in range 1..16
170  vSolutionsRet.insert(vSolutionsRet.end(), keys.begin(), keys.end());
171  vSolutionsRet.push_back({static_cast<unsigned char>(keys.size())}); // safe as size is in range 1..16
172  return TxoutType::MULTISIG;
173  }
174 
175  vSolutionsRet.clear();
176  return TxoutType::NONSTANDARD;
177 }
178 
179 bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
180 {
181  std::vector<valtype> vSolutions;
182  TxoutType whichType = Solver(scriptPubKey, vSolutions);
183 
184  switch (whichType) {
185  case TxoutType::PUBKEY: {
186  CPubKey pubKey(vSolutions[0]);
187  if (!pubKey.IsValid())
188  return false;
189 
190  addressRet = PKHash(pubKey);
191  return true;
192  }
193  case TxoutType::PUBKEYHASH: {
194  addressRet = PKHash(uint160(vSolutions[0]));
195  return true;
196  }
197  case TxoutType::SCRIPTHASH: {
198  addressRet = ScriptHash(uint160(vSolutions[0]));
199  return true;
200  }
202  WitnessV0KeyHash hash;
203  std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
204  addressRet = hash;
205  return true;
206  }
208  WitnessV0ScriptHash hash;
209  std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
210  addressRet = hash;
211  return true;
212  }
215  WitnessUnknown unk;
216  unk.version = vSolutions[0][0];
217  std::copy(vSolutions[1].begin(), vSolutions[1].end(), unk.program);
218  unk.length = vSolutions[1].size();
219  addressRet = unk;
220  return true;
221  }
222  case TxoutType::MULTISIG:
225  return false;
226  } // no default case, so the compiler can warn about missing cases
227  assert(false);
228 }
229 
230 // TODO: from v23 ("addresses" and "reqSigs" deprecated) "ExtractDestinations" should be removed
231 bool ExtractDestinations(const CScript& scriptPubKey, TxoutType& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet)
232 {
233  addressRet.clear();
234  std::vector<valtype> vSolutions;
235  typeRet = Solver(scriptPubKey, vSolutions);
236  if (typeRet == TxoutType::NONSTANDARD) {
237  return false;
238  } else if (typeRet == TxoutType::NULL_DATA) {
239  // This is data, not addresses
240  return false;
241  }
242 
243  if (typeRet == TxoutType::MULTISIG)
244  {
245  nRequiredRet = vSolutions.front()[0];
246  for (unsigned int i = 1; i < vSolutions.size()-1; i++)
247  {
248  CPubKey pubKey(vSolutions[i]);
249  if (!pubKey.IsValid())
250  continue;
251 
252  CTxDestination address = PKHash(pubKey);
253  addressRet.push_back(address);
254  }
255 
256  if (addressRet.empty())
257  return false;
258  }
259  else
260  {
261  nRequiredRet = 1;
262  CTxDestination address;
263  if (!ExtractDestination(scriptPubKey, address))
264  return false;
265  addressRet.push_back(address);
266  }
267 
268  return true;
269 }
270 
271 namespace {
272 class CScriptVisitor
273 {
274 public:
275  CScript operator()(const CNoDestination& dest) const
276  {
277  return CScript();
278  }
279 
280  CScript operator()(const PKHash& keyID) const
281  {
282  return CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
283  }
284 
285  CScript operator()(const ScriptHash& scriptID) const
286  {
287  return CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
288  }
289 
290  CScript operator()(const WitnessV0KeyHash& id) const
291  {
292  return CScript() << OP_0 << ToByteVector(id);
293  }
294 
295  CScript operator()(const WitnessV0ScriptHash& id) const
296  {
297  return CScript() << OP_0 << ToByteVector(id);
298  }
299 
300  CScript operator()(const WitnessUnknown& id) const
301  {
302  return CScript() << CScript::EncodeOP_N(id.version) << std::vector<unsigned char>(id.program, id.program + id.length);
303  }
304 };
305 } // namespace
306 
308 {
309  return std::visit(CScriptVisitor(), dest);
310 }
311 
313 {
314  return CScript() << std::vector<unsigned char>(pubKey.begin(), pubKey.end()) << OP_CHECKSIG;
315 }
316 
317 CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys)
318 {
319  CScript script;
320 
321  script << CScript::EncodeOP_N(nRequired);
322  for (const CPubKey& key : keys)
323  script << ToByteVector(key);
324  script << CScript::EncodeOP_N(keys.size()) << OP_CHECKMULTISIG;
325  return script;
326 }
327 
329  return dest.index() != 0;
330 }
WITNESS_V0_KEYHASH_SIZE
static constexpr size_t WITNESS_V0_KEYHASH_SIZE
Definition: interpreter.h:211
OP_0
@ OP_0
Definition: script.h:68
WITNESS_V0_SCRIPTHASH_SIZE
static constexpr size_t WITNESS_V0_SCRIPTHASH_SIZE
Signature hash sizes.
Definition: interpreter.h:210
WitnessUnknown
CTxDestination subtype to encode any future Witness version.
Definition: standard.h:180
CSHA256::Write
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:637
Solver
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
Definition: standard.cpp:109
ScriptHash::ScriptHash
ScriptHash()
Definition: standard.h:152
prevector::const_iterator
Definition: prevector.h:98
TxoutType
TxoutType
Definition: standard.h:120
TxoutType::NONSTANDARD
@ NONSTANDARD
TxoutType::WITNESS_UNKNOWN
@ WITNESS_UNKNOWN
Only for Witness versions not already defined above.
GetScriptForDestination
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
Definition: standard.cpp:307
WitnessUnknown::version
unsigned int version
Definition: standard.h:182
CPubKey::SIZE
static constexpr unsigned int SIZE
secp256k1:
Definition: pubkey.h:37
CScript::IsWitnessProgram
bool IsWitnessProgram(int &version, std::vector< unsigned char > &program) const
Definition: script.cpp:220
BaseHash< uint256 >::begin
unsigned char * begin()
Definition: standard.h:31
ToByteVector
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:59
WitnessUnknown::length
unsigned int length
Definition: standard.h:183
CScript::EncodeOP_N
static opcodetype EncodeOP_N(int n)
Definition: script.h:504
OP_HASH160
@ OP_HASH160
Definition: script.h:179
CScript::DecodeOP_N
static int DecodeOP_N(opcodetype opcode)
Encode/decode small integers:
Definition: script.h:497
CKeyID
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:21
CScript::IsPayToScriptHash
bool IsPayToScriptHash() const
Definition: script.cpp:201
pubkey.h
BaseHash
Definition: standard.h:22
CPubKey::ValidSize
static bool ValidSize(const std::vector< unsigned char > &vch)
Definition: pubkey.h:75
TxoutType::WITNESS_V1_TAPROOT
@ WITNESS_V1_TAPROOT
MatchPayToPubkey
static bool MatchPayToPubkey(const CScript &script, valtype &pubkey)
Definition: standard.cpp:63
WitnessV0KeyHash
Definition: standard.h:170
CScript::IsPushOnly
bool IsPushOnly(const_iterator pc) const
Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical).
Definition: script.cpp:236
CPubKey::begin
const unsigned char * begin() const
Definition: pubkey.h:112
prevector::end
iterator end()
Definition: prevector.h:292
TxoutType::WITNESS_V0_SCRIPTHASH
@ WITNESS_V0_SCRIPTHASH
OP_RETURN
@ OP_RETURN
Definition: script.h:103
TxoutType::PUBKEY
@ PUBKEY
IsValidDestination
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:328
GetScriptForRawPubKey
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
Definition: standard.cpp:312
GetScriptForMultisig
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
Definition: standard.cpp:317
CPubKey::end
const unsigned char * end() const
Definition: pubkey.h:113
IsSmallInteger
static constexpr bool IsSmallInteger(opcodetype opcode)
Test for "small positive integer" script opcodes - OP_1 through OP_16.
Definition: standard.cpp:86
OP_DUP
@ OP_DUP
Definition: script.h:117
prevector::back
T & back()
Definition: prevector.h:453
OP_CHECKMULTISIG
@ OP_CHECKMULTISIG
Definition: script.h:184
standard.h
MatchMultisig
static bool MatchMultisig(const CScript &script, unsigned int &required, std::vector< valtype > &pubkeys)
Definition: standard.cpp:91
TxoutType::SCRIPTHASH
@ SCRIPTHASH
CPubKey::COMPRESSED_SIZE
static constexpr unsigned int COMPRESSED_SIZE
Definition: pubkey.h:38
nMaxDatacarrierBytes
unsigned nMaxDatacarrierBytes
Maximum size of TxoutType::NULL_DATA scripts that this node considers standard.
Definition: standard.cpp:17
CSHA256::Finalize
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha256.cpp:663
OP_CHECKSIG
@ OP_CHECKSIG
Definition: script.h:182
CScript
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:404
ExtractDestination
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
Definition: standard.cpp:179
CNoDestination
Definition: standard.h:134
TxoutType::NULL_DATA
@ NULL_DATA
unspendable OP_RETURN script that carries data
OP_16
@ OP_16
Definition: script.h:91
sha256.h
TxoutType::PUBKEYHASH
@ PUBKEYHASH
PKHash
Definition: standard.h:140
ToKeyID
CKeyID ToKeyID(const PKHash &key_hash)
Definition: standard.cpp:31
GetTxnOutputType
std::string GetTxnOutputType(TxoutType t)
Get the name of a TxoutType as a string.
Definition: standard.cpp:46
uint160
160-bit opaque blob.
Definition: uint256.h:113
CPubKey
An encapsulated public key.
Definition: pubkey.h:31
MAX_OP_RETURN_RELAY
static const unsigned int MAX_OP_RETURN_RELAY
Default setting for nMaxDatacarrierBytes.
Definition: standard.h:99
Hash160
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
Definition: hash.h:92
PKHash::PKHash
PKHash()
Definition: standard.h:142
prevector::data
value_type * data()
Definition: prevector.h:528
prevector::size
size_type size() const
Definition: prevector.h:282
OP_EQUAL
@ OP_EQUAL
Definition: script.h:138
prevector::begin
iterator begin()
Definition: prevector.h:290
TxoutType::MULTISIG
@ MULTISIG
CSHA256
A hasher class for SHA-256.
Definition: sha256.h:13
CTxDestination
std::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:212
WITNESS_V1_TAPROOT_SIZE
static constexpr size_t WITNESS_V1_TAPROOT_SIZE
Definition: interpreter.h:212
valtype
std::vector< unsigned char > valtype
Definition: interpreter.cpp:15
script.h
MatchPayToPubkeyHash
static bool MatchPayToPubkeyHash(const CScript &script, valtype &pubkeyhash)
Definition: standard.cpp:76
CPubKey::IsValid
bool IsValid() const
Definition: pubkey.h:184
TxoutType::WITNESS_V0_KEYHASH
@ WITNESS_V0_KEYHASH
WitnessV0ScriptHash
Definition: standard.h:163
CScriptID
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: standard.h:86
WitnessV0KeyHash::WitnessV0KeyHash
WitnessV0KeyHash()
Definition: standard.h:172
ExtractDestinations
bool ExtractDestinations(const CScript &scriptPubKey, TxoutType &typeRet, std::vector< CTxDestination > &addressRet, int &nRequiredRet)
Parse a standard scriptPubKey with one or more destination addresses.
Definition: standard.cpp:231
fAcceptDatacarrier
bool fAcceptDatacarrier
A data carrying output is an unspendable output containing data.
Definition: standard.cpp:16
CScriptID::CScriptID
CScriptID()
Definition: standard.h:89
WitnessV0ScriptHash::WitnessV0ScriptHash
WitnessV0ScriptHash()
Definition: standard.h:165
assert
assert(std::addressof(::ChainstateActive().CoinsTip())==std::addressof(coins_cache))
OP_EQUALVERIFY
@ OP_EQUALVERIFY
Definition: script.h:139
OP_1
@ OP_1
Definition: script.h:75
ScriptHash
Definition: standard.h:150
valtype
std::vector< unsigned char > valtype
Definition: standard.cpp:14
opcodetype
opcodetype
Script opcodes.
Definition: script.h:65
WitnessUnknown::program
unsigned char program[40]
Definition: standard.h:184
it
auto it
Definition: validation.cpp:399
CScript::GetOp
bool GetOp(const_iterator &pc, opcodetype &opcodeRet, std::vector< unsigned char > &vchRet) const
Definition: script.h:486
DEFAULT_ACCEPT_DATACARRIER
static const bool DEFAULT_ACCEPT_DATACARRIER
Definition: standard.h:15