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 UniValue
ValueFromAmount(const CAmount
& amount
)
21 bool sign
= amount
< 0;
22 int64_t n_abs
= (sign
? -amount
: amount
);
23 int64_t quotient
= n_abs
/ COIN
;
24 int64_t remainder
= n_abs
% COIN
;
25 return UniValue(UniValue::VNUM
,
26 strprintf("%s%d.%08d", sign
? "-" : "", quotient
, remainder
));
29 std::string
FormatScript(const CScript
& script
)
32 CScript::const_iterator it
= script
.begin();
34 while (it
!= script
.end()) {
35 CScript::const_iterator it2
= it
;
36 std::vector
<unsigned char> vch
;
37 if (script
.GetOp2(it
, op
, &vch
)) {
41 } else if ((op
>= OP_1
&& op
<= OP_16
) || op
== OP_1NEGATE
) {
42 ret
+= strprintf("%i ", op
- OP_1NEGATE
- 1);
44 } else if (op
>= OP_NOP
&& op
<= OP_NOP10
) {
45 std::string
str(GetOpName(op
));
46 if (str
.substr(0, 3) == std::string("OP_")) {
47 ret
+= str
.substr(3, std::string::npos
) + " ";
52 ret
+= strprintf("0x%x 0x%x ", HexStr(it2
, it
- vch
.size()), HexStr(it
- vch
.size(), it
));
54 ret
+= strprintf("0x%x ", HexStr(it2
, it
));
58 ret
+= strprintf("0x%x ", HexStr(it2
, script
.end()));
61 return ret
.substr(0, ret
.size() - 1);
64 const std::map
<unsigned char, std::string
> mapSigHashTypes
= {
65 {static_cast<unsigned char>(SIGHASH_ALL
), std::string("ALL")},
66 {static_cast<unsigned char>(SIGHASH_ALL
|SIGHASH_ANYONECANPAY
), std::string("ALL|ANYONECANPAY")},
67 {static_cast<unsigned char>(SIGHASH_NONE
), std::string("NONE")},
68 {static_cast<unsigned char>(SIGHASH_NONE
|SIGHASH_ANYONECANPAY
), std::string("NONE|ANYONECANPAY")},
69 {static_cast<unsigned char>(SIGHASH_SINGLE
), std::string("SINGLE")},
70 {static_cast<unsigned char>(SIGHASH_SINGLE
|SIGHASH_ANYONECANPAY
), std::string("SINGLE|ANYONECANPAY")},
74 * Create the assembly string representation of a CScript object.
75 * @param[in] script CScript object to convert into the asm string representation.
76 * @param[in] fAttemptSighashDecode Whether to attempt to decode sighash types on data within the script that matches the format
77 * of a signature. Only pass true for scripts you believe could contain signatures. For example,
78 * pass false, or omit the this argument (defaults to false), for scriptPubKeys.
80 std::string
ScriptToAsmStr(const CScript
& script
, const bool fAttemptSighashDecode
)
84 std::vector
<unsigned char> vch
;
85 CScript::const_iterator pc
= script
.begin();
86 while (pc
< script
.end()) {
90 if (!script
.GetOp(pc
, opcode
, vch
)) {
94 if (0 <= opcode
&& opcode
<= OP_PUSHDATA4
) {
95 if (vch
.size() <= static_cast<std::vector
<unsigned char>::size_type
>(4)) {
96 str
+= strprintf("%d", CScriptNum(vch
, false).getint());
98 // the IsUnspendable check makes sure not to try to decode OP_RETURN data that may match the format of a signature
99 if (fAttemptSighashDecode
&& !script
.IsUnspendable()) {
100 std::string strSigHashDecode
;
101 // goal: only attempt to decode a defined sighash type from data that looks like a signature within a scriptSig.
102 // this won't decode correctly formatted public keys in Pubkey or Multisig scripts due to
103 // the restrictions on the pubkey formats (see IsCompressedOrUncompressedPubKey) being incongruous with the
104 // checks in CheckSignatureEncoding.
105 if (CheckSignatureEncoding(vch
, SCRIPT_VERIFY_STRICTENC
, nullptr)) {
106 const unsigned char chSigHashType
= vch
.back();
107 if (mapSigHashTypes
.count(chSigHashType
)) {
108 strSigHashDecode
= "[" + mapSigHashTypes
.find(chSigHashType
)->second
+ "]";
109 vch
.pop_back(); // remove the sighash type byte. it will be replaced by the decode.
112 str
+= HexStr(vch
) + strSigHashDecode
;
118 str
+= GetOpName(opcode
);
124 std::string
EncodeHexTx(const CTransaction
& tx
, const int serializeFlags
)
126 CDataStream
ssTx(SER_NETWORK
, PROTOCOL_VERSION
| serializeFlags
);
128 return HexStr(ssTx
.begin(), ssTx
.end());
131 void ScriptPubKeyToUniv(const CScript
& scriptPubKey
,
132 UniValue
& out
, bool fIncludeHex
)
135 std::vector
<CTxDestination
> addresses
;
138 out
.pushKV("asm", ScriptToAsmStr(scriptPubKey
));
140 out
.pushKV("hex", HexStr(scriptPubKey
.begin(), scriptPubKey
.end()));
142 if (!ExtractDestinations(scriptPubKey
, type
, addresses
, nRequired
)) {
143 out
.pushKV("type", GetTxnOutputType(type
));
147 out
.pushKV("reqSigs", nRequired
);
148 out
.pushKV("type", GetTxnOutputType(type
));
150 UniValue
a(UniValue::VARR
);
151 for (const CTxDestination
& addr
: addresses
)
152 a
.push_back(CBitcoinAddress(addr
).ToString());
153 out
.pushKV("addresses", a
);
156 void TxToUniv(const CTransaction
& tx
, const uint256
& hashBlock
, UniValue
& entry
, bool include_hex
, int serialize_flags
)
158 entry
.pushKV("txid", tx
.GetHash().GetHex());
159 entry
.pushKV("hash", tx
.GetWitnessHash().GetHex());
160 entry
.pushKV("version", tx
.nVersion
);
161 entry
.pushKV("size", (int)::GetSerializeSize(tx
, SER_NETWORK
, PROTOCOL_VERSION
));
162 entry
.pushKV("vsize", (GetTransactionWeight(tx
) + WITNESS_SCALE_FACTOR
- 1) / WITNESS_SCALE_FACTOR
);
163 entry
.pushKV("locktime", (int64_t)tx
.nLockTime
);
165 UniValue
vin(UniValue::VARR
);
166 for (unsigned int i
= 0; i
< tx
.vin
.size(); i
++) {
167 const CTxIn
& txin
= tx
.vin
[i
];
168 UniValue
in(UniValue::VOBJ
);
170 in
.pushKV("coinbase", HexStr(txin
.scriptSig
.begin(), txin
.scriptSig
.end()));
172 in
.pushKV("txid", txin
.prevout
.hash
.GetHex());
173 in
.pushKV("vout", (int64_t)txin
.prevout
.n
);
174 UniValue
o(UniValue::VOBJ
);
175 o
.pushKV("asm", ScriptToAsmStr(txin
.scriptSig
, true));
176 o
.pushKV("hex", HexStr(txin
.scriptSig
.begin(), txin
.scriptSig
.end()));
177 in
.pushKV("scriptSig", o
);
178 if (!tx
.vin
[i
].scriptWitness
.IsNull()) {
179 UniValue
txinwitness(UniValue::VARR
);
180 for (const auto& item
: tx
.vin
[i
].scriptWitness
.stack
) {
181 txinwitness
.push_back(HexStr(item
.begin(), item
.end()));
183 in
.pushKV("txinwitness", txinwitness
);
186 in
.pushKV("sequence", (int64_t)txin
.nSequence
);
189 entry
.pushKV("vin", vin
);
191 UniValue
vout(UniValue::VARR
);
192 for (unsigned int i
= 0; i
< tx
.vout
.size(); i
++) {
193 const CTxOut
& txout
= tx
.vout
[i
];
195 UniValue
out(UniValue::VOBJ
);
197 out
.pushKV("value", ValueFromAmount(txout
.nValue
));
198 out
.pushKV("n", (int64_t)i
);
200 UniValue
o(UniValue::VOBJ
);
201 ScriptPubKeyToUniv(txout
.scriptPubKey
, o
, true);
202 out
.pushKV("scriptPubKey", o
);
205 entry
.pushKV("vout", vout
);
207 if (!hashBlock
.IsNull())
208 entry
.pushKV("blockhash", hashBlock
.GetHex());
211 entry
.pushKV("hex", EncodeHexTx(tx
, serialize_flags
)); // the hex-encoded transaction. used the name "hex" to be consistent with the verbose output of "getrawtransaction".