1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 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.
6 #include <script/standard.h>
9 #include <script/script.h>
11 #include <utilstrencodings.h>
14 typedef std::vector
<unsigned char> valtype
;
16 bool fAcceptDatacarrier
= DEFAULT_ACCEPT_DATACARRIER
;
17 unsigned nMaxDatacarrierBytes
= MAX_OP_RETURN_RELAY
;
19 CScriptID::CScriptID(const CScript
& in
) : uint160(Hash160(in
.begin(), in
.end())) {}
21 const char* GetTxnOutputType(txnouttype t
)
25 case TX_NONSTANDARD
: return "nonstandard";
26 case TX_PUBKEY
: return "pubkey";
27 case TX_PUBKEYHASH
: return "pubkeyhash";
28 case TX_SCRIPTHASH
: return "scripthash";
29 case TX_MULTISIG
: return "multisig";
30 case TX_NULL_DATA
: return "nulldata";
31 case TX_WITNESS_V0_KEYHASH
: return "witness_v0_keyhash";
32 case TX_WITNESS_V0_SCRIPTHASH
: return "witness_v0_scripthash";
33 case TX_WITNESS_UNKNOWN
: return "witness_unknown";
38 bool Solver(const CScript
& scriptPubKey
, txnouttype
& typeRet
, std::vector
<std::vector
<unsigned char> >& vSolutionsRet
)
41 static std::multimap
<txnouttype
, CScript
> mTemplates
;
42 if (mTemplates
.empty())
44 // Standard tx, sender provides pubkey, receiver adds signature
45 mTemplates
.insert(std::make_pair(TX_PUBKEY
, CScript() << OP_PUBKEY
<< OP_CHECKSIG
));
47 // Bitcoin address tx, sender provides hash of pubkey, receiver provides signature and pubkey
48 mTemplates
.insert(std::make_pair(TX_PUBKEYHASH
, CScript() << OP_DUP
<< OP_HASH160
<< OP_PUBKEYHASH
<< OP_EQUALVERIFY
<< OP_CHECKSIG
));
50 // Sender provides N pubkeys, receivers provides M signatures
51 mTemplates
.insert(std::make_pair(TX_MULTISIG
, CScript() << OP_SMALLINTEGER
<< OP_PUBKEYS
<< OP_SMALLINTEGER
<< OP_CHECKMULTISIG
));
54 vSolutionsRet
.clear();
56 // Shortcut for pay-to-script-hash, which are more constrained than the other types:
57 // it is always OP_HASH160 20 [20 byte hash] OP_EQUAL
58 if (scriptPubKey
.IsPayToScriptHash())
60 typeRet
= TX_SCRIPTHASH
;
61 std::vector
<unsigned char> hashBytes(scriptPubKey
.begin()+2, scriptPubKey
.begin()+22);
62 vSolutionsRet
.push_back(hashBytes
);
67 std::vector
<unsigned char> witnessprogram
;
68 if (scriptPubKey
.IsWitnessProgram(witnessversion
, witnessprogram
)) {
69 if (witnessversion
== 0 && witnessprogram
.size() == 20) {
70 typeRet
= TX_WITNESS_V0_KEYHASH
;
71 vSolutionsRet
.push_back(witnessprogram
);
74 if (witnessversion
== 0 && witnessprogram
.size() == 32) {
75 typeRet
= TX_WITNESS_V0_SCRIPTHASH
;
76 vSolutionsRet
.push_back(witnessprogram
);
79 if (witnessversion
!= 0) {
80 typeRet
= TX_WITNESS_UNKNOWN
;
81 vSolutionsRet
.push_back(std::vector
<unsigned char>{(unsigned char)witnessversion
});
82 vSolutionsRet
.push_back(std::move(witnessprogram
));
88 // Provably prunable, data-carrying output
90 // So long as script passes the IsUnspendable() test and all but the first
91 // byte passes the IsPushOnly() test we don't care what exactly is in the
93 if (scriptPubKey
.size() >= 1 && scriptPubKey
[0] == OP_RETURN
&& scriptPubKey
.IsPushOnly(scriptPubKey
.begin()+1)) {
94 typeRet
= TX_NULL_DATA
;
99 const CScript
& script1
= scriptPubKey
;
100 for (const std::pair
<txnouttype
, CScript
>& tplate
: mTemplates
)
102 const CScript
& script2
= tplate
.second
;
103 vSolutionsRet
.clear();
105 opcodetype opcode1
, opcode2
;
106 std::vector
<unsigned char> vch1
, vch2
;
109 CScript::const_iterator pc1
= script1
.begin();
110 CScript::const_iterator pc2
= script2
.begin();
113 if (pc1
== script1
.end() && pc2
== script2
.end())
116 typeRet
= tplate
.first
;
117 if (typeRet
== TX_MULTISIG
)
119 // Additional checks for TX_MULTISIG:
120 unsigned char m
= vSolutionsRet
.front()[0];
121 unsigned char n
= vSolutionsRet
.back()[0];
122 if (m
< 1 || n
< 1 || m
> n
|| vSolutionsRet
.size()-2 != n
)
127 if (!script1
.GetOp(pc1
, opcode1
, vch1
))
129 if (!script2
.GetOp(pc2
, opcode2
, vch2
))
132 // Template matching opcodes:
133 if (opcode2
== OP_PUBKEYS
)
135 while (vch1
.size() >= 33 && vch1
.size() <= 65)
137 vSolutionsRet
.push_back(vch1
);
138 if (!script1
.GetOp(pc1
, opcode1
, vch1
))
141 if (!script2
.GetOp(pc2
, opcode2
, vch2
))
143 // Normal situation is to fall through
144 // to other if/else statements
147 if (opcode2
== OP_PUBKEY
)
149 if (vch1
.size() < 33 || vch1
.size() > 65)
151 vSolutionsRet
.push_back(vch1
);
153 else if (opcode2
== OP_PUBKEYHASH
)
155 if (vch1
.size() != sizeof(uint160
))
157 vSolutionsRet
.push_back(vch1
);
159 else if (opcode2
== OP_SMALLINTEGER
)
160 { // Single-byte small integer pushed onto vSolutions
161 if (opcode1
== OP_0
||
162 (opcode1
>= OP_1
&& opcode1
<= OP_16
))
164 char n
= (char)CScript::DecodeOP_N(opcode1
);
165 vSolutionsRet
.push_back(valtype(1, n
));
170 else if (opcode1
!= opcode2
|| vch1
!= vch2
)
172 // Others must match exactly
178 vSolutionsRet
.clear();
179 typeRet
= TX_NONSTANDARD
;
183 bool ExtractDestination(const CScript
& scriptPubKey
, CTxDestination
& addressRet
)
185 std::vector
<valtype
> vSolutions
;
186 txnouttype whichType
;
187 if (!Solver(scriptPubKey
, whichType
, vSolutions
))
190 if (whichType
== TX_PUBKEY
)
192 CPubKey
pubKey(vSolutions
[0]);
193 if (!pubKey
.IsValid())
196 addressRet
= pubKey
.GetID();
199 else if (whichType
== TX_PUBKEYHASH
)
201 addressRet
= CKeyID(uint160(vSolutions
[0]));
204 else if (whichType
== TX_SCRIPTHASH
)
206 addressRet
= CScriptID(uint160(vSolutions
[0]));
208 } else if (whichType
== TX_WITNESS_V0_KEYHASH
) {
209 WitnessV0KeyHash hash
;
210 std::copy(vSolutions
[0].begin(), vSolutions
[0].end(), hash
.begin());
213 } else if (whichType
== TX_WITNESS_V0_SCRIPTHASH
) {
214 WitnessV0ScriptHash hash
;
215 std::copy(vSolutions
[0].begin(), vSolutions
[0].end(), hash
.begin());
218 } else if (whichType
== TX_WITNESS_UNKNOWN
) {
220 unk
.version
= vSolutions
[0][0];
221 std::copy(vSolutions
[1].begin(), vSolutions
[1].end(), unk
.program
);
222 unk
.length
= vSolutions
[1].size();
226 // Multisig txns have more than one address...
230 bool ExtractDestinations(const CScript
& scriptPubKey
, txnouttype
& typeRet
, std::vector
<CTxDestination
>& addressRet
, int& nRequiredRet
)
233 typeRet
= TX_NONSTANDARD
;
234 std::vector
<valtype
> vSolutions
;
235 if (!Solver(scriptPubKey
, typeRet
, vSolutions
))
237 if (typeRet
== TX_NULL_DATA
){
238 // This is data, not addresses
242 if (typeRet
== TX_MULTISIG
)
244 nRequiredRet
= vSolutions
.front()[0];
245 for (unsigned int i
= 1; i
< vSolutions
.size()-1; i
++)
247 CPubKey
pubKey(vSolutions
[i
]);
248 if (!pubKey
.IsValid())
251 CTxDestination address
= pubKey
.GetID();
252 addressRet
.push_back(address
);
255 if (addressRet
.empty())
261 CTxDestination address
;
262 if (!ExtractDestination(scriptPubKey
, address
))
264 addressRet
.push_back(address
);
272 class CScriptVisitor
: public boost::static_visitor
<bool>
277 explicit CScriptVisitor(CScript
*scriptin
) { script
= scriptin
; }
279 bool operator()(const CNoDestination
&dest
) const {
284 bool operator()(const CKeyID
&keyID
) const {
286 *script
<< OP_DUP
<< OP_HASH160
<< ToByteVector(keyID
) << OP_EQUALVERIFY
<< OP_CHECKSIG
;
290 bool operator()(const CScriptID
&scriptID
) const {
292 *script
<< OP_HASH160
<< ToByteVector(scriptID
) << OP_EQUAL
;
296 bool operator()(const WitnessV0KeyHash
& id
) const
299 *script
<< OP_0
<< ToByteVector(id
);
303 bool operator()(const WitnessV0ScriptHash
& id
) const
306 *script
<< OP_0
<< ToByteVector(id
);
310 bool operator()(const WitnessUnknown
& id
) const
313 *script
<< CScript::EncodeOP_N(id
.version
) << std::vector
<unsigned char>(id
.program
, id
.program
+ id
.length
);
319 CScript
GetScriptForDestination(const CTxDestination
& dest
)
323 boost::apply_visitor(CScriptVisitor(&script
), dest
);
327 CScript
GetScriptForRawPubKey(const CPubKey
& pubKey
)
329 return CScript() << std::vector
<unsigned char>(pubKey
.begin(), pubKey
.end()) << OP_CHECKSIG
;
332 CScript
GetScriptForMultisig(int nRequired
, const std::vector
<CPubKey
>& keys
)
336 script
<< CScript::EncodeOP_N(nRequired
);
337 for (const CPubKey
& key
: keys
)
338 script
<< ToByteVector(key
);
339 script
<< CScript::EncodeOP_N(keys
.size()) << OP_CHECKMULTISIG
;
343 CScript
GetScriptForWitness(const CScript
& redeemscript
)
348 std::vector
<std::vector
<unsigned char> > vSolutions
;
349 if (Solver(redeemscript
, typ
, vSolutions
)) {
350 if (typ
== TX_PUBKEY
) {
351 unsigned char h160
[20];
352 CHash160().Write(&vSolutions
[0][0], vSolutions
[0].size()).Finalize(h160
);
353 ret
<< OP_0
<< std::vector
<unsigned char>(&h160
[0], &h160
[20]);
355 } else if (typ
== TX_PUBKEYHASH
) {
356 ret
<< OP_0
<< vSolutions
[0];
361 CSHA256().Write(&redeemscript
[0], redeemscript
.size()).Finalize(hash
.begin());
362 ret
<< OP_0
<< ToByteVector(hash
);
366 bool IsValidDestination(const CTxDestination
& dest
) {
367 return dest
.which() != 0;