BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
wallet_transfer.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 "wallet_api_impl.hpp"
26 
27 /***
28  * Methods to handle transfers / exchange orders
29  */
30 
31 namespace graphene { namespace wallet { namespace detail {
32 
33  /***
34  * @brief a helper method to create an htlc_hash from an algo/hash combination
35  */
36  htlc_hash wallet_api_impl::do_hash( const string& algorithm, const std::string& hash )
37  {
38  string name_upper;
39  std::transform( algorithm.begin(), algorithm.end(), std::back_inserter(name_upper), ::toupper);
40  if( name_upper == "RIPEMD160" )
41  return fc::ripemd160( hash );
42  if( name_upper == "SHA256" )
43  return fc::sha256( hash );
44  if( name_upper == "SHA1" )
45  return fc::sha1( hash );
46  if( name_upper == "HASH160" )
47  return fc::hash160( hash );
48  FC_THROW_EXCEPTION( fc::invalid_arg_exception, "Unknown algorithm '${a}'", ("a",algorithm) );
49  }
50 
51  signed_transaction wallet_api_impl::transfer(string from, string to, string amount,
52  string asset_symbol, string memo, bool broadcast )
53  { try {
54  FC_ASSERT( !self.is_locked() );
55  fc::optional<asset_object> asset_obj = get_asset(asset_symbol);
56  FC_ASSERT(asset_obj, "Could not find asset matching ${asset}", ("asset", asset_symbol));
57 
58  account_object from_account = get_account(from);
59  account_object to_account = get_account(to);
60  account_id_type from_id = from_account.get_id();
61  account_id_type to_id = to_account.get_id();
62 
63  transfer_operation xfer_op;
64 
65  xfer_op.from = from_id;
66  xfer_op.to = to_id;
67  xfer_op.amount = asset_obj->amount_from_string(amount);
68 
69  if( memo.size() )
70  {
71  xfer_op.memo = memo_data();
72  xfer_op.memo->from = from_account.options.memo_key;
73  xfer_op.memo->to = to_account.options.memo_key;
74  xfer_op.memo->set_message(get_private_key(from_account.options.memo_key),
75  to_account.options.memo_key, memo);
76  }
77 
79  tx.operations.push_back(xfer_op);
80  set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees());
81  tx.validate();
82 
83  return sign_transaction(tx, broadcast);
84  } FC_CAPTURE_AND_RETHROW( (from)(to)(amount)(asset_symbol)(memo)(broadcast) ) }
85 
86  signed_transaction wallet_api_impl::htlc_create( const string& source, const string& destination,
87  const string& amount, const string& asset_symbol, const string& hash_algorithm,
88  const string& preimage_hash, uint32_t preimage_size,
89  uint32_t claim_period_seconds, const string& memo, bool broadcast )
90  {
91  try
92  {
93  FC_ASSERT( !self.is_locked() );
94  fc::optional<asset_object> asset_obj = get_asset(asset_symbol);
95  FC_ASSERT(asset_obj, "Could not find asset matching ${asset}", ("asset", asset_symbol));
96 
97  const account_object& from_acct = get_account(source);
98  const account_object& to_acct = get_account(destination);
99  htlc_create_operation create_op;
100  create_op.from = get_account(source).id;
101  create_op.to = get_account(destination).id;
102  create_op.amount = asset_obj->amount_from_string(amount);
103  create_op.claim_period_seconds = claim_period_seconds;
104  create_op.preimage_hash = do_hash( hash_algorithm, preimage_hash );
105  create_op.preimage_size = preimage_size;
106  if (!memo.empty())
107  {
108  memo_data data;
109  data.from = from_acct.options.memo_key;
110  data.to = to_acct.options.memo_key;
111  data.set_message(
112  get_private_key(from_acct.options.memo_key), to_acct.options.memo_key, memo);
113  create_op.extensions.value.memo = data;
114  }
115 
117  tx.operations.push_back(create_op);
118  set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees());
119  tx.validate();
120 
121  return sign_transaction(tx, broadcast);
122  } FC_CAPTURE_AND_RETHROW( (source)(destination)(amount)(asset_symbol)(hash_algorithm)
123  (preimage_hash)(preimage_size)(claim_period_seconds)(broadcast) )
124  }
125 
126  signed_transaction wallet_api_impl::htlc_redeem( const htlc_id_type& htlc_id, const string& issuer,
127  const std::vector<char>& preimage, bool broadcast )
128  {
129  try
130  {
131  FC_ASSERT( !self.is_locked() );
132  fc::optional<htlc_object> htlc_obj = get_htlc(htlc_id);
133  FC_ASSERT(htlc_obj, "Could not find HTLC matching ${htlc}", ("htlc", htlc_id));
134 
135  account_object issuer_obj = get_account(issuer);
136 
137  htlc_redeem_operation update_op;
138  update_op.htlc_id = htlc_obj->id;
139  update_op.redeemer = issuer_obj.id;
140  update_op.preimage = preimage;
141 
143  tx.operations.push_back(update_op);
144  set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees());
145  tx.validate();
146 
147  return sign_transaction(tx, broadcast);
148  } FC_CAPTURE_AND_RETHROW( (htlc_id)(issuer)(preimage)(broadcast) )
149  }
150 
151  signed_transaction wallet_api_impl::htlc_extend( const htlc_id_type& htlc_id, const string& issuer,
152  uint32_t seconds_to_add, bool broadcast )
153  {
154  try
155  {
156  FC_ASSERT( !self.is_locked() );
157  fc::optional<htlc_object> htlc_obj = get_htlc(htlc_id);
158  FC_ASSERT(htlc_obj, "Could not find HTLC matching ${htlc}", ("htlc", htlc_id));
159 
160  account_object issuer_obj = get_account(issuer);
161 
162  htlc_extend_operation update_op;
163  update_op.htlc_id = htlc_obj->id;
164  update_op.update_issuer = issuer_obj.id;
165  update_op.seconds_to_add = seconds_to_add;
166 
168  tx.operations.push_back(update_op);
169  set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees());
170  tx.validate();
171 
172  return sign_transaction(tx, broadcast);
173  } FC_CAPTURE_AND_RETHROW( (htlc_id)(issuer)(seconds_to_add)(broadcast) )
174  }
175 
176  fc::optional<htlc_object> wallet_api_impl::get_htlc(const htlc_id_type& htlc_id) const
177  {
178  auto obj = _remote_db->get_objects( { object_id_type(htlc_id) }, {}).front();
179  if ( !obj.is_null() )
180  {
181  return fc::optional<htlc_object>(obj.template as<htlc_object>(GRAPHENE_MAX_NESTED_OBJECTS));
182  }
183  return fc::optional<htlc_object>();
184  }
185 
186  signed_transaction wallet_api_impl::sell_asset(string seller_account, string amount_to_sell,
187  string symbol_to_sell, string min_to_receive, string symbol_to_receive,
188  uint32_t timeout_sec, bool fill_or_kill, bool broadcast )
189  {
190  account_object seller = get_account( seller_account );
191 
193  op.seller = seller.id;
194  op.amount_to_sell = get_asset(symbol_to_sell).amount_from_string(amount_to_sell);
195  op.min_to_receive = get_asset(symbol_to_receive).amount_from_string(min_to_receive);
196  if( timeout_sec )
197  op.expiration = fc::time_point::now() + fc::seconds(timeout_sec);
198  op.fill_or_kill = fill_or_kill;
199 
201  tx.operations.push_back(op);
202  set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees());
203  tx.validate();
204 
205  return sign_transaction( tx, broadcast );
206  }
207 
208  signed_transaction wallet_api_impl::borrow_asset_ext( string seller_name, string amount_to_borrow,
209  string asset_symbol, string amount_of_collateral,
210  call_order_update_operation::extensions_type extensions, bool broadcast )
211  {
212  account_object seller = get_account(seller_name);
213  auto mia = get_asset(asset_symbol);
214  FC_ASSERT(mia.is_market_issued());
215  auto collateral = get_asset(get_object(*mia.bitasset_data_id).options.short_backing_asset);
216 
218  op.funding_account = seller.id;
219  op.delta_debt = mia.amount_from_string(amount_to_borrow);
220  op.delta_collateral = collateral.amount_from_string(amount_of_collateral);
221  op.extensions = extensions;
222 
223  signed_transaction trx;
224  trx.operations = {op};
225  set_operation_fees( trx, _remote_db->get_global_properties().parameters.get_current_fees());
226  trx.validate();
227 
228  return sign_transaction(trx, broadcast);
229  }
230 
231  signed_transaction wallet_api_impl::cancel_order(const limit_order_id_type& order_id, bool broadcast )
232  { try {
233  FC_ASSERT(!is_locked());
234  signed_transaction trx;
235 
237  op.fee_paying_account = get_object(order_id).seller;
238  op.order = order_id;
239  trx.operations = {op};
240  set_operation_fees( trx, _remote_db->get_global_properties().parameters.get_current_fees());
241 
242  trx.validate();
243  return sign_transaction(trx, broadcast);
244  } FC_CAPTURE_AND_RETHROW((order_id)) }
245 
246  signed_transaction wallet_api_impl::withdraw_vesting( string witness_name, string amount, string asset_symbol,
247  bool broadcast )
248  { try {
249  auto asset_obj = get_asset( asset_symbol );
250  fc::optional<vesting_balance_id_type> vbid = maybe_id<vesting_balance_id_type>(witness_name);
251  if( !vbid )
252  {
253  witness_object wit = get_witness( witness_name );
254  FC_ASSERT( wit.pay_vb );
255  vbid = wit.pay_vb;
256  }
257 
258  vesting_balance_object vbo = get_object( *vbid );
259  vesting_balance_withdraw_operation vesting_balance_withdraw_op;
260 
261  vesting_balance_withdraw_op.vesting_balance = *vbid;
262  vesting_balance_withdraw_op.owner = vbo.owner;
263  vesting_balance_withdraw_op.amount = asset_obj.amount_from_string(amount);
264 
266  tx.operations.push_back( vesting_balance_withdraw_op );
267  set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees() );
268  tx.validate();
269 
270  return sign_transaction( tx, broadcast );
271  } FC_CAPTURE_AND_RETHROW( (witness_name)(amount) )
272  }
273 
274 }}} // namespace graphene::wallet::detail
graphene::protocol::transaction::operations
vector< operation > operations
Definition: transaction.hpp:89
FC_CAPTURE_AND_RETHROW
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:479
graphene::protocol::extension< options_type >
graphene::db::object::id
object_id_type id
Definition: object.hpp:69
graphene::protocol::transfer_operation::amount
asset amount
The amount of asset to transfer from from to to.
Definition: transfer.hpp:58
graphene::protocol::call_order_update_operation::delta_debt
asset delta_debt
the amount of the debt to be paid off, may be negative to issue new debt
Definition: market.hpp:190
graphene::protocol::vesting_balance_withdraw_operation
Withdraw from a vesting balance.
Definition: vesting.hpp:101
graphene::protocol::limit_order_create_operation::amount_to_sell
asset amount_to_sell
Definition: market.hpp:89
graphene::wallet::detail::wallet_api_impl::get_asset
extended_asset_object get_asset(asset_id_type id) const
Definition: wallet_asset.cpp:63
graphene::protocol::vesting_balance_withdraw_operation::vesting_balance
vesting_balance_id_type vesting_balance
Definition: vesting.hpp:106
fc::static_variant< htlc_algo_ripemd160, htlc_algo_sha1, htlc_algo_sha256, htlc_algo_hash160 >
graphene::protocol::htlc_create_operation::preimage_size
uint16_t preimage_size
Definition: htlc.hpp:63
graphene::protocol::htlc_redeem_operation
Definition: htlc.hpp:90
graphene::protocol::vesting_balance_withdraw_operation::amount
asset amount
Definition: vesting.hpp:108
graphene::wallet::detail::wallet_api_impl::get_private_key
fc::ecc::private_key get_private_key(const public_key_type &id) const
Definition: wallet_sign.cpp:406
graphene::protocol::htlc_redeem_operation::preimage
std::vector< char > preimage
Definition: htlc.hpp:104
graphene::protocol::htlc_create_operation::from
account_id_type from
Definition: htlc.hpp:55
graphene::wallet::detail::wallet_api_impl::_remote_db
fc::api< database_api > _remote_db
Definition: wallet_api_impl.hpp:414
fc::sha256
Definition: sha256.hpp:10
graphene::wallet::detail::wallet_api_impl::sign_transaction
signed_transaction sign_transaction(signed_transaction tx, bool broadcast=false)
Definition: wallet_sign.cpp:336
graphene::wallet::detail::wallet_api_impl::set_operation_fees
void set_operation_fees(signed_transaction &tx, const fee_schedule &s) const
Definition: wallet_api_impl.cpp:197
graphene::wallet::detail::wallet_api_impl::htlc_redeem
signed_transaction htlc_redeem(const htlc_id_type &htlc_id, const string &issuer, const std::vector< char > &preimage, bool broadcast)
Definition: wallet_transfer.cpp:132
graphene::protocol::htlc_extend_operation::htlc_id
htlc_id_type htlc_id
Definition: htlc.hpp:163
wallet_api_impl.hpp
graphene::protocol::call_order_update_operation::delta_collateral
asset delta_collateral
the amount of collateral to add to the margin position
Definition: market.hpp:189
graphene::chain::witness_object::pay_vb
optional< vesting_balance_id_type > pay_vb
Definition: witness_object.hpp:38
graphene::chain::asset_object::amount_from_string
asset amount_from_string(string amount_string) const
Definition: asset_object.cpp:152
fc::seconds
microseconds seconds(int64_t s)
Definition: time.hpp:34
graphene::protocol::htlc_create_operation::to
account_id_type to
Definition: htlc.hpp:57
graphene::wallet::detail::wallet_api_impl::get_account
account_object get_account(account_id_type id) const
Definition: wallet_account.cpp:193
graphene::wallet::detail::wallet_api_impl::get_htlc
fc::optional< htlc_object > get_htlc(const htlc_id_type &htlc_id) const
Definition: wallet_transfer.cpp:182
graphene::protocol::memo_data::to
public_key_type to
Definition: memo.hpp:43
graphene::protocol::htlc_create_operation
Definition: htlc.hpp:45
graphene::chain::vesting_balance_object
Definition: vesting_balance_object.hpp:151
graphene::protocol::signed_transaction
adds a signature to a transaction
Definition: transaction.hpp:134
graphene::protocol::limit_order_create_operation::seller
account_id_type seller
Definition: market.hpp:88
graphene::chain::account_object::options
account_options options
Definition: account_object.hpp:222
graphene::wallet::detail::wallet_api_impl::get_witness
witness_object get_witness(string owner_account)
Definition: wallet_voting.cpp:124
graphene::protocol::vesting_balance_withdraw_operation::owner
account_id_type owner
Must be vesting_balance.owner.
Definition: vesting.hpp:107
graphene::protocol::call_order_update_operation
Definition: market.hpp:171
graphene::protocol::htlc_extend_operation::update_issuer
account_id_type update_issuer
Definition: htlc.hpp:165
wallet.hpp
graphene::chain::account_object
This class represents an account on the object graph.
Definition: account_object.hpp:180
graphene::wallet::detail::wallet_api_impl::htlc_extend
signed_transaction htlc_extend(const htlc_id_type &htlc_id, const string &issuer, uint32_t seconds_to_add, bool broadcast)
Definition: wallet_transfer.cpp:157
graphene::protocol::transfer_operation
Transfers an amount of one asset from one account to another.
Definition: transfer.hpp:45
graphene::protocol::htlc_create_operation::amount
asset amount
Definition: htlc.hpp:59
graphene::protocol::account_options::memo_key
public_key_type memo_key
Definition: account.hpp:44
fc::ripemd160
Definition: ripemd160.hpp:11
graphene::protocol::htlc_redeem_operation::htlc_id
htlc_id_type htlc_id
Definition: htlc.hpp:100
graphene::wallet::detail::wallet_api_impl::cancel_order
signed_transaction cancel_order(const limit_order_id_type &order_id, bool broadcast=false)
Definition: wallet_transfer.cpp:237
graphene::protocol::limit_order_cancel_operation
Definition: market.hpp:145
graphene::protocol::call_order_update_operation::extensions
extensions_type extensions
Definition: market.hpp:193
graphene::protocol::limit_order_create_operation::expiration
time_point_sec expiration
Definition: market.hpp:94
graphene::protocol::transfer_operation::to
account_id_type to
Account to transfer asset to.
Definition: transfer.hpp:56
graphene::protocol::limit_order_create_operation::min_to_receive
asset min_to_receive
Definition: market.hpp:90
graphene::protocol::transfer_operation::from
account_id_type from
Account to transfer asset from.
Definition: transfer.hpp:54
fc::typelist::transform
typename impl::transform< List, Transformer >::type transform
Transform elements of a typelist.
Definition: typelist.hpp:170
graphene::wallet::detail::wallet_api_impl::withdraw_vesting
signed_transaction withdraw_vesting(string witness_name, string amount, string asset_symbol, bool broadcast=false)
Definition: wallet_transfer.cpp:252
graphene::protocol::htlc_create_operation::preimage_hash
htlc_hash preimage_hash
Definition: htlc.hpp:61
fc::time_point::now
static time_point now()
Definition: time.cpp:13
FC_ASSERT
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
fc::sha1
Definition: sha1.hpp:10
graphene::protocol::memo_data::set_message
void set_message(const fc::ecc::private_key &priv, const fc::ecc::public_key &pub, const string &msg, uint64_t custom_nonce=0)
Definition: memo.cpp:31
graphene::protocol::transaction::validate
virtual void validate() const
Definition: transaction.cpp:58
graphene::db::object_id_type
Definition: object_id.hpp:30
graphene::wallet::detail::wallet_api_impl::transfer
signed_transaction transfer(string from, string to, string amount, string asset_symbol, string memo, bool broadcast=false)
Definition: wallet_transfer.cpp:57
graphene::wallet::detail::wallet_api_impl::get_object
graphene::db::object_downcast_t< const ID & > get_object(const ID &id) const
Definition: wallet_api_impl.hpp:129
GRAPHENE_MAX_NESTED_OBJECTS
#define GRAPHENE_MAX_NESTED_OBJECTS
Definition: config.hpp:33
graphene::protocol::limit_order_cancel_operation::fee_paying_account
account_id_type fee_paying_account
Definition: market.hpp:152
graphene::chain::witness_object
Definition: witness_object.hpp:32
graphene::protocol::limit_order_cancel_operation::order
limit_order_id_type order
Definition: market.hpp:150
graphene::protocol::htlc_extend_operation
Definition: htlc.hpp:153
graphene::protocol::limit_order_create_operation
instructs the blockchain to attempt to sell one asset for another
Definition: market.hpp:72
graphene::protocol::memo_data
defines the keys used to derive the shared secret
Definition: memo.hpp:40
graphene::wallet::detail::wallet_api_impl::is_locked
bool is_locked() const
Definition: wallet_api_impl.cpp:304
graphene::db::abstract_object::get_id
object_id< SpaceID, TypeID > get_id() const
Definition: object.hpp:113
graphene::chain::vesting_balance_object::owner
account_id_type owner
Account which owns and may withdraw from this vesting balance.
Definition: vesting_balance_object.hpp:156
fc::optional
provides stack-based nullable value similar to boost::optional
Definition: optional.hpp:20
graphene::protocol::transfer_operation::memo
optional< memo_data > memo
User provided data encrypted to the memo key of the "to" account.
Definition: transfer.hpp:61
graphene::protocol::htlc_redeem_operation::redeemer
account_id_type redeemer
Definition: htlc.hpp:102
FC_THROW_EXCEPTION
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
Definition: exception.hpp:379
fc::hash160
Definition: hash160.hpp:32
graphene::protocol::memo_data::from
public_key_type from
Definition: memo.hpp:42
graphene::protocol::limit_order_create_operation::fill_or_kill
bool fill_or_kill
If this flag is set the entire order must be filled or the operation is rejected.
Definition: market.hpp:97
graphene::wallet::detail::wallet_api_impl::htlc_create
signed_transaction htlc_create(const string &source, const string &destination, const string &amount, const string &asset_symbol, const string &hash_algorithm, const string &preimage_hash, uint32_t preimage_size, uint32_t claim_period_seconds, const string &memo, bool broadcast=false)
Definition: wallet_transfer.cpp:92
graphene::protocol::htlc_extend_operation::seconds_to_add
uint32_t seconds_to_add
Definition: htlc.hpp:167
graphene::protocol::htlc_create_operation::extensions
extension< additional_options_type > extensions
Definition: htlc.hpp:72
graphene::protocol::call_order_update_operation::funding_account
account_id_type funding_account
pays fee, collateral, and cover
Definition: market.hpp:188
graphene::wallet::detail::wallet_api_impl::borrow_asset_ext
signed_transaction borrow_asset_ext(string seller_name, string amount_to_borrow, string asset_symbol, string amount_of_collateral, call_order_update_operation::extensions_type extensions, bool broadcast=false)
Definition: wallet_transfer.cpp:214
graphene::wallet::detail::wallet_api_impl::sell_asset
signed_transaction sell_asset(string seller_account, string amount_to_sell, string symbol_to_sell, string min_to_receive, string symbol_to_receive, uint32_t timeout_sec=0, bool fill_or_kill=false, bool broadcast=false)
Definition: wallet_transfer.cpp:192
graphene
Definition: api.cpp:48
graphene::protocol::htlc_create_operation::claim_period_seconds
uint32_t claim_period_seconds
Definition: htlc.hpp:65