Skip to content

Commit

Permalink
refactor(compiler)!: remove contractEncodeCallDataAPI
Browse files Browse the repository at this point in the history
use @aeternity/aepp-calldata or sdk.compilerApi.encodeCalldata
  • Loading branch information
davidyuk committed Jan 24, 2022
1 parent fb929f8 commit 7d02317
Show file tree
Hide file tree
Showing 10 changed files with 37 additions and 88 deletions.
1 change: 0 additions & 1 deletion docs/guides/error-handling.md
Expand Up @@ -49,7 +49,6 @@ AeError
│ │ UnknownChannelStateError
└───CompilerError
│ │ UnavailableCompilerError
│ │ UnsupportedCompilerError
│ │ InvalidAuthDataError
Expand Down
21 changes: 10 additions & 11 deletions examples/node/paying-for-tx-contract-call-tx.js
Expand Up @@ -120,11 +120,11 @@ const NEW_USER_KEYPAIR = Crypto.generateKeyPair();
// `ContractCallTx` by invoking the generated contract method on the contract instance that you
// typically use for contract calls.
//
// Following 3 steps need to be done:
// Following 4 steps need to be done:
//
// 1. Create calldata by calling the http compiler using `contractEncodeCallDataAPI` and
// providing the contract source, the name of the `entrypoint` to call as well as the
// required params.
// 1. Initialize a contract instance by the source code and the contract address.
// 1. Create calldata by calling the `encode` function providing the contract name, the name of
// the `entrypoint` to call as well as the required params.
// - The `entrypoint` with the name `set_latest_caller` doesn't require any params so you
// can provide an empty array
// 1. Create the `ContractCreateTx` by providing all required params.
Expand All @@ -134,7 +134,10 @@ const NEW_USER_KEYPAIR = Crypto.generateKeyPair();
// 1. Sign the transaction by providing `innerTx: true` as transaction option.
// - The transaction will be signed in a special way that is required for inner transactions.
//
const calldata = await client.contractEncodeCallDataAPI(CONTRACT_SOURCE, 'set_last_caller', [])
const contract = await client.getContractInstance(
{ source: CONTRACT_SOURCE, contractAddress: CONTRACT_ADDRESS }
)
const calldata = contract.calldata.encode('PayingForTxExample', 'set_last_caller', [])
const contractCallTx = await client.contractCallTx({
callerId: await newUserAccount.address(),
contractId: CONTRACT_ADDRESS,
Expand All @@ -152,12 +155,8 @@ const NEW_USER_KEYPAIR = Crypto.generateKeyPair();
console.log(payForTx)

// ## 7. Check that last caller is the new user
// Knowing the contract address and the source code allows you to
// initialize a contract instance and interact with the contract in a convenient way.
const contractInstance = await client.getContractInstance(
{ source: CONTRACT_SOURCE, contractAddress: CONTRACT_ADDRESS }
)
const dryRunTx = await contractInstance.methods.get_last_caller()
// Contract instance allows interacting with the contract in a convenient way.
const dryRunTx = await contract.methods.get_last_caller()
console.log(`New user: ${await newUserAccount.address()}`)
console.log('Last caller:', dryRunTx.decodedResult)

Expand Down
30 changes: 1 addition & 29 deletions src/contract/compiler.js
Expand Up @@ -28,11 +28,7 @@ import ContractBase from './index'
import semverSatisfies from '../utils/semver-satisfies'
import AsyncInit from '../utils/async-init'
import genSwaggerClient from '../utils/swagger'
import {
UnavailableCompilerError,
MissingParamError,
UnsupportedCompilerError
} from '../utils/errors'
import { MissingParamError, UnsupportedCompilerError } from '../utils/errors'
import { mapObject } from '../utils/other'

/**
Expand Down Expand Up @@ -95,30 +91,6 @@ export default AsyncInit.compose(ContractBase, {
this.compilerVersion, COMPILER_GE_VERSION, COMPILER_LT_VERSION
)
}
},
_ensureCompilerReady () {
if (!this.compilerApi) throw new UnavailableCompilerError()
},
/**
* Encode call data for contract call
* @function
* @category async
* @param {String} source Contract source code
* @param {String} name Name of function to call
* @param {Array} args Argument's for call
* @param {Object} [options={}] Options
* @param {Object} [options.filesystem={}] Contract external namespaces map
* @return {Promise<String>}
*/
async contractEncodeCallDataAPI (source, name, args = [], options) {
this._ensureCompilerReady()
const { calldata } = await this.compilerApi.encodeCalldata({
source,
function: name,
arguments: args,
options
})
return calldata
}
},
props: {
Expand Down
3 changes: 2 additions & 1 deletion src/contract/ga/helpers.js
Expand Up @@ -11,8 +11,9 @@ export const prepareGaParams = (ins) => async (authData, authFnName) => {
return { authCallData: authData.callData, gas }
}
if (!authData.source || !authData.args) throw new InvalidAuthDataError('Auth data must contain source code and arguments.')
const contract = await ins.getContractInstance({ source: authData.source })
return {
authCallData: await ins.contractEncodeCallDataAPI(authData.source, authFnName, authData.args),
authCallData: contract.calldata.encode(contract.aci.name, authFnName, authData.args),
gas
}
}
6 changes: 4 additions & 2 deletions src/contract/ga/index.js
Expand Up @@ -88,11 +88,13 @@ async function createGeneralizeAccount (authFnName, source, args = [], options =
const ownerId = await this.address(opt)
if (await this.isGA(ownerId)) throw new IllegalArgumentError(`Account ${ownerId} is already GA`)

const contract = await this.getContractInstance({ source })
await contract.compile()
const { tx, contractId } = await this.gaAttachTx({
...opt,
ownerId,
code: (await this.contractCompile(source)).bytecode,
callData: await this.contractEncodeCallDataAPI(source, 'init', args),
code: contract.bytecode,
callData: contract.calldata.encode(contract.aci.name, 'init', args),
authFun: hash(authFnName)
})

Expand Down
16 changes: 0 additions & 16 deletions src/contract/index.js
Expand Up @@ -39,26 +39,10 @@ import { required } from '@stamp/required'
*/
const ContractBase = stampit(required({
methods: {
contractEncodeCallDataAPI: required,
setCompilerUrl: required
}
}))

/**
* Encode contract data
* @function contractEncodeCallDataAPI
* @instance
* @abstract
* @category async
* @rtype (source: String, name: String, args: Array, options: Array) => callData: Promise[String]
* @param {String} source - Contract source code
* @param {String} name - Function name
* @param {Array} args - Function argument's
* @param {Object} [options={}] Options
* @param {Object} [options.filesystem] Contract external namespaces map
* @return {String} - Contract encoded data
*/

/**
* Set compiler url
* @function setCompilerUrl
Expand Down
7 changes: 0 additions & 7 deletions src/utils/errors.ts
Expand Up @@ -329,13 +329,6 @@ export class UnknownChannelStateError extends ChannelError {
}

/* compiler issued errors */
export class UnavailableCompilerError extends CompilerError {
constructor () {
super('Compiler is not ready')
this.name = 'UnavailableCompilerError'
}
}

export class UnsupportedCompilerError extends CompilerError {
constructor (compilerVersion: string, COMPILER_GE_VERSION: string, COMPILER_LT_VERSION: string) {
super(`Unsupported compiler version ${compilerVersion}. ` +
Expand Down
9 changes: 0 additions & 9 deletions test/integration/contract.js
Expand Up @@ -282,7 +282,6 @@ describe('Contract', function () {
})

describe('Sophia Compiler', function () {
let callData
let bytecode

it('compile', async () => {
Expand Down Expand Up @@ -320,14 +319,6 @@ describe('Contract', function () {
.to.be.rejectedWith('validation_error in body ({"error":"missing_required_property","data":"code","path":[]})')
})

it('encode call-data', async () => {
callData = await sdk.contractEncodeCallDataAPI(identityContract, 'init', [])
const prefix = callData.slice(0, 2)
const isString = typeof callData === 'string'
prefix.should.be.equal('cb')
isString.should.be.equal(true)
})

it('validate bytecode', async () => {
expect(await sdk.compilerApi.validateByteCode({ bytecode, source: identityContract }))
.to.be.eql({})
Expand Down
11 changes: 6 additions & 5 deletions test/integration/ga.js
Expand Up @@ -20,7 +20,7 @@ import { getSdk } from './'
import { generateKeyPair } from '../../src/utils/crypto'
import MemoryAccount from '../../src/account/memory'

const authContract = `contract BlindAuth =
const authContractSource = `contract BlindAuth =
stateful entrypoint authorize(r: int) : bool =
// r is a random number only used to make tx hashes unique
switch(Auth.tx_hash)
Expand All @@ -39,13 +39,13 @@ describe('Generalize Account', function () {
})

it('Make account GA', async () => {
await sdk.createGeneralizeAccount('authorize', authContract)
await sdk.createGeneralizeAccount('authorize', authContractSource)
const isGa = await sdk.isGA(gaAccount.publicKey)
isGa.should.be.equal(true)
})

it('Fail on make GA on already GA account', async () => {
await sdk.createGeneralizeAccount('authorize', authContract)
await sdk.createGeneralizeAccount('authorize', authContractSource)
.should.be.rejectedWith(`Account ${gaAccount.publicKey} is already GA`)
})

Expand All @@ -55,9 +55,10 @@ describe('Generalize Account', function () {
const { publicKey } = generateKeyPair()

const r = () => Math.floor(Math.random() * 20).toString()
const callData = await sdk.contractEncodeCallDataAPI(authContract, 'authorize', [r()])
const authContract = await sdk.getContractInstance({ source: authContractSource })
const callData = authContract.calldata.encode('BlindAuth', 'authorize', [r()])
await sdk.spend(10000, publicKey, { authData: { callData } })
await sdk.spend(10000, publicKey, { authData: { source: authContract, args: [r()] } })
await sdk.spend(10000, publicKey, { authData: { source: authContractSource, args: [r()] } })
const balanceAfter = await sdk.balance(publicKey)
balanceAfter.should.be.equal('20000')
})
Expand Down
21 changes: 14 additions & 7 deletions test/integration/transaction.js
Expand Up @@ -46,7 +46,7 @@ const query = '{\'city\': \'Berlin\'}'
const queryResponse = '{\'tmp\': 101}'

// Contract test data
const contractCode = `
const contractSource = `
contract Identity =
entrypoint getArg(x : int) = x
`
Expand Down Expand Up @@ -134,12 +134,19 @@ describe('Native Transaction', function () {
txFromAPI.should.be.equal(nativeTx)
})

let contract
it('native build of contract create tx', async () => {
const { bytecode } = await sdk.contractCompile(contractCode)
const callData = await sdk.contractEncodeCallDataAPI(contractCode, 'init')
const owner = await sdk.address()

const params = { ownerId: owner, code: bytecode, deposit, amount, gas, gasPrice, callData }
contract = await sdk.getContractInstance({ source: contractSource })
await contract.compile()
const params = {
ownerId: await sdk.address(),
code: contract.bytecode,
deposit,
amount,
gas,
gasPrice,
callData: contract.calldata.encode('Identity', 'init', [])
}
const txFromAPI = await sdk.contractCreateTx(params)
const nativeTx = await sdkNative.contractCreateTx(params)

Expand All @@ -151,7 +158,7 @@ describe('Native Transaction', function () {
})

it('native build of contract call tx', async () => {
const callData = await sdk.contractEncodeCallDataAPI(contractCode, 'getArg', ['2'])
const callData = contract.calldata.encode('Identity', 'getArg', [2])
const owner = await sdk.address()

const params = { callerId: owner, contractId, amount, gas, gasPrice, callData }
Expand Down

0 comments on commit 7d02317

Please sign in to comment.