Skip to content

Commit

Permalink
Flatten options of contractCallStatic, remove extra dryRunContractTx
Browse files Browse the repository at this point in the history
  • Loading branch information
davidyuk committed Mar 1, 2021
1 parent 401c53d commit f3ffb66
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 65 deletions.
97 changes: 40 additions & 57 deletions es/ae/contract.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import { isBase64 } from '../utils/string'
import ContractCompilerAPI from '../contract/compiler'
import ContractBase from '../contract'
import ContractACI from '../contract/aci'
import BigNumber from 'bignumber.js'
import NodePool from '../node-pool'
import { AMOUNT, DEPOSIT, DRY_RUN_ACCOUNT, GAS, MIN_GAS_PRICE } from '../tx/builder/schema'
import { decode, produceNameId } from '../tx/builder/helpers'
Expand Down Expand Up @@ -127,56 +126,41 @@ async function contractDecodeData (source, fn, callValue, callResult, options) {
* @param {String} address Contract address
* @param {String} name Name of function to call
* @param {Array|String} args Argument's or callData for call/deploy transaction
* @param {Object} [options={}] Options
* @param {String} [options.top] Block hash on which you want to call contract
* @param {Object} [options]
* @param {Number|String} [options.top] Block height or hash on which you want to call contract
* @param {String} [options.bytecode] Block hash on which you want to call contract
* @param {Object} [options.options] Transaction options (fee, ttl, gas, amount, deposit)
* @param {Object} [options.options.filesystem] Contract external namespaces map
* @param {Object} [options.filesystem] Contract external namespaces map
* @return {Promise<Object>} Result object
* @example
* const callResult = await client.contractCallStatic(source, address, fnName, args = [], { top, options = {} })
* const callResult = await client.contractCallStatic(source, address, fnName, args)
* {
* result: TX_DATA,
* decode: (type) => Decode call result
* }
*/
async function contractCallStatic (source, address, name, args = [], { top, options = {}, bytecode } = {}) {
const opt = R.merge(this.Ae.defaults, options)
const callerId = opt.onAccount
? await this.address(opt)
: await this.address().catch(e => opt.dryRunAccount.pub)

// Prepare call-data
const callData = Array.isArray(args) ? await this.contractEncodeCall(source, name, args, opt) : args

// Get block hash by height
if (top && !isNaN(top)) {
top = (await this.getKeyBlock(top)).hash
async function contractCallStatic (source, address, name, args = [], options = {}) {
const callerId = await this.address(options).catch(() => DRY_RUN_ACCOUNT.pub)
if (typeof options.top === 'number') {
options.top = (await this.getKeyBlock(options.top)).hash
}
// Prepare nonce
const nonce = top ? (await this.getAccount(callerId, { hash: top })).nonce + 1 : undefined
if (name === 'init') {
// Prepare deploy transaction
const { tx } = await this.contractCreateTx(R.merge(opt, {
callData,
code: bytecode,
ownerId: callerId,
nonce
}))
return this.dryRunContractTx(tx, callerId, source, name, { ...opt, top })
} else {
// Prepare `call` transaction
const tx = await this.contractCallTx(R.merge(opt, {
callerId,
contractId: await this.resolveName(address, 'ct', { resolveByNode: true }),
callData,
nonce
}))
return this.dryRunContractTx(tx, callerId, source, name, { ...opt, top })
const txOpt = {
...this.Ae.defaults,
...options,
callData: Array.isArray(args) ? await this.contractEncodeCall(source, name, args, options) : args,
nonce: options.top && (await this.getAccount(callerId, { hash: options.top })).nonce + 1
}
}
const tx = name === 'init'
? (await this.contractCreateTx({
...txOpt,
code: options.bytecode,
ownerId: callerId
})).tx
: await this.contractCallTx({
...txOpt,
callerId,
contractId: await this.resolveName(address, 'ct', { resolveByNode: true })
})

async function dryRunContractTx (tx, callerId, source, name, options) {
const { callObj, ...dryRunOther } = await this.txDryRun(tx, callerId, options)

const { returnType, returnValue } = callObj
Expand Down Expand Up @@ -253,7 +237,7 @@ async function contractCall (source, address, name, argsOrCallData = [], options
* }
*/
async function contractDeploy (code, source, initState = [], options = {}) {
const opt = R.merge(this.Ae.defaults, options)
const opt = { ...this.Ae.defaults, ...options }
const callData = Array.isArray(initState) ? await this.contractEncodeCall(source, 'init', initState, opt) : initState
const ownerId = await this.address(opt)

Expand All @@ -271,11 +255,10 @@ async function contractDeploy (code, source, initState = [], options = {}) {
rawTx,
txData,
address: contractId,
call: async (name, args = [], options = {}) => this.contractCall(source, contractId, name, args, R.merge(opt, options)),
callStatic: async (name, args = [], options = {}) => this.contractCallStatic(source, contractId, name, args, {
...options,
options: { onAccount: opt.onAccount, ...R.merge(opt, options.options) }
}),
call: (name, args, options) =>
this.contractCall(source, contractId, name, args, { ...opt, ...options }),
callStatic: (name, args, options) =>
this.contractCallStatic(source, contractId, name, args, { ...opt, ...options }),
createdAt: new Date()
})
}
Expand All @@ -299,17 +282,18 @@ async function contractDeploy (code, source, initState = [], options = {}) {
* }
*/
async function contractCompile (source, options = {}) {
const opt = R.merge(this.Ae.defaults, options)
const opt = { ...this.Ae.defaults, ...options }
const bytecode = await this.compileContractAPI(source, options)
return Object.freeze(Object.assign({
encodeCall: async (name, args) => this.contractEncodeCall(source, name, args, R.merge(opt, options)),
deploy: async (init, options = {}) => this.contractDeploy(bytecode, source, init, R.merge(opt, options)),
deployStatic: async (init, options = {}) => this.contractCallStatic(source, null, 'init', init, {
bytecode,
top: options.top,
options: R.merge(opt, options)
})
}, { bytecode }))
return Object.freeze({
encodeCall: (name, args) => this.contractEncodeCall(source, name, args, opt),
deploy: (init, options) => this.contractDeploy(bytecode, source, init, { ...opt, ...options }),
deployStatic: (init, options) => this.contractCallStatic(source, null, 'init', init, {
...opt,
...options,
bytecode
}),
bytecode
})
}

/**
Expand Down Expand Up @@ -467,7 +451,6 @@ export const ContractAPI = Ae.compose(ContractBase, ContractACI, {
contractCall,
contractEncodeCall,
contractDecodeData,
dryRunContractTx,
_handleCallError,
// Delegation for contract
// AENS
Expand Down
12 changes: 4 additions & 8 deletions es/contract/aci/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ const eventDecode = ({ instance }) => (fn, events) => {
}

const call = ({ client, instance }) => async (fn, params = [], options = {}) => {
const opt = R.merge(instance.options, options)
const opt = { ...instance.options, ...options }
const fnACI = getFunctionACI(instance.aci, fn, { external: instance.externalAci })
const source = opt.source || instance.source

Expand All @@ -172,10 +172,7 @@ const call = ({ client, instance }) => async (fn, params = [], options = {}) =>
) throw new Error(`You try to pay "${opt.amount}" to function "${fn}" which is not payable. Only payable function can accept tokens`)
params = !opt.skipArgsConvert ? await prepareArgs(fnACI, params) : params
const result = opt.callStatic
? await client.contractCallStatic(source, instance.deployInfo.address, fn, params, {
top: opt.top,
options: opt
})
? await client.contractCallStatic(source, instance.deployInfo.address, fn, params, opt)
: await client.contractCall(source, instance.deployInfo.address, fn, params, opt)
return {
...result,
Expand All @@ -184,7 +181,7 @@ const call = ({ client, instance }) => async (fn, params = [], options = {}) =>
}

const deploy = ({ client, instance }) => async (init = [], options = {}) => {
const opt = R.merge(instance.options, options)
const opt = { ...instance.options, ...options }
const fnACI = getFunctionACI(instance.aci, 'init', { external: instance.externalAci })
const source = opt.source || instance.source

Expand All @@ -193,8 +190,7 @@ const deploy = ({ client, instance }) => async (init = [], options = {}) => {

if (opt.callStatic) {
return client.contractCallStatic(source, null, 'init', init, {
top: opt.top,
options: opt,
...opt,
bytecode: instance.compiled
})
} else {
Expand Down

0 comments on commit f3ffb66

Please sign in to comment.