[Solved] How to propertly call createContract?


#1

We’re trying to deploy a contract in a state channel. We were reading the docs and we know we have to call createContract, but we don’t know how to get all the parameters. The parameters are the following:

function createContract ({ code, callData, deposit, vmVersion, abiVersion }, sign)

For example, how can we get callData? Is that the encoded contructor and parameters call?


#2

Hi @fedecaccia

I see your question is more regarding the JS SDK than it is regarding channels themselves.
The channels off-chain protocol regarding updates tends to follow the on-chain one. This is to reduce confusion. For example off-chain transfers closely resemble on-chain spend transaction with their set of arguments. Same stands true for off-chain contract create and call events: they take the same arguments as on-chain contract_create_tx and contract_call_tx would use, including the call data. You can read about those here.

To answer your question:

  • code is the encoded contract bytecode
  • callData is the encoded contract initial call
  • deposit is the amount the contract owner dedicates to the contract itself
  • vmVersion and abiVersion are the VM and ABI being used (tautology, but not sure how elaborate this further :D)

State channels and smart contracts
#3

I think the best examples can be found in integration tests https://github.com/aeternity/aepp-sdk-js/blob/develop/test/integration/channel.js. I’ve extracted most relevant parts for creating a contract below:

const account = await Universal({
  networkdId: '__NETWORK_ID__',
  url: '__URL__',
  internalUrl: '__INTERNAL_API_URL__',
  keypair: {
    publicKey: '__PUBLIC_KEY__',
    secretKey: '__SECRET_KEY___'
  }
})
const channel = await Channel({
  // ... Channel params
})

const identityContract = `
contract Identity =
  type state = ()
  public function main(x : int) = x
`

// Let's compile the contract
const code = await account.compileContractAPI(identityContract)
// Now encode call for initialization
const callData = await account.contractEncodeCallDataAPI(identityContract, 'init', [])
// Create contract inside the channel
const { address, accepted } = await channel.createContract({
  code,
  callData,
  deposit: 1000,
  vmVersion: 3,
  abiVersion: 1
}, async (tx) => await account.signTransaction(tx))

Now if you want to call this contract you can do it like this:

const result = await channel.callContract({
  amount: 0,
  callData: await account.contractEncodeCallDataAPI(identityContract, 'main', ['42']),
  contract: address,
  abiVersion: 1
}, async (tx) => await account.signTransaction(tx))

#4

Thanks! Your answer was very useful!