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