2

I would like to send SYS token owned by the smart contract account to a third party account when anyone call a specific action. I have tried the following code but I am getting an error:

[[eosio::action]]
void sendtoalice() {
    // make an inline transfer to alice
    action transferAlice = action(
        permission_level{get_self(),"active"_n},
        "eosio.token"_n,
        "transfer"_n,
        std::make_tuple(get_self(), "alice", "0.0001 SYS", "")
         );

    transferAlice.send();
}

Error:

$ cleos push action mycontract sendtoalice '[]' -p bob@active
Error 3090003: Provided keys, permissions, and delays do not satisfy declared authorizations
Ensure that you have the related private keys inside your wallet and your wallet is unlocked.
Error Details:
transaction declares authority '{"actor":"mycontract","permission":"active"}', but does not have signatures for it under a provided delay of 0 ms, provided permissions [{"actor":"mycontract","permission":"eosio.code"}], provided keys [], and a delay max limit of 3888000000 ms
pending console output:

Any idea of what could be wrong?

2

The problem is you are trying to transfer tokens, which requires mycontract@active permission. But when you send tokens from within a contract, the permission is mycontract@eosio.code - even if you sign the transaction with your mycontract@active key.

There are then two problems with the example you post:

  1. You sign the action with bob@active, it should be mycontract@active.
  2. You need to add mycontract@eosio.code permission to the active permissions. To do that, type the following into the terminal:
cleos set account permission mycontract active '{"threshold": 1, "keys":[{"key":"MYCONTRACT_PUBLIC_KEY", "weight":1}], "accounts":[{"permission":{"actor":"mycontract","permission":"eosio.code"},"weight":1}], "waits":[] }' owner -p mycontract

This allows the active key to be satisfied by either the private key that currently belongs to the active permission, OR it also allows any of the code in the mycontract smart contract to act with active permission.

Allowing a contract to act on your behalf

If Bob wants to transfer money through this smart contract, then he needs to give the contract permission to use his active permission:

cleos set account permission bob active '{"threshold": 1, "keys":[{"key":"BOB_PUBLIC_KEY", "weight":1}], "accounts":[{"permission":{"actor":"mycontract","permission":"eosio.code"},"weight":1}], "waits":[] }' owner -p bob

Then, the code of the contract would be changed as follows:

[[eosio::action]]
void sendtoalice() {
    // make an inline transfer to alice
    require_auth(eosio::name("bob"));
    action transferAlice = action(
        permission_level{get_self(),"active"_n},
        "eosio.token"_n,
        "transfer"_n,
        std::make_tuple("bob", "alice", "0.0001 SYS", "")
         );

    transferAlice.send();
}
  • Is my use case impossible to implement? I would like to make some action triggered by someone sending SYS from the contract to a third party? – poiuytrez Mar 13 at 17:33
  • I confirm that I would like to use bob (a regular user) and not mycontract to call the action. – poiuytrez Mar 13 at 17:52
  • 1
    I updated my answer to show how the smart contract could send money from Bob's account – Phillip Hamnett - EOS42 Mar 13 at 20:53
  • Thanks. However, I want to transfer the contract tokens and not Bob's tokens. – poiuytrez Mar 14 at 7:27
  • 1
    So set the permission as I show in my first part of my answer: cleos set account permission mycontract active '{"threshold": 1, "keys":[{"key":"MYCONTRACT_PUBLIC_KEY", "weight":1}], "accounts":[{"permission":{"actor":"mycontract","permission":"eosio.code"},"weight":1}], "waits":[] }' owner -p mycontract After this you can sign contract actions as bob and it will transfer the money appropriately – Phillip Hamnett - EOS42 Mar 14 at 15:14

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.