BitShares-Core  4.0.0
BitShares blockchain implementation and command-line interface software
operation_printer.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Cryptonomex, Inc., and contributors.
3  *
4  * The MIT License
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include "operation_printer.hpp"
26 #include "wallet_api_impl.hpp"
28 
29 namespace graphene { namespace wallet { namespace detail {
30 
32 {
33 public:
34  typedef std::string result_type;
35 
36  result_type operator()( const fc::ripemd160& hash )const
37  {
38  return "RIPEMD160 " + hash.str();
39  }
40 
41  result_type operator()( const fc::sha1& hash )const
42  {
43  return "SHA1 " + hash.str();
44  }
45 
46  result_type operator()( const fc::sha256& hash )const
47  {
48  return "SHA256 " + hash.str();
49  }
50  result_type operator()( const fc::hash160& hash )const
51  {
52  return "HASH160 " + hash.str();
53  }
54 };
55 
56 std::string operation_printer::fee(const graphene::protocol::asset& a)const {
57  out << " (Fee: " << wallet.get_asset(a.asset_id).amount_to_pretty_string(a) << ")";
58  return "";
59 }
60 
62 {
63  std::string outstr;
64  if( memo )
65  {
66  if( wallet.is_locked() )
67  {
68  out << " -- Unlock wallet to see memo.";
69  } else {
70  try {
71  FC_ASSERT( wallet._keys.count(memo->to) || wallet._keys.count(memo->from),
72  "Memo is encrypted to a key ${to} or ${from} not in this wallet.",
73  ("to", memo->to)("from",memo->from) );
74  if( wallet._keys.count(memo->to) ) {
75  auto my_key = wif_to_key(wallet._keys.at(memo->to));
76  FC_ASSERT(my_key, "Unable to recover private key to decrypt memo. Wallet may be corrupted.");
77  outstr = memo->get_message(*my_key, memo->from);
78  out << " -- Memo: " << outstr;
79  } else {
80  auto my_key = wif_to_key(wallet._keys.at(memo->from));
81  FC_ASSERT(my_key, "Unable to recover private key to decrypt memo. Wallet may be corrupted.");
82  outstr = memo->get_message(*my_key, memo->to);
83  out << " -- Memo: " << outstr;
84  }
85  } catch (const fc::exception& e) {
86  out << " -- could not decrypt memo";
87  }
88  }
89  }
90  return outstr;
91 }
92 
93 void operation_printer::print_preimage(const std::vector<char>& preimage)const
94 {
95  if (preimage.size() == 0)
96  return;
97  out << " with preimage \"";
98  // cut it at 300 bytes max
99  auto flags = out.flags();
100  out << std::hex << setw(2) << setfill('0');
101  for (size_t i = 0; i < std::min<size_t>(300, preimage.size()); i++)
102  out << +preimage[i];
103  out.flags(flags);
104  if (preimage.size() > 300)
105  out << "...(truncated due to size)";
106  out << "\"";
107 }
108 
109 string operation_printer::print_redeem(const graphene::protocol::htlc_id_type& id,
110  const std::string& redeemer, const std::vector<char>& preimage,
111  const graphene::protocol::asset& op_fee)const
112 {
113  out << redeemer << " redeemed HTLC with id "
114  << std::string( static_cast<object_id_type>(id));
115  print_preimage( preimage );
116  return fee(op_fee);
117 }
118 
120 {
121  auto a = wallet.get_asset( op.fee.asset_id );
122  auto receiver = wallet.get_account( op.to );
123 
124  out << receiver.name
125  << " received " << a.amount_to_pretty_string( op.amount ) << " from blinded balance";
126  return "";
127 }
129 {
130  auto fa = wallet.get_asset( op.fee.asset_id );
131  auto a = wallet.get_asset( op.amount.asset_id );
132  auto sender = wallet.get_account( op.from );
133 
134  out << sender.name
135  << " sent " << a.amount_to_pretty_string( op.amount ) << " to " << op.outputs.size()
136  << " blinded balance" << (op.outputs.size()>1?"s":"")
137  << " fee: " << fa.amount_to_pretty_string( op.fee );
138  return "";
139 }
140 
142 {
143  out << "Transfer " << wallet.get_asset(op.amount.asset_id).amount_to_pretty_string(op.amount)
144  << " from " << wallet.get_account(op.from).name << " to " << wallet.get_account(op.to).name;
145  std::string memo = print_memo( op.memo );
146  fee(op.fee);
147  return memo;
148 }
149 
151 {
152  out << "Create Account '" << op.name << "'";
153  return fee(op.fee);
154 }
155 
157 {
158  out << "Update Account '" << wallet.get_account(op.account).name << "'";
159  return fee(op.fee);
160 }
161 
163 {
164  out << "Create ";
165  if( op.bitasset_opts.valid() )
166  out << "BitAsset ";
167  else
168  out << "User-Issue Asset ";
169  out << "'" << op.symbol << "' with issuer " << wallet.get_account(op.issuer).name;
170  return fee(op.fee);
171 }
172 
174 {
175  return print_redeem(op.htlc_id, wallet.get_account(op.redeemer).name, op.preimage, op.fee);
176 }
177 
179 {
180  return print_redeem(op.htlc_id, wallet.get_account(op.redeemer).name, op.preimage, op.fee);
181 }
182 
184 {
185  static htlc_hash_to_string_visitor vtor;
186 
187  auto fee_asset = wallet.get_asset( op.fee.asset_id );
188  auto to = wallet.get_account( op.to );
189  auto from = wallet.get_account( op.from );
190  operation_result_printer rprinter(wallet);
191  std::string database_id = result.visit(rprinter);
192 
193  out << "Create HTLC from " << from.name << " to " << to.name
194  << " with id " << database_id
195  << " preimage hash: [" << op.preimage_hash.visit( vtor ) << "] ";
196  print_memo( op.extensions.value.memo );
197  // determine if the block that the HTLC is in is before or after LIB
198  int32_t pending_blocks = hist.block_num - wallet.get_dynamic_global_properties().last_irreversible_block_num;
199  if (pending_blocks > 0)
200  out << " (pending " << std::to_string(pending_blocks) << " blocks)";
201  return fee(op.fee);
202 }
203 
205 {
206  return "";
207 }
208 
210 {
211  return std::string(oid);
212 }
213 
215 {
216  return _wallet.get_asset(a.asset_id).amount_to_pretty_string(a);
217 }
218 
220 {
221  return fc::json::to_pretty_string(r);
222 }
223 
224 }}} // graphene::wallet::detail
string str() const
Definition: hash160.cpp:46
void print_preimage(const std::vector< char > &preimage) const
result_type operator()(const fc::ripemd160 &hash) const
Definition: api.cpp:56
fc::optional< fc::ecc::private_key > wif_to_key(const std::string &wif_key)
Update an existing account.
Definition: account.hpp:135
std::string operator()(const graphene::protocol::void_result &x) const
Used to generate a useful error report when an exception is thrown.At each level in the stack where t...
Definition: exception.hpp:56
visitor::result_type visit(visitor &v)
extension< additional_options_type > extensions
Definition: htlc.hpp:72
public_key_type to
Definition: memo.hpp:43
string symbol
The ticker symbol of this asset.
Definition: asset_ops.hpp:167
result_type operator()(const fc::hash160 &hash) const
Transfers an amount of one asset from one account to another.
Definition: transfer.hpp:45
Converts blinded/stealth balance to a public account balance.
string str() const
Definition: ripemd160.cpp:21
result_type operator()(const fc::sha1 &hash) const
std::string get_message(const fc::ecc::private_key &priv, const fc::ecc::public_key &pub) const
Definition: memo.cpp:58
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
static string to_pretty_string(const variant &v, output_formatting format=stringify_large_ints_and_doubles, uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
Definition: json.cpp:736
string str() const
Definition: sha256.cpp:24
account_id_type issuer
This account must sign and pay the fee for this operation. Later, this account may update the asset...
Definition: asset_ops.hpp:165
optional< memo_data > memo
User provided data encrypted to the memo key of the "to" account.
Definition: transfer.hpp:61
account_id_type account
The account to update.
Definition: account.hpp:152
asset amount
The amount of asset to transfer from from to to.
Definition: transfer.hpp:58
std::string to_string(double)
Definition: string.cpp:73
asset_id_type asset_id
Definition: asset.hpp:39
std::string operator()(const T &op) const
optional< bitasset_options > bitasset_opts
Definition: asset_ops.hpp:179
account_id_type from
Account to transfer asset from.
Definition: transfer.hpp:54
std::string print_memo(const fc::optional< graphene::protocol::memo_data > &memo) const
result_type operator()(const fc::sha256 &hash) const
public_key_type from
Definition: memo.hpp:42
std::string print_redeem(const graphene::protocol::htlc_id_type &id, const std::string &redeemer, const std::vector< char > &preimage, const graphene::protocol::asset &op_fee) const
account_id_type to
Account to transfer asset to.
Definition: transfer.hpp:56
Converts public account balance to a blinded or stealth balance.
std::string str() const
Definition: sha1.cpp:18