1

In my contract I have an action which is supposed to allow users to collect the tokens they have accumulated. To do this I use:

void transfer_token(account_name receiver, asset quantity, std::string memo) {

    action(
            permission_level{_self, N(active)},
            N(eosio.token),
            N(transfer),
            std::make_tuple(_self, receiver, quantity, memo)
    ).send();
}

But for this to work I have to use the following command for every user:

cleos set account permission <contract> active '{"threshold": 1,"keys": [{"key": <public_key>,"weight": 1}],"accounts": [{"permission":{"actor": <user>,"permission":"active"},"weight":1}]}' owner -p <contract>

My question is:

How can I, using scatter and eosjs, setup the authorization for a user to call an action that transfers tokens from the contract to himself?

edit: I am using scatter on my client, and it has been setup properly, I can use it to transfer tokens to the contract.

edit: Here's the output of using the client to call the action that makes the contract transfer tokens to the user.

{
  "code": 500,
  "message": "Internal Service Error",
  "error": {
    "code": 3090003,
    "name": "unsatisfied_authorization",
    "what": "Provided keys, permissions, and delays do not satisfy declared authorizations",
    "details": [
      {
        "message": "transaction declares authority '{\"actor\":\"testacccpico\",\"permission\":\"active\"}', but does not have signatures for it under a provided delay of 0 ms, provided permissions [{\"actor\":\"testacccpico\",\"permission\":\"eosio.code\"}], provided keys [], and a delay max limit of 3888000000 ms",
        "file": "authorization_manager.cpp",
        "line_number": 413,
        "method": "check_authorization"
      },
      {
        "message": "pending console output: ",
        "file": "apply_context.cpp",
        "line_number": 61,
        "method": "exec_one"
      }
    ]
  }
}
5
  • Are you using scatter and Eosjs in front end? than I can tell a way to do this. Sep 26, 2018 at 6:33
  • Yes, I will be using scatter and Eosjs in the front end.
    – mbsff
    Sep 26, 2018 at 7:13
  • did you try cleos set account permission <account> active '{"threshold": 1,"keys": [{"key": "<key>","weight": 1}],"accounts": [{"permission":{"actor":"<contract>","permission":"eosio.code"},"weight":1}]}' -p <account>
    – confused00
    Oct 12, 2018 at 10:26
  • that command just says transaction declares authority '{"actor":"testacccpus1","permission":"active"}', but does not have signatures for it.
    – mbsff
    Oct 12, 2018 at 10:35
  • maybe cleos set account permission <account> active '{"threshold": 1,"keys": [{"key": "<key>","weight": 1}],"accounts": [{"permission":{"actor":"<contract>","permission":"eosio.code"},"weight":1}]}' owner -p <account>@owner assuming you have the keys for <account>@owner authority in your wallet and your wallet is unlocked
    – confused00
    Oct 12, 2018 at 11:54

1 Answer 1

1

Assuming you have setup the scatter and eosjs for your front. if not go here After that you need to set permissions, Using two functions like this:

async getScatter(nextProps) {
    const scatter = nextProps.scatterObj;
    const { accounts } = await scatter.getIdentity({
      accounts: [config.EOS_CONFIG.network]
    });
    return accounts;
  }

  setNewPermissions = accountName => {
    this.props.eosObj
      .getAccount(accountName)
      .then(account => {
        let newPerms = this.updatePermissions(
          JSON.parse(JSON.stringify(account.permissions))
        );
        console.log(newPerms);

        this.props.eosObj.transaction(tr => {
          for (const perm of newPerms) {
            if (perm.perm_name === "active") {
              tr.updateauth({
                account: accountName,
                permission: perm.perm_name,
                parent: perm.parent,
                auth: perm.required_auth
              });
            }
          }
        });
      })
      .catch(e => {
        console.log(e);
      });
  };
  updatePermissions = permissions => {
    for (let perm of permissions) {
      if (perm.perm_name === "active") {
        let newPerm = {
          permission: {
            actor: config.EOS_CONFIG.contractSender,
            permission: "eosio.code"
          },
          weight: 1
        };
        if (!this.isObjPresentInArray(newPerm, perm.required_auth.accounts))
          perm.required_auth.accounts.push(newPerm);
      }
    }
    return permissions;
  };

You also need to import the private key for the account to whom you providing the permission. Hope this will work for you.

3
  • I tried this but it keeps giving me the same error on the jungle testnet
    – mbsff
    Oct 12, 2018 at 13:25
  • did you set the permissions correctly. First try to push the transaction using cleos command on jungle test net if it work means something is wrong with permissions or setting scatter.Try to modify my code accordingly to your usecase don't exactly copy it. Because it working fine for my usecase. Give link to your repo So that i can have a look Oct 12, 2018 at 23:57
  • Did you use require_auth(account_name); in you action. Only two possiblities are there either you set different keys as @confuse00 said or you pushing the action with a account that don't have authority to execute. Oct 13, 2018 at 0:07

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.