BitShares-Core  4.0.0
BitShares blockchain implementation and command-line interface 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.id;
61  account_id_type to_id = to_account.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( string source, string destination, string amount,
87  string asset_symbol, string hash_algorithm, const std::string& preimage_hash, uint32_t preimage_size,
88  const uint32_t claim_period_seconds, const std::string& memo, bool broadcast )
89  {
90  try
91  {
92  FC_ASSERT( !self.is_locked() );
93  fc::optional<asset_object> asset_obj = get_asset(asset_symbol);
94  FC_ASSERT(asset_obj, "Could not find asset matching ${asset}", ("asset", asset_symbol));
95 
96  const account_object& from_acct = get_account(source);
97  const account_object& to_acct = get_account(destination);
98  htlc_create_operation create_op;
99  create_op.from = get_account(source).id;
100  create_op.to = get_account(destination).id;
101  create_op.amount = asset_obj->amount_from_string(amount);
102  create_op.claim_period_seconds = claim_period_seconds;
103  create_op.preimage_hash = do_hash( hash_algorithm, preimage_hash );
104  create_op.preimage_size = preimage_size;
105  if (!memo.empty())
106  {
107  memo_data data;
108  data.from = from_acct.options.memo_key;
109  data.to = to_acct.options.memo_key;
110  data.set_message(
111  get_private_key(from_acct.options.memo_key), to_acct.options.memo_key, memo);
112  create_op.extensions.value.memo = data;
113  }
114 
116  tx.operations.push_back(create_op);
117  set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees());
118  tx.validate();
119 
120  return sign_transaction(tx, broadcast);
121  } FC_CAPTURE_AND_RETHROW( (source)(destination)(amount)(asset_symbol)(hash_algorithm)
122  (preimage_hash)(preimage_size)(claim_period_seconds)(broadcast) )
123  }
124 
125  signed_transaction wallet_api_impl::htlc_redeem( string htlc_id, string issuer,
126  const std::vector<char>& preimage, bool broadcast )
127  {
128  try
129  {
130  FC_ASSERT( !self.is_locked() );
131  fc::optional<htlc_object> htlc_obj = get_htlc(htlc_id);
132  FC_ASSERT(htlc_obj, "Could not find HTLC matching ${htlc}", ("htlc", htlc_id));
133 
134  account_object issuer_obj = get_account(issuer);
135 
136  htlc_redeem_operation update_op;
137  update_op.htlc_id = htlc_obj->id;
138  update_op.redeemer = issuer_obj.id;
139  update_op.preimage = preimage;
140 
142  tx.operations.push_back(update_op);
143  set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees());
144  tx.validate();
145 
146  return sign_transaction(tx, broadcast);
147  } FC_CAPTURE_AND_RETHROW( (htlc_id)(issuer)(preimage)(broadcast) )
148  }
149 
150  signed_transaction wallet_api_impl::htlc_extend ( string htlc_id, string issuer, const uint32_t seconds_to_add,
151  bool broadcast)
152  {
153  try
154  {
155  FC_ASSERT( !self.is_locked() );
156  fc::optional<htlc_object> htlc_obj = get_htlc(htlc_id);
157  FC_ASSERT(htlc_obj, "Could not find HTLC matching ${htlc}", ("htlc", htlc_id));
158 
159  account_object issuer_obj = get_account(issuer);
160 
161  htlc_extend_operation update_op;
162  update_op.htlc_id = htlc_obj->id;
163  update_op.update_issuer = issuer_obj.id;
164  update_op.seconds_to_add = seconds_to_add;
165 
167  tx.operations.push_back(update_op);
168  set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees());
169  tx.validate();
170 
171  return sign_transaction(tx, broadcast);
172  } FC_CAPTURE_AND_RETHROW( (htlc_id)(issuer)(seconds_to_add)(broadcast) )
173  }
174 
176  {
177  htlc_id_type id;
178  fc::from_variant(htlc_id, id);
179  auto obj = _remote_db->get_objects( { id }, {}).front();
180  if ( !obj.is_null() )
181  {
182  return fc::optional<htlc_object>(obj.template as<htlc_object>(GRAPHENE_MAX_NESTED_OBJECTS));
183  }
184  return fc::optional<htlc_object>();
185  }
186 
187  signed_transaction wallet_api_impl::sell_asset(string seller_account, string amount_to_sell,
188  string symbol_to_sell, string min_to_receive, string symbol_to_receive,
189  uint32_t timeout_sec, bool fill_or_kill, bool broadcast )
190  {
191  account_object seller = get_account( seller_account );
192 
194  op.seller = seller.id;
195  op.amount_to_sell = get_asset(symbol_to_sell).amount_from_string(amount_to_sell);
196  op.min_to_receive = get_asset(symbol_to_receive).amount_from_string(min_to_receive);
197  if( timeout_sec )
198  op.expiration = fc::time_point::now() + fc::seconds(timeout_sec);
199  op.fill_or_kill = fill_or_kill;
200 
202  tx.operations.push_back(op);
203  set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees());
204  tx.validate();
205 
206  return sign_transaction( tx, broadcast );
207  }
208 
209  signed_transaction wallet_api_impl::borrow_asset(string seller_name, string amount_to_borrow,
210  string asset_symbol, string amount_of_collateral, bool broadcast )
211  {
212  account_object seller = get_account(seller_name);
213  asset_object mia = get_asset(asset_symbol);
215  asset_object 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 
222  signed_transaction trx;
223  trx.operations = {op};
224  set_operation_fees( trx, _remote_db->get_global_properties().parameters.get_current_fees());
225  trx.validate();
226 
227  return sign_transaction(trx, broadcast);
228  }
229 
230  signed_transaction wallet_api_impl::borrow_asset_ext( string seller_name, string amount_to_borrow,
231  string asset_symbol, string amount_of_collateral,
232  call_order_update_operation::extensions_type extensions, bool broadcast )
233  {
234  account_object seller = get_account(seller_name);
235  asset_object mia = get_asset(asset_symbol);
237  asset_object collateral = get_asset(get_object(*mia.bitasset_data_id).options.short_backing_asset);
238 
240  op.funding_account = seller.id;
241  op.delta_debt = mia.amount_from_string(amount_to_borrow);
242  op.delta_collateral = collateral.amount_from_string(amount_of_collateral);
243  op.extensions = extensions;
244 
245  signed_transaction trx;
246  trx.operations = {op};
247  set_operation_fees( trx, _remote_db->get_global_properties().parameters.get_current_fees());
248  trx.validate();
249 
250  return sign_transaction(trx, broadcast);
251  }
252 
253  signed_transaction wallet_api_impl::cancel_order(limit_order_id_type order_id, bool broadcast )
254  { try {
255  FC_ASSERT(!is_locked());
256  signed_transaction trx;
257 
259  op.fee_paying_account = get_object(order_id).seller;
260  op.order = order_id;
261  trx.operations = {op};
262  set_operation_fees( trx, _remote_db->get_global_properties().parameters.get_current_fees());
263 
264  trx.validate();
265  return sign_transaction(trx, broadcast);
266  } FC_CAPTURE_AND_RETHROW((order_id)) }
267 
268  signed_transaction wallet_api_impl::withdraw_vesting( string witness_name, string amount, string asset_symbol,
269  bool broadcast )
270  { try {
271  asset_object asset_obj = get_asset( asset_symbol );
272  fc::optional<vesting_balance_id_type> vbid = maybe_id<vesting_balance_id_type>(witness_name);
273  if( !vbid )
274  {
275  witness_object wit = get_witness( witness_name );
276  FC_ASSERT( wit.pay_vb );
277  vbid = wit.pay_vb;
278  }
279 
280  vesting_balance_object vbo = get_object( *vbid );
281  vesting_balance_withdraw_operation vesting_balance_withdraw_op;
282 
283  vesting_balance_withdraw_op.vesting_balance = *vbid;
284  vesting_balance_withdraw_op.owner = vbo.owner;
285  vesting_balance_withdraw_op.amount = asset_obj.amount_from_string(amount);
286 
288  tx.operations.push_back( vesting_balance_withdraw_op );
289  set_operation_fees( tx, _remote_db->get_global_properties().parameters.get_current_fees() );
290  tx.validate();
291 
292  return sign_transaction( tx, broadcast );
293  } FC_CAPTURE_AND_RETHROW( (witness_name)(amount) )
294  }
295 
296 }}} // namespace graphene::wallet::detail
bool fill_or_kill
If this flag is set the entire order must be filled or the operation is rejected. ...
Definition: market.hpp:62
vector< operation > operations
Definition: transaction.hpp:89
#define GRAPHENE_MAX_NESTED_OBJECTS
Definition: config.hpp:31
virtual void validate() const
Definition: transaction.cpp:58
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)
This class represents an account on the object graphAccounts are the primary unit of authority on the...
account_id_type owner
Must be vesting_balance.owner.
Definition: vesting.hpp:107
Definition: api.cpp:56
signed_transaction htlc_redeem(string htlc_id, string issuer, const std::vector< char > &preimage, bool broadcast)
signed_transaction transfer(string from, string to, string amount, string asset_symbol, string memo, bool broadcast=false)
signed_transaction withdraw_vesting(string witness_name, string amount, string asset_symbol, bool broadcast=false)
signed_transaction cancel_order(limit_order_id_type order_id, bool broadcast=false)
account_object get_account(account_id_type id) const
asset amount_from_string(string amount_string) const
optional< vesting_balance_id_type > pay_vb
const auto source
asset delta_collateral
the amount of collateral to add to the margin position
Definition: market.hpp:126
account_id_type funding_account
pays fee, collateral, and cover
Definition: market.hpp:125
provides stack-based nullable value similar to boost::optional
Definition: optional.hpp:20
extension< additional_options_type > extensions
Definition: htlc.hpp:72
public_key_type to
Definition: memo.hpp:43
fc::optional< htlc_object > get_htlc(string htlc_id) const
Transfers an amount of one asset from one account to another.
Definition: transfer.hpp:45
object_id_type id
Definition: object.hpp:73
signed_transaction borrow_asset(string seller_name, string amount_to_borrow, string asset_symbol, string amount_of_collateral, bool broadcast=false)
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)
microseconds seconds(int64_t s)
Definition: time.hpp:34
signed_transaction sign_transaction(signed_transaction tx, bool broadcast=false)
signed_transaction htlc_extend(string htlc_id, string issuer, const uint32_t seconds_to_add, bool broadcast)
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:478
instructs the blockchain to attempt to sell one asset for anotherThe blockchain will atempt to sell a...
Definition: market.hpp:48
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
adds a signature to a transaction
fc::ecc::private_key get_private_key(const public_key_type &id) const
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
Definition: exception.hpp:378
signed_transaction htlc_create(string source, string destination, string amount, string asset_symbol, string hash_algorithm, const std::string &preimage_hash, uint32_t preimage_size, const uint32_t claim_period_seconds, const std::string &memo, bool broadcast=false)
optional< memo_data > memo
User provided data encrypted to the memo key of the "to" account.
Definition: transfer.hpp:61
Withdraw from a vesting balance.Withdrawal from a not-completely-mature vesting balance will result i...
Definition: vesting.hpp:101
witness_object get_witness(string owner_account)
tracks the parameters of an assetAll assets have a globally unique symbol name that controls how they...
typename impl::transform< List, Transformer >::type transform
Transform elements of a typelist.
Definition: typelist.hpp:170
asset amount
The amount of asset to transfer from from to to.
Definition: transfer.hpp:58
void from_variant(const variant &var, flat_set< T, A... > &vo, uint32_t _max_depth)
Definition: flat.hpp:116
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
asset delta_debt
the amount of the debt to be paid off, may be negative to issue new debt
Definition: market.hpp:127
graphene::db::object_downcast_t< ID > get_object(ID id) const
account_id_type from
Account to transfer asset from.
Definition: transfer.hpp:54
extended_asset_object get_asset(asset_id_type id) const
public_key_type from
Definition: memo.hpp:42
static time_point now()
Definition: time.cpp:13
optional< asset_bitasset_data_id_type > bitasset_data_id
Extra data associated with BitAssets. This field is non-null if and only if is_market_issued() return...
void set_operation_fees(signed_transaction &tx, const fee_schedule &s)
account_id_type to
Account to transfer asset to.
Definition: transfer.hpp:56
defines the keys used to derive the shared secret
Definition: memo.hpp:40
account_id_type owner
Account which owns and may withdraw from this vesting balance.