EOSIO / eosjs

General purpose library for the EOSIO blockchain.
http://eosio.github.io/eosjs
MIT License
1.43k stars 462 forks source link

Support ABI action.name #308

Closed plazav closed 6 years ago

plazav commented 6 years ago

When I am trying to set producer with code like:

    this.eos.transaction({
      actions: [
        {
          account: 'eosio',
          name: 'set_producers',
          authorization: [],
          data: {
            schedule: [{
              producer_name: 'eoscanadacom',
              block_signing_key: 'EOS6RZgDFAt6UgB7CYuyzb35cQTRAABTu4TGnjmbN5FKFYjd2zMx2'
            }]
          }
        }
      ]
    })

I am receiving error:

A name can be up to 12 characters long action.name = "set_producers"

When I am replacing set_producers with short name setprods then I am receiving another one:

Unknown struct 'setprods' for contract 'eosio', locate this struct or provide serialized action.data

Also related to set_account_limits

jcalfee commented 6 years ago

fixed in eosjs@16.0.3

anniepank commented 6 years ago

Actually it's still not working

jcalfee commented 6 years ago

I updated http://jcalfee.github.io/eos.html .. It works there.

You need to add something to your authorization array.

Short version:

eos.setprods(
   [{
      producer_name: 'geymytestacct',
      block_signing_key: 'EOS...'
   }],
   {authorization: 'geymytestacct@owner'}
)

Pass-through version:

(async () => {
tr = await eos.transaction({
      actions: [
        {
          account: 'eosio',
          name: 'setprods',
          authorization: [{actor: 'geymytestacct', permission: 'owner'}],
          data: {
            schedule: [{
              producer_name: 'geymytestacct',
              block_signing_key: 'EOS...'
            }]
          }
        }
      ]
    })

console.log(JSON.stringify(tr))

})()

Promise { <state>: "pending" }

{"broadcast":true,"transaction":{"compression":"none","transaction":{"expiration":"2018-08-20T13:03:18","ref_block_num":53107,"ref_block_prefix":2682365910,"max_net_usage_words":0,"max_cpu_usage_ms":0,"delay_sec":0,"context_free_actions":[],"actions":[{"account":"eosio","name":"setprods","authorization":[{"actor":"geymytestacct","permission":"owner"}],"data":{"schedule":[{"producer_name":"geymytestacct","block_signing_key":"EOS..."}]}}],"transaction_extensions":[]},"signatures":["SIGK1...ULfSjUrYupDEvLZZBeemw8GGz"]},"transaction_id":"ec3530b20a7fffd3468c17c9006efaf72e7da69ae6012c8c7f105d57d322fec2","processed":{"id":"ec3530b20a7fffd3468c17c9006efaf72e7da69ae6012c8c7f105d57d322fec2","receipt":{"status":"executed","cpu_usage_us":784,"net_usage_words":17},"elapsed":784,"net_usage":136,"scheduled":false,"action_traces":[{"receipt":{"receiver":"eosio","act_digest":"1fe1489200e4d49862c23dee2f25c9203542cf7d7fe80202c656f8a0b8f58a9d","global_sequence":278708305,"recv_sequence":14446146,"auth_sequence":[["geydcmrxg4gf",14]],"code_sequence":8,"abi_sequence":9},"act":{"account":"eosio","name":"setprods","authorization":[{"actor":"geydcmrxg4gf","permission":"owner"}],"data":{"schedule":[{"producer_name":"geydcmrxg4gf","block_signing_key":"EOS..."}]},"hex_data":"..."},"elapsed":377,"cpu_usage":0,"console":"","total_cpu_usage":0,"trx_id":"ec3530b20a7fffd3468c17c9006efaf72e7da69ae6012c8c7f105d57d322fec2","inline_traces":[]}],"except":null}}

plazav commented 6 years ago

The first option still throws error:

TypeError: A name can be up to 12 characters long action.name = "set_producers" transaction.actions = [{"account":"eosio","name":"set_producers","authorization":[{"actor":"geymytestacct","permission":"owner"}],"data":{"schedule":[]}}]

