1

I'm using the following contract on both my local and jungle testnets, the on_notify methods are not being fired. Everything appears to be in order, I'm hoping I've missed something obvious.

I created the table so that I can track whether the on_notify are firing on the jungle testnet.

#include <eosio/eosio.hpp>
#include <eosio/asset.hpp>

using namespace eosio;

class [[eosio::contract]] notifytest : public contract {
   public:
      using contract::contract;

      [[eosio::action]] 
      void addstat(name account, std::string action_text) {
          print("Adding Stat: ", name(account), " Action: ", action_text, "\n");
          add_stat(account, action_text);
      }

      [[eosio::on_notify("eosio.token::transfer")]] 
      void on_transfer(name from, name to, asset quant, std::string memo) {
         check(_first_receiver == name("eosio.token"), "should be eosio.token");
         print_f("On notify : % % % %\n", from, to, quant, memo);
         add_stat(to, "eosio.token transfer");
      }

      [[eosio::on_notify("gre111111111::issinflation")]] 
      void on_issinflation(name to, asset quantity) {
         check(_first_receiver == name("gre111111111"), "should be gre111111111");
         print("Issue Inflation ", name(to), " Amount ", quantity.to_string(), "\n");
         add_stat(to, "Issue Inflation");
      }

    private:
        struct [[eosio::table]] notifystat {
            name account;
            std::string last_action;
            int count;

            uint64_t primary_key() const { return account.value; }
        };
        typedef eosio::multi_index<name("notifystats"), notifystat> notifystats;

        void add_stat(name account, std::string action_text) {
            notifystats stats(_self, _self.value);
            auto existing = stats.find(account.value);
            print("Action added for:  ", name(account), "\n");

            if (existing == stats.end()) {
               stats.emplace(_self, [&](auto& aa) {
                  aa.account = account;
                  aa.last_action = action_text;
                  aa.count = 1;
               });
            }
            else {
               const auto& exaa = *existing;
               stats.modify(exaa, _self, [&](auto& aa) {
                    aa.last_action = action_text;
                    aa.count = ++aa.count;
               });
            }
        }
};

Commands used via cleos:

cleos --url https://jungle2.cryptolions.io:443 push action eosio.token transfer '[ "gre222222222", "gre333333333", "1.0000 EOS", "Test" ]' -p gre111111111

executed transaction: 84fc4c054918649b0ce4b875b4b0922684619f4d76abbbe5b8a901811d1781ff  136 bytes  275 us
#   eosio.token <= eosio.token::transfer        {"from":"gre222222222","to":"gre333333333","quantity":"1.0000 EOS","memo":"Test"}
#  gre222222222 <= eosio.token::transfer        {"from":"gre222222222","to":"gre333333333","quantity":"1.0000 EOS","memo":"Test"}
#  gre333333333 <= eosio.token::transfer        {"from":"gre222222222","to":"gre333333333","quantity":"1.0000 EOS","memo":"Test"}

cleos --url https://jungle2.cryptolions.io:443 push action gre1111111p2 addstat '[ "gre111111111", "Test Action Stat"]' -p gre1111111p2

executed transaction: f8ff8d05aec829fd8ccba9a909c8f04ca065fcabf724390cf0c0b839cb94d523  120 bytes  217 us
#  gre1111111p2 <= gre1111111p2::addstat        {"account":"gre222222222","action_text":"Test Action Stat"}
>> Adding Stat: gre222222222 Action: Test Action Stat

cleos --url https://jungle2.cryptolions.io:443 get table gre1111111p2 gre1111111p2 notifystats

{
  "rows": [{
      "account": "gre111111111",
      "last_action": "Test Action Stat",
      "count": 1
    },{
      "account": "gre222222222",
      "last_action": "Test Action Stat",
      "count": 1
    }
  ],
  "more": false
}

The stats output above is from me testing the table and add_stat method works. It's just the on_notify which aren't firing and updating the table.

2
  • what are you expecting from "const auto& exaa = *existing;" ? Just do stats.modify(existing, _self, [&](auto& aa) {..}.
    – cmadh
    Commented Apr 5, 2019 at 14:58
  • 1
    It was just a test contract I knocked up from other contracts, it is indeed superfluous :)
    – Jason Bert
    Commented Apr 7, 2019 at 13:00

1 Answer 1

1

Turns out there's one vital piece when using on_notify, the action being monitored must call require_recipient(<your contract account name with on_notify>). This sends a copy of the action to that account.

4
  • Are you able to get notified of eosio.token::transfer actions? I'm having no success with that
    – Matei Radu
    Commented Apr 10, 2019 at 14:26
  • 2
    Guys at EOS Cafe pointed me to an implementation they are using: github.com/eoscafe/tipped/blob/master/contract/tipped.hpp . You need to make sure the contract with the on_notify is either the to or recipient of the transfer
    – Jason Bert
    Commented Apr 11, 2019 at 8:37
  • @JasonBert the link is broken (404)
    – ekkis
    Commented Dec 13, 2019 at 3:21
  • "the action being monitored must call..." -- that means that if I'm monitoring eosio.token's transfer method, then that method must call require_recipient()... but we have no control over that!
    – ekkis
    Commented Dec 13, 2019 at 3:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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