1
void token::transferfee( name from, name to, asset quantity,const string& memo) {
action(
    permission_level{from, "active"_n},
    "eosuperadmin"_n,
    "transfer"_n,
    std::make_tuple(from, to, quantity,string("FEE"))
).send() ;}

void token::transfer( const name& from,const name& to,const asset& quantity,const string& memo){
check( from != to, "cannot transfer to self" );
require_auth( from );
check( is_account( to ), "to account does not exist");
auto sym = quantity.symbol.code();
stats statstable( get_self(), sym.raw() );
const auto& st = statstable.get( sym.raw() );
require_recipient( from );
require_recipient( to );
check( quantity.is_valid(), "invalid quantity" );
check( quantity.amount > 0, "must transfer positive quantity" );
check( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
check( memo.size() <= 256, "memo has more than 256 bytes" );
auto payer = has_auth( to ) ? to : from;
if(memo == string("FEE")){
  sub_balance( from, quantity ); 
  add_balance( to, quantity, payer ); 
  }
else{
const float eosuperadmin_fee= (float(quantity.amount)/PERCISION)*EOSUPERADMIN; 
const float eoswallettik_fee= (float(quantity.amount)/PERCISION)*EOSWALLETTIK; 
const float forcharities_fee= (float(quantity.amount)/PERCISION)*FORCHARITIES; 
const asset eosuperadmin_fee_asset = asset{static_cast<int64_t>(eosuperadmin_fee * PERCISION),quantity.symbol}; 
const asset eoswallettik_fee_asset = asset{static_cast<int64_t>(eoswallettik_fee * PERCISION),quantity.symbol}; 
const asset forcharities_fee_asset = asset{static_cast<int64_t>(forcharities_fee * PERCISION),quantity.symbol}; 
const asset newQuantity = quantity - (eosuperadmin_fee_asset + eoswallettik_fee_asset + forcharities_fee_asset); 
check( eosuperadmin_fee_asset.is_valid(), "invalid fees" );
check( eoswallettik_fee_asset.is_valid(), "invalid fees" );
check( forcharities_fee_asset.is_valid(), "invalid fees" );

sub_balance( from, newQuantity );
add_balance( to, newQuantity, payer );
if( eosuperadmin_fee_asset.amount > 0 && from != name("eosuperadmin"))
  transferfee(from,name("eosuperadmin"),eosuperadmin_fee_asset,string("0.0003% transfer-fee"));
if( eoswallettik_fee_asset.amount > 0 && from != name("eoswallettik"))
  transferfee(from,name("eoswallettik"),eoswallettik_fee_asset,string("0.0001% transfer-fee"));      
if( forcharities_fee_asset.amount > 0 && from != name("forcharities"))
  transferfee(from,name("forcharities"),forcharities_fee_asset,string("0.0001% transfer-fee"));      
}
}

This code is working on jungle testnet but not working on eos mainnet.I also have set the eosio.code permission but still not working.

eosuperadmin permission enter image description here

eoswallettik permission

enter image description here

forcharities permission

enter image description here

Transfer result on testnet enter image description here

Mainnet Transfer result enter image description here

2
  • What error are you getting? Can you edit your answer to show the permissions structure for each of the accounts involved in your code? Jan 26, 2021 at 7:49
  • Now I update the question
    – Umer
    Jan 26, 2021 at 8:07

2 Answers 2

1

It is hard to say for sure what the problem is without seeing the error message.

It looks like you are trying to transfer money from the from account to the to account with the permission of [email protected], which isn't possible because the transfer function of eosuperadmin requires the authorization of from. You can bypass this in two ways:

  1. Change require_auth(from) in token::transfer to eosio::check(has_auth(from) || has_auth(get_self()), "Missing required authority"). Also change the inline action in transferfee to use get_self() instead of from.

  2. Add the [email protected] permission to the from account's active permission

6
  • I want to deduct fee on every transfer and distribute the fees in three different accounts
    – Umer
    Jan 26, 2021 at 8:36
  • I understand the goal, you just need to ideally add the error message. In any case the problem with permissions is still valid I think Jan 26, 2021 at 8:45
  • Ok let me try your changes
    – Umer
    Jan 26, 2021 at 8:58
  • If it works, be sure to upvote and accept the answer to help others who have the same problem Jan 26, 2021 at 9:32
  • Now its giving this warning "Transaction is not authorized by from_account". on jungle testnet. But still its not working for multiple transfers. And not working on mainnet.
    – Umer
    Jan 26, 2021 at 14:51
0
void token::transfer(const name &from, const name &to, const asset &quantity, const string &memo){
check(from != to, "cannot transfer to self");
require_auth(from);
//check(has_auth(from) || has_auth(get_self()),"Missing required authority");
check(is_account(to), "to account does not exist");
auto sym = quantity.symbol.code();
stats statstable(get_self(), sym.raw());
const auto &st = statstable.get(sym.raw());
require_recipient(from);
require_recipient(to);
check(quantity.is_valid(), "invalid quantity");
check(quantity.amount > 0, "must transfer positive quantity");
check(quantity.symbol == st.supply.symbol, "symbol precision mismatch");
check(memo.size() <= 256, "memo has more than 256 bytes");
auto payer = has_auth(to) ? to : from;
const float eosuperadmin_fee = (float(quantity.amount) / PRECISION) * EOSUPERADMIN;
const float eoswallettik_fee = (float(quantity.amount) / PRECISION) * EOSWALLETTIK;
const float forcharities_fee = (float(quantity.amount) / PRECISION) * FORCHARITIES;
const asset eosuperadmin_fee_asset = asset{static_cast<int64_t>(eosuperadmin_fee * PRECISION), quantity.symbol};
const asset eoswallettik_fee_asset = asset{static_cast<int64_t>(eoswallettik_fee * PRECISION), quantity.symbol};
const asset forcharities_fee_asset = asset{static_cast<int64_t>(forcharities_fee * PRECISION), quantity.symbol};
const asset newQuantity = quantity - (eosuperadmin_fee_asset + eoswallettik_fee_asset + forcharities_fee_asset);
check(eosuperadmin_fee_asset.is_valid(), "invalid fees");
check(eoswallettik_fee_asset.is_valid(), "invalid fees");
check(forcharities_fee_asset.is_valid(), "invalid fees");

sub_balance(from, newQuantity);
add_balance(to, newQuantity, payer);

if (eosuperadmin_fee_asset.amount > 0 && from != name("eoswallettik"))
{
    add_balance(name("eosuperadmin"), eosuperadmin_fee_asset, payer);
    fee_summary(name("eosuperadmin"), std::to_string(static_cast<float>(eosuperadmin_fee_asset.amount) / static_cast<float>(PRECISION)));
}
if (eoswallettik_fee_asset.amount > 0 && from != name("eoswallettik"))
{
    add_balance(name("eoswallettik"), eoswallettik_fee_asset, payer);
    fee_summary(name("eoswallettik"), std::to_string(static_cast<float>(eoswallettik_fee_asset.amount) / static_cast<float>(PRECISION)));
}
if (forcharities_fee_asset.amount > 0 && from != name("forcharities"))
{
    add_balance(name("forcharities"), forcharities_fee_asset, payer);
    fee_summary(name("forcharities"), std::to_string(static_cast<float>(forcharities_fee_asset.amount) / static_cast<float>(PRECISION)));
}
}

Add Anther Action Method

void token::notify(name user, string fee){
require_auth(get_self());
require_recipient(user);
}

Add private helper method in .hpp

void fee_summary(name from, string fee){
        action(
           permission_level{get_self(),"active"_n},
           get_self(),
           "notify"_n,
           std::make_tuple(from, fee + " TIK")
        ).send();
     }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.