The second option with code like:

  this.eos.transaction(tr => {
          actions: [
            {
              account: 'eosio',
              name: 'setprods',
              authorization: [{actor: 'geymytestacct', permission: 'owner'}],
              data: {
                schedule: [{
                  producer_name: 'geymytestacct',
                  block_signing_key: 'EOSXXXXX.....'
                }]
              }
            }
          ]
        })

throws something else:

Error: missing required keys for {"expiration":"2018-08-22T08:30:25","ref_block_num":36437,"ref_block_prefix":2503058476,"net_usage_words":0,"max_cpu_usage_ms":0,"delay_sec":0,"context_free_actions":[],"actions":[],"transaction_extensions":[]}

May be you can recommend how to get block_signing_key?

jcalfee commented 6 years ago

geymytestacct is 13 character

you signed with the wrong key?

plazav commented 6 years ago

We are using public key as value for block_signing_key. First (short) version still not working. Second probably works, but returned with 12 symbols name:

core.js:1673 ERROR Error: Uncaught (in promise): Object: {"type":"account_missing","message":"Missing required accounts, repull the identity","code":402,"isError":true}

Trying with scatter. That is probably something else. Not related to 12 symbols length.

jcalfee commented 6 years ago

@nsjames --^ https://github.com/GetScatter/ScatterWebExtension/blob/30655e025dac2e6fcdbbeebb7dacc1998fef396c/src/models/errors/Error.js#L46

nsjames commented 6 years ago

Hmm, this usually occurs when the authorization array is missing in the eosjs options and Scatter either can't infer which account to use to sign or the account inferred has the wrong @ permission specified ( defaulting to @active when the user has @owner linked into Scatter ).

However, I see that you have indeed specified the authorization array but hardcoded the values. It might be that you aren't requesting access to the account you need within the getIdentity request. Check out this ticket to see if it helps you. Generally you should always be building the authorization from the account returned from Scatter and never assume the user's account even if they have provided it to you manually.

plazav commented 6 years ago

And here is what I get without scatter:

[{"message":"transaction must have at least one authorization","file":"controller.cpp","line_number":1641,"method":"validate_referenced_accounts"}]

That is when eos init with private key.
With public key:

missing required keys for {"expiration":"2018-08-24T13:54:22","ref_block_num":26014,"ref_block_prefix":3290271931,"net_usage_words":0,"max_cpu_usage_ms":0,"delay_sec":0,"context_free_actions":[],"actions":[],"transaction_extensions":[]}

Code is:

await this.eos.transaction(tr => {
      [
        {
          account: 'eosio',
          name: 'setprods',
          authorization: [{actor: 'myaccountnam', permission: 'active'}],
          data: {
            schedule: [{
              producer_name: this.sheldule,
              block_signing_key: pubKey
            }]
          }
        }
      ]
    })
nsjames commented 6 years ago

