Bitcoin ABC  0.22.12
P2P Digital Currency
core_write.cpp
Go to the documentation of this file.
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.
4 
5 #include <core_io.h>
6 
7 #include <config.h>
8 #include <key_io.h>
10 #include <script/script.h>
11 #include <script/sigencoding.h>
12 #include <script/standard.h>
13 #include <serialize.h>
14 #include <streams.h>
15 #include <util/strencodings.h>
16 #include <util/system.h>
17 
18 #include <univalue.h>
19 
21  bool sign = amount < Amount::zero();
22  Amount n_abs(sign ? -amount : amount);
23  int64_t quotient = n_abs / COIN;
24  int64_t remainder = (n_abs % COIN) / SATOSHI;
25  return UniValue(UniValue::VNUM, strprintf("%s%d.%08d", sign ? "-" : "",
26  quotient, remainder));
27 }
28 
29 std::string FormatScript(const CScript &script) {
30  std::string ret;
31  CScript::const_iterator it = script.begin();
32  opcodetype op;
33  while (it != script.end()) {
34  CScript::const_iterator it2 = it;
35  std::vector<uint8_t> vch;
36  if (script.GetOp(it, op, vch)) {
37  if (op == OP_0) {
38  ret += "0 ";
39  continue;
40  }
41 
42  if ((op >= OP_1 && op <= OP_16) || op == OP_1NEGATE) {
43  ret += strprintf("%i ", op - OP_1NEGATE - 1);
44  continue;
45  }
46 
47  if (op >= OP_NOP && op < FIRST_UNDEFINED_OP_VALUE) {
48  std::string str(GetOpName(op));
49  if (str.substr(0, 3) == std::string("OP_")) {
50  ret += str.substr(3, std::string::npos) + " ";
51  continue;
52  }
53  }
54 
55  if (vch.size() > 0) {
56  ret += strprintf("0x%x 0x%x ", HexStr(it2, it - vch.size()),
57  HexStr(it - vch.size(), it));
58  } else {
59  ret += strprintf("0x%x ", HexStr(it2, it));
60  }
61 
62  continue;
63  }
64 
65  ret += strprintf("0x%x ", HexStr(it2, script.end()));
66  break;
67  }
68 
69  return ret.substr(0, ret.size() - 1);
70 }
71 
72 const std::map<uint8_t, std::string> mapSigHashTypes = {
73  {SIGHASH_ALL, "ALL"},
74  {SIGHASH_ALL | SIGHASH_ANYONECANPAY, "ALL|ANYONECANPAY"},
75  {SIGHASH_ALL | SIGHASH_FORKID, "ALL|FORKID"},
77  "ALL|FORKID|ANYONECANPAY"},
78  {SIGHASH_NONE, "NONE"},
79  {SIGHASH_NONE | SIGHASH_ANYONECANPAY, "NONE|ANYONECANPAY"},
80  {SIGHASH_NONE | SIGHASH_FORKID, "NONE|FORKID"},
82  "NONE|FORKID|ANYONECANPAY"},
83  {SIGHASH_SINGLE, "SINGLE"},
84  {SIGHASH_SINGLE | SIGHASH_ANYONECANPAY, "SINGLE|ANYONECANPAY"},
85  {SIGHASH_SINGLE | SIGHASH_FORKID, "SINGLE|FORKID"},
87  "SINGLE|FORKID|ANYONECANPAY"},
88 };
89 
90 std::string SighashToStr(uint8_t sighash_type) {
91  const auto &it = mapSigHashTypes.find(sighash_type);
92  if (it == mapSigHashTypes.end()) {
93  return "";
94  }
95  return it->second;
96 }
97 
107 std::string ScriptToAsmStr(const CScript &script,
108  const bool fAttemptSighashDecode) {
109  std::string str;
110  opcodetype opcode;
111  std::vector<uint8_t> vch;
112  CScript::const_iterator pc = script.begin();
113  while (pc < script.end()) {
114  if (!str.empty()) {
115  str += " ";
116  }
117 
118  if (!script.GetOp(pc, opcode, vch)) {
119  str += "[error]";
120  return str;
121  }
122 
123  if (0 <= opcode && opcode <= OP_PUSHDATA4) {
124  if (vch.size() <= static_cast<std::vector<uint8_t>::size_type>(4)) {
125  str += strprintf("%d", CScriptNum(vch, false).getint());
126  } else {
127  // the IsUnspendable check makes sure not to try to decode
128  // OP_RETURN data that may match the format of a signature
129  if (fAttemptSighashDecode && !script.IsUnspendable()) {
130  std::string strSigHashDecode;
131  // goal: only attempt to decode a defined sighash type from
132  // data that looks like a signature within a scriptSig. This
133  // won't decode correctly formatted public keys in Pubkey or
134  // Multisig scripts due to the restrictions on the pubkey
135  // formats (see IsCompressedOrUncompressedPubKey) being
136  // incongruous with the checks in
137  // CheckTransactionSignatureEncoding.
138  uint32_t flags = SCRIPT_VERIFY_STRICTENC;
139  if (vch.back() & SIGHASH_FORKID) {
140  // If the transaction is using SIGHASH_FORKID, we need
141  // to set the appropriate flag.
142  // TODO: Remove after the Hard Fork.
144  }
145  if (CheckTransactionSignatureEncoding(vch, flags,
146  nullptr)) {
147  const uint8_t chSigHashType = vch.back();
148  if (mapSigHashTypes.count(chSigHashType)) {
149  strSigHashDecode =
150  "[" +
151  mapSigHashTypes.find(chSigHashType)->second +
152  "]";
153  // remove the sighash type byte. it will be replaced
154  // by the decode.
155  vch.pop_back();
156  }
157  }
158 
159  str += HexStr(vch) + strSigHashDecode;
160  } else {
161  str += HexStr(vch);
162  }
163  }
164  } else {
165  str += GetOpName(opcode);
166  }
167  }
168 
169  return str;
170 }
171 
172 std::string EncodeHexTx(const CTransaction &tx, const int serializeFlags) {
173  CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | serializeFlags);
174  ssTx << tx;
175  return HexStr(ssTx.begin(), ssTx.end());
176 }
177 
178 void ScriptToUniv(const CScript &script, UniValue &out, bool include_address) {
179  out.pushKV("asm", ScriptToAsmStr(script));
180  out.pushKV("hex", HexStr(script.begin(), script.end()));
181 
182  std::vector<std::vector<uint8_t>> solns;
183  txnouttype type = Solver(script, solns);
184  out.pushKV("type", GetTxnOutputType(type));
185 
186  CTxDestination address;
187  if (include_address && ExtractDestination(script, address) &&
188  type != TX_PUBKEY) {
189  out.pushKV("address", EncodeDestination(address, GetConfig()));
190  }
191 }
192 
193 void ScriptPubKeyToUniv(const CScript &scriptPubKey, UniValue &out,
194  bool fIncludeHex) {
196  std::vector<CTxDestination> addresses;
197  int nRequired;
198 
199  out.pushKV("asm", ScriptToAsmStr(scriptPubKey));
200  if (fIncludeHex) {
201  out.pushKV("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
202  }
203 
204  if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired) ||
205  type == TX_PUBKEY) {
206  out.pushKV("type", GetTxnOutputType(type));
207  return;
208  }
209 
210  out.pushKV("reqSigs", nRequired);
211  out.pushKV("type", GetTxnOutputType(type));
212 
214  for (const CTxDestination &addr : addresses) {
216  }
217  out.pushKV("addresses", a);
218 }
219 
220 void TxToUniv(const CTransaction &tx, const uint256 &hashBlock, UniValue &entry,
221  bool include_hex, int serialize_flags) {
222  entry.pushKV("txid", tx.GetId().GetHex());
223  entry.pushKV("hash", tx.GetHash().GetHex());
224  entry.pushKV("version", tx.nVersion);
225  entry.pushKV("size", (int)::GetSerializeSize(tx, PROTOCOL_VERSION));
226  entry.pushKV("locktime", (int64_t)tx.nLockTime);
227 
229  for (unsigned int i = 0; i < tx.vin.size(); i++) {
230  const CTxIn &txin = tx.vin[i];
232  if (tx.IsCoinBase()) {
233  in.pushKV("coinbase",
234  HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
235  } else {
236  in.pushKV("txid", txin.prevout.GetTxId().GetHex());
237  in.pushKV("vout", int64_t(txin.prevout.GetN()));
239  o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true));
240  o.pushKV("hex",
241  HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
242  in.pushKV("scriptSig", o);
243  }
244 
245  in.pushKV("sequence", (int64_t)txin.nSequence);
246  vin.push_back(in);
247  }
248 
249  entry.pushKV("vin", vin);
250 
251  UniValue vout(UniValue::VARR);
252  for (unsigned int i = 0; i < tx.vout.size(); i++) {
253  const CTxOut &txout = tx.vout[i];
254 
256 
257  out.pushKV("value", ValueFromAmount(txout.nValue));
258  out.pushKV("n", int64_t(i));
259 
261  ScriptPubKeyToUniv(txout.scriptPubKey, o, true);
262  out.pushKV("scriptPubKey", o);
263  vout.push_back(out);
264  }
265 
266  entry.pushKV("vout", vout);
267 
268  if (!hashBlock.IsNull()) {
269  entry.pushKV("blockhash", hashBlock.GetHex());
270  }
271 
272  if (include_hex) {
273  // The hex-encoded transaction. Used the name "hex" to be consistent
274  // with the verbose output of "getrawtransaction".
275  entry.pushKV("hex", EncodeHexTx(tx, serialize_flags));
276  }
277 }
uint32_t GetN() const
Definition: transaction.h:44
txnouttype Solver(const CScript &scriptPubKey, std::vector< std::vector< uint8_t >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
Definition: standard.cpp:102
void TxToUniv(const CTransaction &tx, const uint256 &hashBlock, UniValue &entry, bool include_hex, int serialize_flags)
Definition: core_write.cpp:220
static constexpr Amount zero()
Definition: amount.h:35
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
Definition: standard.cpp:152
CScript scriptPubKey
Definition: transaction.h:144
std::string EncodeHexTx(const CTransaction &tx, const int serializeFlags)
Definition: core_write.cpp:172
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1201
Definition: amount.h:17
const TxId & GetTxId() const
Definition: transaction.h:43
const TxHash GetHash() const
Definition: transaction.h:262
static constexpr Amount SATOSHI
Definition: amount.h:151
std::string EncodeDestination(const CTxDestination &dest, const Config &config)
Definition: key_io.cpp:170
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:196
bool IsNull() const
Definition: uint256.h:26
bool IsCoinBase() const
Definition: transaction.h:275
void ScriptToUniv(const CScript &script, UniValue &out, bool include_address)
Definition: core_write.cpp:178
const std::map< uint8_t, std::string > mapSigHashTypes
Definition: core_write.cpp:72
void ScriptPubKeyToUniv(const CScript &scriptPubKey, UniValue &out, bool fIncludeHex)
Definition: core_write.cpp:193
Definition: script.h:71
const std::vector< CTxIn > vin
Definition: transaction.h:227
size_t GetSerializeSize(const T &t, int nVersion=0)
Definition: serialize.h:1193
std::string ScriptToAsmStr(const CScript &script, const bool fAttemptSighashDecode)
Create the assembly string representation of a CScript object.
Definition: core_write.cpp:107
bool IsUnspendable() const
Returns whether the script is guaranteed to fail at execution, regardless of the initial stack...
Definition: script.h:571
bool ExtractDestinations(const CScript &scriptPubKey, txnouttype &typeRet, std::vector< CTxDestination > &addressRet, int &nRequiredRet)
Parse a standard scriptPubKey with one or more destination addresses.
Definition: standard.cpp:178
iterator end()
Definition: prevector.h:390
opcodetype
Script opcodes.
Definition: script.h:46
bool push_back(const UniValue &val)
Definition: univalue.cpp:108
static constexpr Amount COIN
Definition: amount.h:153
An input of a transaction.
Definition: transaction.h:67
UniValue()
Definition: univalue.h:29
Definition: script.h:55
Definition: script.h:74
const std::vector< CTxOut > vout
Definition: transaction.h:228
const char * GetTxnOutputType(txnouttype t)
Get the name of a txnouttype as a C string, or nullptr if unknown.
Definition: standard.cpp:23
const Config & GetConfig()
Definition: config.cpp:34
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:133
An output of a transaction.
Definition: transaction.h:141
std::string FormatScript(const CScript &script)
Definition: core_write.cpp:29
const char * GetOpName(opcodetype opcode)
Definition: script.cpp:13
CScript scriptSig
Definition: transaction.h:70
int flags
Definition: bitcoin-tx.cpp:529
txnouttype
Definition: standard.h:41
256-bit opaque blob.
Definition: uint256.h:120
const int32_t nVersion
Definition: transaction.h:229
enum VType type() const
Definition: univalue.h:135
const_iterator end() const
Definition: streams.h:277
const_iterator begin() const
Definition: streams.h:275
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:429
bool CheckTransactionSignatureEncoding(const valtype &vchSig, uint32_t flags, ScriptError *serror)
Check that the signature provided to authentify a transaction is properly encoded.
uint32_t nSequence
Definition: transaction.h:71
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:11
std::string GetHex() const
Definition: uint256.cpp:16
std::string HexStr(const T itbegin, const T itend)
Definition: strencodings.h:132
std::string SighashToStr(uint8_t sighash_type)
Definition: core_write.cpp:90
bool GetOp(const_iterator &pc, opcodetype &opcodeRet, std::vector< uint8_t > &vchRet) const
Definition: script.h:524
iterator begin()
Definition: prevector.h:388
The basic transaction that is broadcasted on the network and contained in blocks. ...
Definition: transaction.h:211
COutPoint prevout
Definition: transaction.h:69
Definition: script.h:48
Amount nValue
Definition: transaction.h:143
boost::variant< CNoDestination, PKHash, ScriptHash > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:87
const TxId GetId() const
Definition: transaction.h:261
const uint32_t nLockTime
Definition: transaction.h:230
UniValue ValueFromAmount(const Amount &amount)
Definition: core_write.cpp:20