void transaction_evaluation_state::evaluate_create_asset( const create_asset_operation& op ) { try { auto cur_record = _current_state->get_asset_record( op.symbol ); if( cur_record ) fail( BTS_ASSET_ALREADY_REGISTERED, fc::variant(op) ); auto issuer_name_record = _current_state->get_name_record( op.issuer_name_id ); if( !issuer_name_record ) fail( BTS_INVALID_NAME_ID, fc::variant(op) ); add_required_signature(issuer_name_record->active_key); sub_balance( balance_id_type(), asset(_current_state->get_asset_registration_fee() , 0) ); // TODO: verify that the json_data is properly formatted asset_record new_record; new_record.id = _current_state->new_asset_id(); new_record.symbol = op.symbol; new_record.name = op.name; new_record.description = op.description; new_record.json_data = op.json_data; new_record.issuer_name_id = op.issuer_name_id; new_record.current_share_supply = 0; new_record.maximum_share_supply = op.maximum_share_supply; new_record.collected_fees = 0; new_record.registration_date = _current_state->now(); _current_state->store_asset_record( new_record ); } FC_RETHROW_EXCEPTIONS( warn, "", ("op",op) ) }
void transaction_evaluation_state::evaluate_reserve_name( const reserve_name_operation& op ) { try { FC_ASSERT( name_record::is_valid_name( op.name ) ); FC_ASSERT( name_record::is_valid_json( op.json_data ) ); FC_ASSERT( op.json_data.size() < BTS_BLOCKCHAIN_MAX_NAME_DATA_SIZE ); auto cur_record = _current_state->get_name_record( op.name ); if( cur_record && ((fc::time_point(cur_record->last_update) + one_year) > fc::time_point(_current_state->now())) ) fail( BTS_NAME_ALREADY_REGISTERED, fc::variant(op) ); name_record new_record; new_record.id = _current_state->new_name_id(); new_record.name = op.name; new_record.json_data = op.json_data; new_record.owner_key = op.owner_key; new_record.active_key = op.active_key; new_record.last_update = _current_state->now(); new_record.registration_date = _current_state->now(); new_record.delegate_info = delegate_stats(); cur_record = _current_state->get_name_record( new_record.id ); FC_ASSERT( !cur_record ); if( op.is_delegate ) { // pay fee sub_balance( balance_id_type(), asset(_current_state->get_delegate_registration_fee()) ); } _current_state->store_name_record( new_record ); } FC_RETHROW_EXCEPTIONS( warn, "", ("op",op) ) }
/** * Process all fees and update the asset records. */ void transaction_evaluation_state::post_evaluate() { try { for( const auto& item : withdraws ) { auto asset_rec = _current_state->get_asset_record( item.first ); if( !asset_rec.valid() ) FC_CAPTURE_AND_THROW( unknown_asset_id, (item) ); if( asset_rec->id > 0 && asset_rec->is_market_issued() && asset_rec->transaction_fee > 0 ) { sub_balance( address(), asset(asset_rec->transaction_fee, asset_rec->id) ); } } balance[0]; // make sure we have something for this. for( const auto& fee : balance ) { if( fee.second < 0 ) FC_CAPTURE_AND_THROW( negative_fee, (fee) ); // if the fee is already in XTS or the fee balance is zero, move along... if( fee.first == 0 || fee.second == 0 ) continue; auto asset_record = _current_state->get_asset_record( fee.first ); if( !asset_record.valid() ) FC_CAPTURE_AND_THROW( unknown_asset_id, (fee.first) ); if( !asset_record->is_market_issued() ) continue; // lowest ask is someone with XTS offered at a price of USD / XTS, fee.first // is an amount of USD which can be converted to price*USD XTS provided we // send lowest_ask.index.owner the USD oprice median_price = _current_state->get_median_delegate_price( fee.first, asset_id_type( 0 ) ); if( median_price ) { // fees paid in something other than XTS are discounted 50% alt_fees_paid += asset( (fee.second*2)/3, fee.first ) * *median_price; } } for( const auto& fee : balance ) { if( fee.second < 0 ) FC_CAPTURE_AND_THROW( negative_fee, (fee) ); if( fee.second > 0 ) // if a fee was paid... { auto asset_record = _current_state->get_asset_record( fee.first ); if( !asset_record ) FC_CAPTURE_AND_THROW( unknown_asset_id, (fee.first) ); asset_record->collected_fees += fee.second; _current_state->store_asset_record( *asset_record ); } } } FC_RETHROW_EXCEPTIONS( warn, "" ) }
void transaction_evaluation_state::evaluate_deposit( const deposit_operation& op ) { try { auto deposit_balance_id = op.balance_id(); auto delegate_record = _current_state->get_name_record( op.condition.delegate_id ); if( !delegate_record ) fail( BTS_INVALID_NAME_ID, fc::variant(op) ); if( !delegate_record->is_delegate() ) fail( BTS_INVALID_DELEGATE_ID, fc::variant(op) ); auto cur_record = _current_state->get_balance_record( deposit_balance_id ); if( !cur_record ) { cur_record = balance_record( op.condition ); } cur_record->last_update = _current_state->now(); cur_record->balance += op.amount; sub_balance( deposit_balance_id, asset(op.amount, cur_record->condition.asset_id) ); if( cur_record->condition.asset_id == 0 ) add_vote( cur_record->condition.delegate_id, op.amount ); _current_state->store_balance_record( *cur_record ); } FC_RETHROW_EXCEPTIONS( warn, "", ("op",op) ) }
void token::transfer( account_name from, account_name to, asset quantity, string memo ) { eosio_assert( from != to, "cannot transfer to self" ); require_auth( from ); eosio_assert( is_account( to ), "to account does not exist"); auto sym = quantity.symbol.name(); stats statstable( _self, sym ); const auto& st = statstable.get( sym ); require_recipient( from ); require_recipient( to ); eosio_assert( quantity.is_valid(), "invalid quantity" ); eosio_assert( quantity.amount > 0, "must transfer positive quantity" ); eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" ); sub_balance( from, quantity ); add_balance( to, quantity, from ); }