Pass the authorization object in as options ( second parameter to transaction, not (only?) within the transaction itself.

jcalfee commented 6 years ago

Each action has its own authorizations so that looks correct.

jcalfee commented 6 years ago

Transaction accepts an object and just sends it. If you send a callback it will think you want to use the short api to collect a bunch of actions. Here your trying to send an object so just remove the callback.

await this.eos.transaction({
     actions: [{
          account: 'eosio',
          name: 'setprods',
          authorization: [{actor: 'myaccountnam', permission: 'active'}],
          data: {
            schedule: [{
              producer_name: this.sheldule,
              block_signing_key: pubKey
            }]
          }
     ...
plazav commented 6 years ago

I have tried to use also options with authorization.

 options = {
        broadcast: true,
        sign: true,
        verbose: true,
        keyProvider: "key_goes_there",
        authorization: [{actor: 'myaccountnam', permission: 'active'}],
        chainId: "id_goes_there"
      }

And transaction doesn't have a callback.

await this.eos.transaction({
     actions: [{
          account: 'eosio',
          name: 'setprods',
          authorization: [{actor: 'myaccountnam', permission: 'active'}],
          data: {
            schedule: [{
              producer_name: this.sheldule,
              block_signing_key: pubKey
            }]
          }, options)

Account name and permission values are hardcoded only for example

jcalfee commented 6 years ago

Can you test with eosjs directly without scatter? Just very it works in eosjs and breaks in scatter so nsjames will know exactly what to look for.

nsjames commented 6 years ago

I actually just had a similar session with @jafri about this. The transaction({actions[]}) isn't implemented yet into Scatter's eosjs proxy, it currently only supports the array based batches.

Here's some example code I gave him which he ended up tweaking an using. I'm sure when he sees this ping he'd be more than happy to let us know exactly what he ended up doing.

const allContracts = [
    {acc:'name', action:'act', params:{}, opts:{}}, 
    {acc:'name', action:'act', params:{}, opts:{}}
]
eos.transaction(allContracts.map(x => x.acc), contracts => {
    allContracts.map(contract => {
        contracts[contract.acc][contract.action](contract.params, contract.opts);
    });
});

I'll have to dig into this new {actions:[]} stuff as it wasn't there the last time I ran through the eosjs code, and add support for it. It's definitely a nice clean way of doing things. However, this is now contained within the scatter-js project itself which is outside of scatter and relies on Dapps upgrading their library for support. So once it's added there you won't need to wait for Scatter users to upgrade at least. Adding a ticket there will help remind me about this, but I'm pretty swamped with Mobile at the moment so you might want to run with the array based batches for now.

Sorry I didn't notice this before, totally missed the {actions} part.

plazav commented 6 years ago

With eosjs 16.0.6 and keys authorization (without scatter) I am receiving error:

Unknown struct 'setprods' for contract 'eosio', locate this struct or provide serialized action.data action.data...

jcalfee commented 6 years ago

You may need to date eosio.system on your chain .. Set prods is one of the actions already.

From eos.getAbi('eosio').then(abi => console.log(JSON.stringify(abi))) {"name":"setprods","type":"set_producers",

plazav commented 6 years ago

@jcalfee, I have tried with BlockMatrix MainNet and there is setprods in abi. But still getting "Unknown struct 'setprods' for contract 'eosio'"

jcalfee commented 6 years ago

what is your code?

plazav commented 6 years ago
await this.eos.transaction({
          actions: [
            {
              account: 'eosio',
              name: 'setprods',
              authorization: [{ actor: this.accountName, permission: this.permission }],
              data: {
                schedule: [{
                  producer_name: this.scheldule.toLowerCase(),
                  block_signing_key: pubKey
                }]
              }
            }
          ]
        })
jcalfee commented 6 years ago

The message "Unknown struct 'setprods' for contract 'eosio'" means that your ABI is not setup correctly.

plazav commented 6 years ago

I am sorry, but what do you mean under "ABI is not setup correctly"?

jcalfee commented 6 years ago

Are you on the latest version? This has been working fine for a while. I can't re-create your problem.

plazav commented 6 years ago

Yes, have just updated to latest. Can you provide sample that you are trying (with specifying network and data send)?

jcalfee commented 6 years ago

At https://jcalfee.github.io/eos.html the "Blockchain" text field is actually a drop-down, select jungle,https://api.eosio.cr and click Connect... Then add 5JtpKhg9eBN4d4vrbnJSKyCd6n1zz8xvaneio86hKzSddEvQyHR to the private key and click Add.

In the console run:

eos.setprods(['fewmanygoubi'], {authorization: 'fewmanygoubi'})

The results are in the network tab under the push_transaction request. I see a green 202 success status.

plazav commented 6 years ago

"action's authorizing actor 'fewmanygoubi' does not exist" - here is what I have recieved

jcalfee commented 6 years ago

image

plazav commented 6 years ago

capture

jcalfee commented 6 years ago

The only difference I see is that we connected to different jungle endpoints. If you change the host it should work: jungle,https://jungle.eosio.cr

The other jungle endpoint should have worked though. Not sure what is going on.

jcalfee commented 6 years ago

I'm closing .. but comment again if you get stuck.

avintoptaros commented 6 years ago

Right. Now I see it's ok.