3

From contract A, I want to send an action to contract B. How to do that?

There is SEND_INLINE_ACTION but that seems to need a pointer to the contract (usually *this), correct?

Solution

Using action.send as suggested by Leo works when having set eosio.code permission to the contract's account.

0

2 Answers 2

4

Maybe you can try to use N(yourcontract) instead of *this. If it does not work you can also try this:

    action(permission_level{ from, N(active) },
           N(eosio.token), N(transfer),
           std::make_tuple(from, self, price, std::string(""))
    ).send();

Instead of N(eosio.token) and N(transfer) you would use the external contract that you want.

The external contract should allow transactions coming from your contract.

5
  • N(yourcontract) does not work.
    – friedger
    Jul 13, 2018 at 18:08
  • action(..).send() only works if the permission is set to eosio.code, i.e. it was manually set.
    – friedger
    Jul 13, 2018 at 18:10
  • What do you mean by contract should allow transactions coming from your contract? How to allow or disallow a user?
    – friedger
    Jul 13, 2018 at 18:11
  • it requires you to give eosio.code permission only if you try a eosio.token::transfer like above or any other contract/action that you try to use this method? Jul 13, 2018 at 19:59
  • It was required for me for a normal action "changepet"
    – friedger
    Jul 13, 2018 at 20:00
0

Here we can see an example from Monstereos sending an inline action for the battlecreate function:

void pet::battlecreate(name host, battle_mode mode, checksum256 secret) {
  require_auth(host);

  _tb_battle tb_battles(_self, _self);
  auto itr_battle = tb_battles.find(host);

  eosio_assert(itr_battle == tb_battles.end(), "you already host a battle!");
  eosio_assert(mode == V1 || mode == V2 || mode == V3, "invalid battle mode");

  // check and increase busy arenas counter
  auto pc = _get_pet_config();
  pc.battle_busy_arenas++;
  eosio_assert(pc.battle_busy_arenas <= pc.battle_max_arenas, "all arenas are busy");

  tb_battles.emplace(_self, [&](auto& r) {
    r.host = host;
    r.mode = mode;
  });
  _update_pet_config(pc);

  SEND_INLINE_ACTION( *this, battlejoin, {host,N(active)}, {host, host, secret} );
}

SEND_INLINE_ACTION | Docs

Parameters

CONTRACT - The account this action is intended for
NAME - The name of the action
... - The member of the action specified as ("action_member1_name", action_member1_value)("action_member2_name", action_member2_value)

So:

*this is the dereferenced pointer of value contract

battlejoin being the name of the action

battlejoin calls for: name host, name player, checksum256 secret

So we give it host with an active permission level for verification, host for host, host for player, and checksum256 for match's secret ID.

2
  • 3
    Can you explain how to get a different contract than *this?
    – friedger
    Jul 13, 2018 at 18:08
  • the first parameter is called CONTRACT but the description states it's an account. a contract is a class, not an account. so does it mean the account owning the contract that this action is intended to call? the documentation is confusing to me
    – ekkis
    Jan 11, 2019 at 5:51

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.