1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2018 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 #include <util/system.h>
12 #include <util/strencodings.h>
13
14
15 typedef std::vector<unsigned char> valtype;
16
17 bool fAcceptDatacarrier = DEFAULT_ACCEPT_DATACARRIER;
18 unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY;
19
CScriptID(const CScript & in)20 CScriptID::CScriptID(const CScript& in) : uint160(Hash160(in.begin(), in.end())) {}
21
WitnessV0ScriptHash(const CScript & in)22 WitnessV0ScriptHash::WitnessV0ScriptHash(const CScript& in)
23 {
24 CSHA256().Write(in.data(), in.size()).Finalize(begin());
25 }
26
GetTxnOutputType(txnouttype t)27 const char* GetTxnOutputType(txnouttype t)
28 {
29 switch (t)
30 {
31 case TX_NONSTANDARD: return "nonstandard";
32 case TX_PUBKEY: return "pubkey";
33 case TX_PUBKEYHASH: return "pubkeyhash";
34 case TX_SCRIPTHASH: return "scripthash";
35 case TX_MULTISIG: return "multisig";
36 case TX_NULL_DATA: return "nulldata";
37 case TX_WITNESS_V0_KEYHASH: return "witness_v0_keyhash";
38 case TX_WITNESS_V0_SCRIPTHASH: return "witness_v0_scripthash";
39 case TX_WITNESS_UNKNOWN: return "witness_unknown";
40 }
41 return nullptr;
42 }
43
MatchPayToPubkey(const CScript & script,valtype & pubkey)44 static bool MatchPayToPubkey(const CScript& script, valtype& pubkey)
45 {
46 if (script.size() == CPubKey::PUBLIC_KEY_SIZE + 2 && script[0] == CPubKey::PUBLIC_KEY_SIZE && script.back() == OP_CHECKSIG) {
47 pubkey = valtype(script.begin() + 1, script.begin() + CPubKey::PUBLIC_KEY_SIZE + 1);
48 return CPubKey::ValidSize(pubkey);
49 }
50 if (script.size() == CPubKey::COMPRESSED_PUBLIC_KEY_SIZE + 2 && script[0] == CPubKey::COMPRESSED_PUBLIC_KEY_SIZE && script.back() == OP_CHECKSIG) {
51 pubkey = valtype(script.begin() + 1, script.begin() + CPubKey::COMPRESSED_PUBLIC_KEY_SIZE + 1);
52 return CPubKey::ValidSize(pubkey);
53 }
54 return false;
55 }
56
MatchPayToPubkeyHash(const CScript & script,valtype & pubkeyhash)57 static bool MatchPayToPubkeyHash(const CScript& script, valtype& pubkeyhash)
58 {
59 if (script.size() == 25 && script[0] == OP_DUP && script[1] == OP_HASH160 && script[2] == 20 && script[23] == OP_EQUALVERIFY && script[24] == OP_CHECKSIG) {
60 pubkeyhash = valtype(script.begin () + 3, script.begin() + 23);
61 return true;
62 }
63 return false;
64 }
65
66 /** Test for "small positive integer" script opcodes - OP_1 through OP_16. */
IsSmallInteger(opcodetype opcode)67 static constexpr bool IsSmallInteger(opcodetype opcode)
68 {
69 return opcode >= OP_1 && opcode <= OP_16;
70 }
71
MatchMultisig(const CScript & script,unsigned int & required,std::vector<valtype> & pubkeys)72 static bool MatchMultisig(const CScript& script, unsigned int& required, std::vector<valtype>& pubkeys)
73 {
74 opcodetype opcode;
75 valtype data;
76 CScript::const_iterator it = script.begin();
77 if (script.size() < 1 || script.back() != OP_CHECKMULTISIG) return false;
78
79 if (!script.GetOp(it, opcode, data) || !IsSmallInteger(opcode)) return false;
80 required = CScript::DecodeOP_N(opcode);
81 while (script.GetOp(it, opcode, data) && CPubKey::ValidSize(data)) {
82 pubkeys.emplace_back(std::move(data));
83 }
84 if (!IsSmallInteger(opcode)) return false;
85 unsigned int keys = CScript::DecodeOP_N(opcode);
86 if (pubkeys.size() != keys || keys < required) return false;
87 return (it + 1 == script.end());
88 }
89
Solver(const CScript & scriptPubKey,std::vector<std::vector<unsigned char>> & vSolutionsRet)90 txnouttype Solver(const CScript& scriptPubKey, std::vector<std::vector<unsigned char>>& vSolutionsRet)
91 {
92 vSolutionsRet.clear();
93
94 // Shortcut for pay-to-script-hash, which are more constrained than the other types:
95 // it is always OP_HASH160 20 [20 byte hash] OP_EQUAL
96 if (scriptPubKey.IsPayToScriptHash())
97 {
98 std::vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22);
99 vSolutionsRet.push_back(hashBytes);
100 return TX_SCRIPTHASH;
101 }
102
103 int witnessversion;
104 std::vector<unsigned char> witnessprogram;
105 if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
106 if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_KEYHASH_SIZE) {
107 vSolutionsRet.push_back(witnessprogram);
108 return TX_WITNESS_V0_KEYHASH;
109 }
110 if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_SCRIPTHASH_SIZE) {
111 vSolutionsRet.push_back(witnessprogram);
112 return TX_WITNESS_V0_SCRIPTHASH;
113 }
114 if (witnessversion != 0) {
115 vSolutionsRet.push_back(std::vector<unsigned char>{(unsigned char)witnessversion});
116 vSolutionsRet.push_back(std::move(witnessprogram));
117 return TX_WITNESS_UNKNOWN;
118 }
119 return TX_NONSTANDARD;
120 }
121
122 // Provably prunable, data-carrying output
123 //
124 // So long as script passes the IsUnspendable() test and all but the first
125 // byte passes the IsPushOnly() test we don't care what exactly is in the
126 // script.
127 if (scriptPubKey.size() >= 1 && scriptPubKey[0] == OP_RETURN && scriptPubKey.IsPushOnly(scriptPubKey.begin()+1)) {
128 return TX_NULL_DATA;
129 }
130
131 std::vector<unsigned char> data;
132 if (MatchPayToPubkey(scriptPubKey, data)) {
133 vSolutionsRet.push_back(std::move(data));
134 return TX_PUBKEY;
135 }
136
137 if (MatchPayToPubkeyHash(scriptPubKey, data)) {
138 vSolutionsRet.push_back(std::move(data));
139 return TX_PUBKEYHASH;
140 }
141
142 unsigned int required;
143 std::vector<std::vector<unsigned char>> keys;
144 if (MatchMultisig(scriptPubKey, required, keys)) {
145 vSolutionsRet.push_back({static_cast<unsigned char>(required)}); // safe as required is in range 1..16
146 vSolutionsRet.insert(vSolutionsRet.end(), keys.begin(), keys.end());
147 vSolutionsRet.push_back({static_cast<unsigned char>(keys.size())}); // safe as size is in range 1..16
148 return TX_MULTISIG;
149 }
150
151 vSolutionsRet.clear();
152 return TX_NONSTANDARD;
153 }
154
ExtractDestination(const CScript & scriptPubKey,CTxDestination & addressRet)155 bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
156 {
157 std::vector<valtype> vSolutions;
158 txnouttype whichType = Solver(scriptPubKey, vSolutions);
159
160 if (whichType == TX_PUBKEY) {
161 CPubKey pubKey(vSolutions[0]);
162 if (!pubKey.IsValid())
163 return false;
164
165 addressRet = pubKey.GetID();
166 return true;
167 }
168 else if (whichType == TX_PUBKEYHASH)
169 {
170 addressRet = CKeyID(uint160(vSolutions[0]));
171 return true;
172 }
173 else if (whichType == TX_SCRIPTHASH)
174 {
175 addressRet = CScriptID(uint160(vSolutions[0]));
176 return true;
177 } else if (whichType == TX_WITNESS_V0_KEYHASH) {
178 WitnessV0KeyHash hash;
179 std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
180 addressRet = hash;
181 return true;
182 } else if (whichType == TX_WITNESS_V0_SCRIPTHASH) {
183 WitnessV0ScriptHash hash;
184 std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
185 addressRet = hash;
186 return true;
187 } else if (whichType == TX_WITNESS_UNKNOWN) {
188 WitnessUnknown unk;
189 unk.version = vSolutions[0][0];
190 std::copy(vSolutions[1].begin(), vSolutions[1].end(), unk.program);
191 unk.length = vSolutions[1].size();
192 addressRet = unk;
193 return true;
194 }
195 // Multisig txns have more than one address...
196 return false;
197 }
198
ExtractDestinations(const CScript & scriptPubKey,txnouttype & typeRet,std::vector<CTxDestination> & addressRet,int & nRequiredRet)199 bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet)
200 {
201 addressRet.clear();
202 std::vector<valtype> vSolutions;
203 typeRet = Solver(scriptPubKey, vSolutions);
204 if (typeRet == TX_NONSTANDARD) {
205 return false;
206 } else if (typeRet == TX_NULL_DATA) {
207 // This is data, not addresses
208 return false;
209 }
210
211 if (typeRet == TX_MULTISIG)
212 {
213 nRequiredRet = vSolutions.front()[0];
214 for (unsigned int i = 1; i < vSolutions.size()-1; i++)
215 {
216 CPubKey pubKey(vSolutions[i]);
217 if (!pubKey.IsValid())
218 continue;
219
220 CTxDestination address = pubKey.GetID();
221 addressRet.push_back(address);
222 }
223
224 if (addressRet.empty())
225 return false;
226 }
227 else
228 {
229 nRequiredRet = 1;
230 CTxDestination address;
231 if (!ExtractDestination(scriptPubKey, address))
232 return false;
233 addressRet.push_back(address);
234 }
235
236 return true;
237 }
238
239 namespace
240 {
241 class CScriptVisitor : public boost::static_visitor<bool>
242 {
243 private:
244 CScript *script;
245 public:
CScriptVisitor(CScript * scriptin)246 explicit CScriptVisitor(CScript *scriptin) { script = scriptin; }
247
operator ()(const CNoDestination & dest) const248 bool operator()(const CNoDestination &dest) const {
249 script->clear();
250 return false;
251 }
252
operator ()(const CKeyID & keyID) const253 bool operator()(const CKeyID &keyID) const {
254 script->clear();
255 *script << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
256 return true;
257 }
258
operator ()(const CScriptID & scriptID) const259 bool operator()(const CScriptID &scriptID) const {
260 script->clear();
261 *script << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
262 return true;
263 }
264
operator ()(const WitnessV0KeyHash & id) const265 bool operator()(const WitnessV0KeyHash& id) const
266 {
267 script->clear();
268 *script << OP_0 << ToByteVector(id);
269 return true;
270 }
271
operator ()(const WitnessV0ScriptHash & id) const272 bool operator()(const WitnessV0ScriptHash& id) const
273 {
274 script->clear();
275 *script << OP_0 << ToByteVector(id);
276 return true;
277 }
278
operator ()(const WitnessUnknown & id) const279 bool operator()(const WitnessUnknown& id) const
280 {
281 script->clear();
282 *script << CScript::EncodeOP_N(id.version) << std::vector<unsigned char>(id.program, id.program + id.length);
283 return true;
284 }
285 };
286 } // namespace
287
GetScriptForDestination(const CTxDestination & dest)288 CScript GetScriptForDestination(const CTxDestination& dest)
289 {
290 CScript script;
291
292 boost::apply_visitor(CScriptVisitor(&script), dest);
293 return script;
294 }
295
GetScriptForRawPubKey(const CPubKey & pubKey)296 CScript GetScriptForRawPubKey(const CPubKey& pubKey)
297 {
298 return CScript() << std::vector<unsigned char>(pubKey.begin(), pubKey.end()) << OP_CHECKSIG;
299 }
300
GetScriptForMultisig(int nRequired,const std::vector<CPubKey> & keys)301 CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys)
302 {
303 CScript script;
304
305 script << CScript::EncodeOP_N(nRequired);
306 for (const CPubKey& key : keys)
307 script << ToByteVector(key);
308 script << CScript::EncodeOP_N(keys.size()) << OP_CHECKMULTISIG;
309 return script;
310 }
311
GetScriptForWitness(const CScript & redeemscript)312 CScript GetScriptForWitness(const CScript& redeemscript)
313 {
314 std::vector<std::vector<unsigned char> > vSolutions;
315 txnouttype typ = Solver(redeemscript, vSolutions);
316 if (typ == TX_PUBKEY) {
317 return GetScriptForDestination(WitnessV0KeyHash(Hash160(vSolutions[0].begin(), vSolutions[0].end())));
318 } else if (typ == TX_PUBKEYHASH) {
319 return GetScriptForDestination(WitnessV0KeyHash(vSolutions[0]));
320 }
321 return GetScriptForDestination(WitnessV0ScriptHash(redeemscript));
322 }
323
IsValidDestination(const CTxDestination & dest)324 bool IsValidDestination(const CTxDestination& dest) {
325 return dest.which() != 0;
326 }
327