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"
      }
    ]
  }
}
  • Are you using scatter and Eosjs in front end? than I can tell a way to do this. – Nirdesh Kumar Choudhary Sep 26 '18 at 6:33
  • Yes, I will be using scatter and Eosjs in the front end. – mbsff Sep 26 '18 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 '18 at 10:26
  • that command just says transaction declares authority '{"actor":"testacccpus1","permission":"active"}', but does not have signatures for it. – mbsff Oct 12 '18 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 '18 at 11:54
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.

  • I tried this but it keeps giving me the same error on the jungle testnet – mbsff Oct 12 '18 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 – Nirdesh Kumar Choudhary Oct 12 '18 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. – Nirdesh Kumar Choudhary Oct 13 '18 at 0:07

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.