3

so I would like to deploy an EOS contract using eosjs. I encountered several problems (especially with converting the .abi and .wasm files). All the examples either use node (so fs is available) or an older version of eosjs. I tried to use fetch and save the files as byte arrays, but I don't know how to convert them to the right format. While searching, I found: https://cmichel.io/setcode-and-setabi-with-eos-js/ and https://github.com/EOSIO/eosjs/issues/285, but neither of these threads helped me with deploying a contract directly from the browser (as they all talk about using node and thus are capable of reading the files directly from the system). Has anyone done something similar and could provide some guidance (code snippet with an example)? I am actually a little bit baffled that this is currently so inconvenient, as deploying a contract should be a pretty common use case.

Thanks in advance and kind regards, Simon

1 Answer 1

0

I saw this question so old with a lot of visualisations and no answer, so decided to reply anyway for the new viewers...

From the CMichel article you shared in your question, you can find that the ABI needs to be passed to serialization as a plain JS object, so just use fetch with json() so that you get it parsed to the right format. For the WASM part you need to use .toString('hex') on the fetch data, to get an hexadecimal string of the code.

This way you get exactly what is needed to feed the deployContract function that could be changed to something like this:

async function deployContract(account, contractDir, wasm, abi) {
  // Prepare SETABI
  const buffer = new Serialize.SerialBuffer({
    textEncoder: api.textEncoder,
    textDecoder: api.textDecoder,
  })

  const abiDefinition = api.abiTypes.get(`abi_def`)
  // need to make sure abi has every field in abiDefinition.fields
  // otherwise serialize throws
  abi = abiDefinition.fields.reduce(
    (acc, { name: fieldName }) =>
      Object.assign(acc, { [fieldName]: acc[fieldName] || [] }),
    abi
  )
  abiDefinition.serialize(buffer, abi)

  // Send transaction with both setcode and setabi actions
  const result = await api.transact(
    {
      actions: [
        {
          account: 'eosio',
          name: 'setcode',
          authorization: [
            {
              actor: account,
              permission: 'active',
            },
          ],
          data: {
            account: account,
            vmtype: 0,
            vmversion: 0,
            code: wasm,
          },
        },
        {
          account: 'eosio',
          name: 'setabi',
          authorization: [
            {
              actor: account,
              permission: 'active',
            },
          ],
          data: {
            account: account,
            abi: Buffer.from(buffer.asUint8Array()).toString(`hex`),
          },
        },
      ],
    },
    {
      blocksBehind: 3,
      expireSeconds: 30,
    }
  )
}

Please refer to the great CMichel article here for all the details...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.