11

The EOSIO_ABI macro seems to only forward actions meant for our contract. How do you also listen to all other contract actions (like the very common transfer action for the account "eosio.token")?

I tried not using the EOSIO_ABI macro and just use the C code, but then the .abi generation doesn't work anymore. So what's the best implementation to listen to all actions for all contracts while still being able to use the eosio toolset (which includes .abi creation)?

EDIT: I just talked to Daniel Larimer himself on Telegram and adding a better way to handle actions for other contracts is planned after june. Right now apparently it can only be done by sacrificing auto generation for .abi files with the eosiocpp toolset.

2 Answers 2

8

Extend EOSIO_ABI macro to handle eosio.token transfer notification. Please pay attention to if statements:


if( code == self || **code == N(eosio.token)** || action == N(onerror) )  
DO NOT USE THIS CODE ABOVE ANYMORE, OR YOU WILL BE ATTACKED! 
if( ((code == self  && action != N(transfer) ) || (code == N(eosio.token) && action == N(transfer)) || action == N(onerror)) )
// extend from EOSIO_ABI
#define EOSIO_ABI_EX( TYPE, MEMBERS ) \
extern "C" { \
   void apply( uint64_t receiver, uint64_t code, uint64_t action ) { \
      auto self = receiver; \
      if( action == N(onerror)) { \
         /* onerror is only valid if it is for the "eosio" code account and authorized by "eosio"'s "active permission */ \
         eosio_assert(code == N(eosio), "onerror action's are only valid from the \"eosio\" system account"); \
      } \
      if( ((code == self && action != N(transfer)) || (code == N(eosio.token) && action == N(transfer)) || action == N(onerror)) ) { \
         TYPE thiscontract( self ); \
         switch( action ) { \
            EOSIO_API( TYPE, MEMBERS ) \
         } \
         /* does not allow destructor of thiscontract to run: eosio_exit(0); */ \
      } \
   } \
}

EOSIO_ABI_EX(eosio::charity, (hi)(transfer))
9
  • still the same problem (the .abi file has no actions after using eoscpp to generate it). Does it work for you? Where do I have to put that macro? Do I need to use a .hpp file or should it work with just a .cpp file?
    – PunchPlump
    May 23, 2018 at 9:43
  • you should add a structure same name with action function and put annotation //@abi action before it. // @abi action struct hi { account_name user; };
    – ofo
    May 23, 2018 at 10:30
  • .hpp/.cpp are the same.
    – ofo
    May 23, 2018 at 10:31
  • Yes they were already in place. Just when I replace the normal EOSIO_ABI macro with your implementation (or any other implementation of the pure C code), the .abi doesn't contain actions anymore after creating it with eosiocpp, so I get errors when pushing the actions to the blockchain. Did you test the macro and does it keep your other actions operational?
    – PunchPlump
    May 23, 2018 at 17:59
  • 3
    maybe many contracts use your code, and be attacked
    – Jimmy Guo
    Sep 14, 2018 at 8:21
4

The solution is to redefine EOSIO_ABI macro. @ofo's solution is correct for the code generation part but to make auto abi generation work EOSIO_ABI macro has to be used. To do this you first undefine macro and than define it again:

#undef EOSIO_ABI

#define EOSIO_ABI(TYPE, MEMBERS) \ ....

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.