void token::issue( account_name to, asset quantity, string memo ) { auto sym = quantity.symbol; eosio_assert( sym.is_valid(), "invalid symbol name" ); eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" ); auto sym_name = sym.name(); stats statstable( _self, sym_name ); auto existing = statstable.find( sym_name ); eosio_assert( existing != statstable.end(), "token with symbol does not exist, create token before issue" ); const auto& st = *existing; require_auth( st.issuer ); eosio_assert( quantity.is_valid(), "invalid quantity" ); eosio_assert( quantity.amount > 0, "must issue positive quantity" ); eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); eosio_assert( quantity.amount <= st.max_supply.amount - st.supply.amount, "quantity exceeds available supply"); statstable.modify( st, 0, [&]( auto& s ) { s.supply += quantity; }); add_balance( st.issuer, quantity, st.issuer ); if( to != st.issuer ) { SEND_INLINE_ACTION( *this, transfer, {st.issuer,N(active)}, {st.issuer, to, quantity, memo} ); } }
void transaction_evaluation_state::evaluate_issue_asset( const issue_asset_operation& op ) { try { auto cur_record = _current_state->get_asset_record( op.asset_id ); if( !cur_record ) fail( BTS_INVALID_ASSET_ID, fc::variant(op) ); auto issuer_name_record = _current_state->get_name_record( cur_record->issuer_name_id ); if( !issuer_name_record ) fail( BTS_INVALID_NAME_ID, fc::variant(op) ); add_required_signature( issuer_name_record->active_key ); if( cur_record->available_shares() < op.amount ) fail( BTS_INSUFFICIENT_FUNDS, fc::variant(op) ); cur_record->current_share_supply += op.amount; add_balance( asset(op.amount, op.asset_id) ); _current_state->store_asset_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 ); }
void transaction_evaluation_state::evaluate_withdraw( const withdraw_operation& op ) { try { obalance_record arec = _current_state->get_balance_record( op.balance_id ); if( !arec ) fail( BTS_UNDEFINED_ADDRESS, fc::variant(op) ); switch( (withdraw_condition_types)arec->condition.condition ) { case withdraw_signature_type: { add_required_signature( arec->condition.as<withdraw_with_signature>().owner ); break; } case withdraw_multi_sig_type: { auto multi_sig = arec->condition.as<withdraw_with_multi_sig>(); uint32_t valid_signatures = 0; for( auto sig : multi_sig.owners ) valid_signatures += check_signature( sig ); if( valid_signatures < multi_sig.required ) fail( BTS_MISSING_SIGNATURE, fc::variant(op) ); break; } case withdraw_password_type: { auto pass = arec->condition.as<withdraw_with_password>(); uint32_t count = 0; count += check_signature( pass.payor ); count += check_signature( pass.payee ); if( count < 2 && op.claim_input_data.size() ) count += pass.password_hash == fc::ripemd160::hash( op.claim_input_data.data(), op.claim_input_data.size() ); if( count != 2 ) fail( BTS_MISSING_SIGNATURE, fc::variant(op) ); break; } case withdraw_option_type: { auto option = arec->condition.as<withdraw_option>(); if( _current_state->now() > option.date ) { add_required_signature( option.optionor ); } else // the option hasn't expired { add_required_signature( option.optionee ); auto pay_amount = asset( op.amount, arec->condition.asset_id ) * option.strike_price; add_required_deposit( option.optionee, pay_amount ); } break; } default: fail( BTS_INVALID_WITHDRAW_CONDITION, fc::variant(op) ); } // update delegate vote on withdrawn account.. arec->balance -= op.amount; arec->last_update = _current_state->now(); add_balance( asset(op.amount, arec->condition.asset_id) ); if( arec->condition.asset_id == 0 ) sub_vote( arec->condition.delegate_id, op.amount ); wlog( "store after withdraw ${r}", ("r",*arec) ); _current_state->store_balance_record( *arec ); } FC_RETHROW_EXCEPTIONS( warn, "", ("op",op) ) }