1 // Copyright (c) 2009-2016 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
8 #include "consensus/consensus.h"
9 #include "consensus/validation.h"
10 #include "script/script.h"
11 #include "script/standard.h"
12 #include "serialize.h"
16 #include "utilmoneystr.h"
17 #include "utilstrencodings.h"
19 std::string
FormatScript(const CScript
& script
)
22 CScript::const_iterator it
= script
.begin();
24 while (it
!= script
.end()) {
25 CScript::const_iterator it2
= it
;
26 std::vector
<unsigned char> vch
;
27 if (script
.GetOp2(it
, op
, &vch
)) {
31 } else if ((op
>= OP_1
&& op
<= OP_16
) || op
== OP_1NEGATE
) {
32 ret
+= strprintf("%i ", op
- OP_1NEGATE
- 1);
34 } else if (op
>= OP_NOP
&& op
<= OP_NOP10
) {
35 std::string
str(GetOpName(op
));
36 if (str
.substr(0, 3) == std::string("OP_")) {
37 ret
+= str
.substr(3, std::string::npos
) + " ";
42 ret
+= strprintf("0x%x 0x%x ", HexStr(it2
, it
- vch
.size()), HexStr(it
- vch
.size(), it
));
44 ret
+= strprintf("0x%x ", HexStr(it2
, it
));
48 ret
+= strprintf("0x%x ", HexStr(it2
, script
.end()));
51 return ret
.substr(0, ret
.size() - 1);
54 const std::map
<unsigned char, std::string
> mapSigHashTypes
= {
55 {static_cast<unsigned char>(SIGHASH_ALL
), std::string("ALL")},
56 {static_cast<unsigned char>(SIGHASH_ALL
|SIGHASH_ANYONECANPAY
), std::string("ALL|ANYONECANPAY")},
57 {static_cast<unsigned char>(SIGHASH_NONE
), std::string("NONE")},
58 {static_cast<unsigned char>(SIGHASH_NONE
|SIGHASH_ANYONECANPAY
), std::string("NONE|ANYONECANPAY")},
59 {static_cast<unsigned char>(SIGHASH_SINGLE
), std::string("SINGLE")},
60 {static_cast<unsigned char>(SIGHASH_SINGLE
|SIGHASH_ANYONECANPAY
), std::string("SINGLE|ANYONECANPAY")},
64 * Create the assembly string representation of a CScript object.
65 * @param[in] script CScript object to convert into the asm string representation.
66 * @param[in] fAttemptSighashDecode Whether to attempt to decode sighash types on data within the script that matches the format
67 * of a signature. Only pass true for scripts you believe could contain signatures. For example,
68 * pass false, or omit the this argument (defaults to false), for scriptPubKeys.
70 std::string
ScriptToAsmStr(const CScript
& script
, const bool fAttemptSighashDecode
)
74 std::vector
<unsigned char> vch
;
75 CScript::const_iterator pc
= script
.begin();
76 while (pc
< script
.end()) {
80 if (!script
.GetOp(pc
, opcode
, vch
)) {
84 if (0 <= opcode
&& opcode
<= OP_PUSHDATA4
) {
85 if (vch
.size() <= static_cast<std::vector
<unsigned char>::size_type
>(4)) {
86 str
+= strprintf("%d", CScriptNum(vch
, false).getint());
88 // the IsUnspendable check makes sure not to try to decode OP_RETURN data that may match the format of a signature
89 if (fAttemptSighashDecode
&& !script
.IsUnspendable()) {
90 std::string strSigHashDecode
;
91 // goal: only attempt to decode a defined sighash type from data that looks like a signature within a scriptSig.
92 // this won't decode correctly formatted public keys in Pubkey or Multisig scripts due to
93 // the restrictions on the pubkey formats (see IsCompressedOrUncompressedPubKey) being incongruous with the
94 // checks in CheckSignatureEncoding.
95 if (CheckSignatureEncoding(vch
, SCRIPT_VERIFY_STRICTENC
, NULL
)) {
96 const unsigned char chSigHashType
= vch
.back();
97 if (mapSigHashTypes
.count(chSigHashType
)) {
98 strSigHashDecode
= "[" + mapSigHashTypes
.find(chSigHashType
)->second
+ "]";
99 vch
.pop_back(); // remove the sighash type byte. it will be replaced by the decode.
102 str
+= HexStr(vch
) + strSigHashDecode
;
108 str
+= GetOpName(opcode
);
114 std::string
EncodeHexTx(const CTransaction
& tx
, const int serializeFlags
)
116 CDataStream
ssTx(SER_NETWORK
, PROTOCOL_VERSION
| serializeFlags
);
118 return HexStr(ssTx
.begin(), ssTx
.end());
121 void ScriptPubKeyToUniv(const CScript
& scriptPubKey
,
122 UniValue
& out
, bool fIncludeHex
)
125 std::vector
<CTxDestination
> addresses
;
128 out
.pushKV("asm", ScriptToAsmStr(scriptPubKey
));
130 out
.pushKV("hex", HexStr(scriptPubKey
.begin(), scriptPubKey
.end()));
132 if (!ExtractDestinations(scriptPubKey
, type
, addresses
, nRequired
)) {
133 out
.pushKV("type", GetTxnOutputType(type
));
137 out
.pushKV("reqSigs", nRequired
);
138 out
.pushKV("type", GetTxnOutputType(type
));
140 UniValue
a(UniValue::VARR
);
141 for (const CTxDestination
& addr
: addresses
)
142 a
.push_back(CBitcoinAddress(addr
).ToString());
143 out
.pushKV("addresses", a
);
146 void TxToUniv(const CTransaction
& tx
, const uint256
& hashBlock
, UniValue
& entry
)
148 entry
.pushKV("txid", tx
.GetHash().GetHex());
149 entry
.pushKV("hash", tx
.GetWitnessHash().GetHex());
150 entry
.pushKV("version", tx
.nVersion
);
151 entry
.pushKV("size", (int)::GetSerializeSize(tx
, SER_NETWORK
, PROTOCOL_VERSION
));
152 entry
.pushKV("vsize", (GetTransactionWeight(tx
) + WITNESS_SCALE_FACTOR
- 1) / WITNESS_SCALE_FACTOR
);
153 entry
.pushKV("locktime", (int64_t)tx
.nLockTime
);
155 UniValue
vin(UniValue::VARR
);
156 for (unsigned int i
= 0; i
< tx
.vin
.size(); i
++) {
157 const CTxIn
& txin
= tx
.vin
[i
];
158 UniValue
in(UniValue::VOBJ
);
160 in
.pushKV("coinbase", HexStr(txin
.scriptSig
.begin(), txin
.scriptSig
.end()));
162 in
.pushKV("txid", txin
.prevout
.hash
.GetHex());
163 in
.pushKV("vout", (int64_t)txin
.prevout
.n
);
164 UniValue
o(UniValue::VOBJ
);
165 o
.pushKV("asm", ScriptToAsmStr(txin
.scriptSig
, true));
166 o
.pushKV("hex", HexStr(txin
.scriptSig
.begin(), txin
.scriptSig
.end()));
167 in
.pushKV("scriptSig", o
);
168 if (!tx
.vin
[i
].scriptWitness
.IsNull()) {
169 UniValue
txinwitness(UniValue::VARR
);
170 for (const auto& item
: tx
.vin
[i
].scriptWitness
.stack
) {
171 txinwitness
.push_back(HexStr(item
.begin(), item
.end()));
173 in
.pushKV("txinwitness", txinwitness
);
176 in
.pushKV("sequence", (int64_t)txin
.nSequence
);
179 entry
.pushKV("vin", vin
);
181 UniValue
vout(UniValue::VARR
);
182 for (unsigned int i
= 0; i
< tx
.vout
.size(); i
++) {
183 const CTxOut
& txout
= tx
.vout
[i
];
185 UniValue
out(UniValue::VOBJ
);
187 UniValue
outValue(UniValue::VNUM
, FormatMoney(txout
.nValue
));
188 out
.pushKV("value", outValue
);
189 out
.pushKV("n", (int64_t)i
);
191 UniValue
o(UniValue::VOBJ
);
192 ScriptPubKeyToUniv(txout
.scriptPubKey
, o
, true);
193 out
.pushKV("scriptPubKey", o
);
196 entry
.pushKV("vout", vout
);
198 if (!hashBlock
.IsNull())
199 entry
.pushKV("blockhash", hashBlock
.GetHex());
201 entry
.pushKV("hex", EncodeHexTx(tx
)); // the hex-encoded transaction. used the name "hex" to be consistent with the verbose output of "getrawtransaction".