void token::transferfee( name from, name to, asset quantity,const string& memo) {
    permission_level{from, "active"_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 ); 
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

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

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 eosuperadmin@eosio.code, 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 eosuperadmin@eosio.code permission to the from account's active permission

  • I want to deduct fee on every transfer and distribute the fees in three different accounts – Umer Jan 26 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 – Phillip Hamnett - EOS42 Jan 26 at 8:45
  • Ok let me try your changes – Umer Jan 26 at 8:58
  • If it works, be sure to upvote and accept the answer to help others who have the same problem – Phillip Hamnett - EOS42 Jan 26 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 at 14:51
void token::transfer(const name &from, const name &to, const asset &quantity, const string &memo){
check(from != to, "cannot transfer to self");
//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());
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){

Add private helper method in .hpp

void fee_summary(name from, string fee){
           std::make_tuple(from, fee + " TIK")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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