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
buyfunction 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
buyfunction to only be accessible by the contract itself, using
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: