0

I'm having compilation issues when creating a custom dispatcher. I'm getting issues when calling EOSIO_DISPATCH. Is it related to changes in new CDT?

class [[eosio::contract("mycontract")]] mycontract : public contract {
...
};

extern "C" {
void apply(uint64_t receiver, uint64_t code, uint64_t action) {
    myContract thiscontract(name(receiver));

    if (((code == name("eosio.token").value) &&
        (action == name("transfer").value)) {
        execute_action(name(receiver), name(code) &myContract::transfer);
        return;
    }

    if (code != receiver) return;

      switch (action) { EOSIO_DISPATCH(myContract, (transfer)(receipt))
    }

    eosio_exit(0);
}
}

Errors and warnings I am getting:

warning: parentheses were disambiguated as a function
  declaration [-Wvexing-parse]
mycontract thiscontract(name(receiver));
                         ^~~~~~~~~~~~~~~~
 note: add a pair of parentheses to declare a variable
mycontract thiscontract(name(receiver));
                          ^
                          (             )
warning: 'thiscontract' has C-linkage specified, but
  returns user-defined type 'mycontract' which is incompatible with C
  [-Wreturn-type-c-linkage]
mycontract thiscontract(name(receiver));
             ^
error: call to non-static member function without an
  object argument
    execute_action(name(receiver), name(code) &mycontract::transfer);
                                               ~~~~~~~~~~~~~~^~~~~~~~
error: expected unqualified-id
  switch (action) { EOSIO_DISPATCH(mycontract, (transfer)(receipt)...
                    ^

/usr/local/Cellar/eosio.cdt/1.5.0/opt/eosio.cdt/bin/../include/eosiolib/dispatcher.hpp:117:8: note: expanded from macro 'EOSIO_DISPATCH' extern "C" { \

1

Some points:

  1. As mentioned in the other post myContract should be lowercase mycontract.
  2. The eosio::contract constructor changed since eosio.cdt 1.3. It takes 3 arguments now: mycontract(eosio::name receiver, eosio::name code, eosio::datastream<const char *> ds) : contract(receiver, code, ds) {}. Not sure if your mycontract already implements this as I can't see it from the code.
  3. A custom dispatcher for mycontract could be written like this:
extern "C" {
void apply(uint64_t receiver, uint64_t code, uint64_t action) {
  if (code == "eosio.token"_n.value && action == "transfer"_n.value) {
    eosio::execute_action(eosio::name(receiver), eosio::name(code),
                          &mycontract::transfer);
  } else if (code == receiver) {
    switch (action) { EOSIO_DISPATCH_HELPER(mycontract, (transfer)(receipt)) }
  }
  eosio_exit(0);
}
}

As a side note: You're allowing the transfer action to be called directly on your contract because you add it to EOSIO_DISPATCH_HELPER again. I'm not sure if that's intended. One could call it without doing an actual eosio.token::transfer.

|improve this answer|||||
0
  1. Your EOSIO_DISPATCH should be called EOSIO_DISPATCH_HELPER. Otherwise you are doing some kind of crazy recursive calling of the apply function.
  2. There seems to be some confusion between mycontract and myContract.
  3. You don't use thiscontract anywhere, so remove it.
|improve this answer|||||
0

Thanks for the other two posts and here is my complete code:

#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/asset.hpp>
#include <eosiolib/action.hpp>

using namespace eosio;
using namespace std;

class [[eosio::contract("mycontract")]] mycontract: public eosio::contract {
  public:
    using contract::contract;

    [[eosio::action]]
    void transfer(name from, name to, asset quantity, string memo) {
        /*if (to != _self) {
            return;
        }*/
        print("a transfer in mycontract:", name{ from }, ",", name{ to });
    }

};

extern "C" { 
    void apply( uint64_t receiver, uint64_t code, uint64_t action ) { 
        if((code == "eosio.token"_n.value && action == "transfer"_n.value) ) { 

                eosio::execute_action(eosio::name(receiver), eosio::name(code), &mycintract::transfer);

           }else if(code == receiver){

                switch( action ) { 
                    EOSIO_DISPATCH_HELPER( mycontract, (transfer) ) 
                } 
            eosio_exit(0);
        } 

    } 
} 

Here I only implement the transfer function, for an example. If you also need to add receipt function or other functions. You should do it like what transfer function do. I hope it can be helpful.

|improve this answer|||||

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.