I have an apply function that listeners for transfers to my contract from eosio.token. On notification of a transfer, a function (buy) is called within the contract. How do I ensure that this "buy" function cannot be called manually, by faking the transfer strut? I am concerned it is possible to supply a false ".from=eosio.token", when no tokens were actually transferred.
There are two ways that you can prevent this:
- You remove the
buy
function from the ABI, it can therefore never be called manually, but only through another function that is part of the ABI. - You restrict access to the
buy
function to only be accessible by the contract itself, usingrequire_auth(_self)
.
Ideally do both, as you can never be too safe...
The problem isn't the "buy" (you can just leave that out of the ABI), it is calling "transfer" directly - not by way of eosio.token. The "transfer" function must be part of the the ABI macro or it won't accept require_recipient calls from eosio.token - I just verified this to be sure.
So then the question I believe you are asking is how to I check that the require_recipient carbon copy actually came from eosio.token. I believe the answer is to check as follows:
require_auth(from);
require_auth2(N(eosio.token), N(eosio.code));
Also some discussion of this here worth reading: