@aeternity/aepp-calldata

中文文档
1.10.0发布于 2026/10/27ISCTypeScriptESM + CJS构建来源已验证近 30 天下载 5532

Aeternity data serialization library

原始使用文档
文档目录16 节
  1. Installation
  2. Quick Start
  3. Encoding calldata
  4. Decoding call result
  5. Contract call errors
  6. Events
  7. Byte Arrays
  8. FATE API Encoder
  9. Contract Encoder
  10. Data types
  11. Versioning
  12. Public API
  13. Errors
  14. Development
  15. Install
  16. Tests

Aeternity data serialization

Aeternity contract calldata encoding and results decoding standalone library.

This is Javascript implementation of data serialization specified in aeternity protocol.

While the only purpose of the library at the moment of this writing is solely to provide encoding and decoding respectively of contracts calldata and return data it may evolve to full-fledged serialization library of the full protocol specification.

Installation

npm install -P @aeternity/aepp-calldata

Quick Start

To work with contract calls with type information provided by ACI the AciContractCallEncoder class should be used. The constructor takes a single argument - Sophia ACI as string.

NodeJS example:

const {AciContractCallEncoder} = require('@aeternity/aepp-calldata')
const ACI = require('./Test.json')
const CONTRACT = 'Test'

const encoder = new AciContractCallEncoder(ACI)

Encoding calldata

The encodeCall method is used to encode calldata taking the contract name as first argument, then function name and list of contract call arguments as last argument.

Example:

const encoded = encoder.encodeCall(CONTRACT, 'test_string', ["whoolymoly"])
console.log(`Encoded data: ${encoded}`)

Expected output:

Encoded data: cb_KxHwzCuVGyl3aG9vbHltb2x5zwMSnw==

Decoding call result

The decodeResult method is used to decode contract call result based on it's type. While the first two arguments are the same as the encoding method, the third one is the actual result to be decoded and last one is the result type which defaults to 'ok'.

Example:

const decoded = encoder.decodeResult(CONTRACT, 'test_string', 'cb_KXdob29seW1vbHlGazSE')
console.log(`Decoded data: ${decoded}`)

Expected output:

Encoded data: cb_KxHwzCuVGyl3aG9vbHltb2x5zwMSnw==
Decoded data: whoolymoly

Contract call errors

FATE contract call error message is represented as encoded contract bytearray (cb_ prefixed string). However, revert messages are FATE string encoded, so the decodeResult method accepts forth argument with the result type.

Example:

// error message
const error = encoder.decodeResult(
    CONTRACT,
    'test_string',
    'cb_VHlwZSBlcnJvciBvbiBjYWxsOiBbe2J5dGVzLDw8MjQwLDIsLi4uPj59XSBpcyBub3Qgb2YgdHlwZSBbe2J5dGVzLDMyfV3EtJjU',
    'error'
)
console.log('Error: ' + error)

// revert message
const revert = encoder.decodeResult(CONTRACT, 'test_string', 'cb_OXJlcXVpcmUgZmFpbGVkarP9mg==', 'revert')
console.log('Revert: ' + revert)

Expected output:

Error: Type error on call: [{bytes,<<240,2,...>>}] is not of type [{bytes,32}]
Revert: require failed

Events

Example:

const data = encoder.decodeEvent('Test', 'cb_dHJpZ2dlcmVk1FYuYA==', [
    34853523142692495808479485503424878684430196596020091237715106250497712463899n,
    17n
])
console.log(data)

Expected output:

{EventTwo: [17n, 'triggered']}

Byte Arrays

Any contract bytearray can be decocded using the ContractByteArrayEncoder class.

Node that FATE does not carry some of the type informaton with the data:

  • Record keys are lost
  • Variant constructor names are lost
  • Any user type information is lost
  • STL type information is lost: i.e. Chain, AENS, Set, BLS12_381

Example:

const {ContractByteArrayEncoder} = require('@aeternity/aepp-calldata')

const decodedString = encoder.decode('cb_KXdob29seW1vbHlGazSE')
console.log(`Decoded string: ${decodedString}`)

const decodedMap = encoder.decode('cb_LwEOfzGit9U')
console.log('Decoded map:', decodedMap)

Expected output:

Decoded string: whoolymoly
Decoded map: Map(1) { 7n => false }

The encoder could also work with explicit type information:

Example:

const {ContractByteArrayEncoder, TypeResolver} = require('@aeternity/aepp-calldata')

const encoder = new ContractByteArrayEncoder()
const resolver = new TypeResolver()

const decodedString = encoder.decodeWithType('cb_KXdob29seW1vbHlGazSE', resolver.resolveType('string'))
console.log(`Decoded string: ${decodedString}`)

const type = resolver.resolveType({map: ['int', 'bool']})
const encodedMap = encoder.encodeWithType(new Map([[7n, false]]), type)
console.log('Encoded map:', encodedMap)

Expected output:

Decoded string: whoolymoly
Decoded map: Map(1) { 7n => false }

FATE API Encoder

Any of the following FATE API data types can be encoded and decoded:

  • key_block_hash
  • micro_block_hash
  • block_pof_hash
  • block_tx_hash
  • block_state_hash
  • contract_bytearray
  • contract_pubkey
  • account_pubkey
  • account_seckey
  • channel
  • oracle_pubkey
  • oracle_query_id
  • peer_pubkey
  • name
  • tx_hash
  • signature
  • commitment
  • bytearray

Example:

const {FateApiEncoder} = require('@aeternity/aepp-calldata')
const encoder = new FateApiEncoder()

const encoded = encoder.encode('contract_bytearray', new Uint8Array())
console.log(`Encoded: ${encoded}`)

const decoded = encoder.decode('cb_Xfbg4g==')
console.log('Decoded:', decoded)

Expected output:

Encoded: cb_Xfbg4g==
Decoded: Uint8Array(0) []

Note that the encoder work with binary data, so that strings has to be encoded as Uint8Array.

String Example:

const textEncoder = new TextEncoder()
const textDecoder = new TextDecoder()

const encoded = encoder.encode('contract_bytearray', textEncoder.encode('whoolymoly'))
console.log(`Encoded: ${encoded}`)

const decoded = textDecoder.decode(encoder.decode('cb_d2hvb2x5bW9seeO2SW0='))
console.log('Decoded:', decoded)

Excepted output:

Encoded: cb_d2hvb2x5bW9seeO2SW0=
Decoded: whoolymoly

Contract Encoder

Decodes contract metadata including bytecode.

Example:

const {ContractEncoder} = require('@aeternity/aepp-calldata')
const encoder = new ContractEncoder()

const testContract = fs.readFileSync(path.resolve(__dirname, '../build/contracts/Test.aeb'))
const contract = encoder.decode(testContract.toString())

console.log('Contract:', contract)

Expected output (trimmed):

{
  tag: 70n,
  vsn: 3n,
  source_hash: 'e50758c624dcacd485db1f9e76208c5858dd968f6218637d055fd4a3b2850baa',
  aevmTypeInfo: [],
  compilerVersion: '6.1.0',
  payable: false,
  bytecode: {
    functions: [
      {
        id: '077a0e02',
        name: 'test_nested_list',
        attributes: [],
        args: {
          name: 'tuple',
          valueTypes: [
            {
              name: 'list',
              valuesType: { name: 'list', valuesType: { name: 'int' } }
            }
          ]
        },
        returnType: {
          name: 'list',
          valuesType: { name: 'list', valuesType: { name: 'int' } }
        },
        instructions: [
          [
            { mnemonic: 'RETURNR', args: [ { mod: 'arg', arg: 0n } ] }
          ]
        ]
      },
      .....
    ],
    symbols: {
      '67419061': 'test_unit',
      ....
    },
    annotations: Map(0) {}
  }
}

Please note that the bytecode is for debugging/print purposes and it's structure WON'T be kept backward compatible

Data types

Using the library involves data types and their mappings from Sophia to JavaScript and vice versa.

Sophia TypeSophia ExampleJavascript typeJavascript Example
int63, -63BigInt63n, -63n
booltrue, falseBooleantrue, false
string"whoolymoly"String"whoolymoly"
bytes#beefBigIntBigInt("0xbeef")
list[1, 2, 3, 5, 8, 13, 21]Array[1,2,3,5,8,13,21]
tuple(true, false)Array[true, false]
map{[7] = false}Map, Object, Arraynew Map([[7, false]]), {7: false}, [[7, false]]
record{x = 0, y = 0}Object (POJO){x: 0, y: 0}
variantSome(404), NoneObject (POJO){'Some': [404]}, {'None': []}, 404, undefined
bitsBits.none, Bits.all Bits.set(Bits.none, 0)BigInt0b0n, -1n, 0b00000001n
hash#001234dBigIntBigInt("0x001234d")
signature#001234dBigIntBigInt("0x001234d")
addressak_2gx9MEFxKvY9vMG5YnqnXWv1hCsX7rgnfvBLJS4aQurustR1rtStringak_2gx9MEFxKvY9vMG5YnqnXWv1hCsX7rgnfvBLJS4aQurustR1rt
Set.setSet.from_list([1, 2, 3])Set, Arraynew Set([1,2,3]),[1,2,3]
BLS12_381.frBLS12_381.int_to_fr(3735928559)BigInt3735928559n
BLS12_381.fpBLS12_381.int_to_fp(3735928559)BigInt3735928559n
  • note the fixed structure of variant object with a single key - the variant constructor (i.e. Some) and array of variant arguments as it's value.
  • while Javascript Number and primitive int types can be used as well when BigInt type is expected it's not recommended because of it's Number.MAX_SAFE_INTEGER limitation.

Versioning

This project follows the semantic versioning guidelines. Refer to the CHANGELOG for more information about releases.

Public API

The backward compatibility promise signaled with semantic versioning above is only applied to public API of this library, that is only the module exports and data types listed above.

The public API namely consist of below classes:

The public API is also defined in TypeScript declation file.

Errors

Error names are also part of the public API and it is guaranteed to get the same error name between compatible versions. Since error classes are not exported as public API, the library users should rely only on Error.name property to handle exceptions. Please also note that error messages are NOT part of the public API and they may change any time between versions without notice.

Development

Please make sure you get familiar with Contributing Guidelines first.

Install

npm install

Tests

Unit tests can be run with:

make tests

Integration tests:

make integration-tests

One can use the benchmarks to do relative comparison on performance for a given change:

make benchmark-tests

Verify browser compatibility with:

make browser-tests

To see the test coverage run:

make coverage

版本与发布记录

@aeternity/aepp-calldata 共发布 17 个版本,首次发布于 2021/08/04;过去 12 个月发布了 1 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.10.0latest2026/10/2711 天前
1.9.12024/12/091.9 年前
1.9.02024/11/291.9 年前
1.8.02024/08/142 年前
1.7.02024/04/032 年前
1.6.02024/01/232 年前

关于 @aeternity/aepp-calldata 的常见问题

@aeternity/aepp-calldata 是什么?

Aeternity data serialization library

如何安装 @aeternity/aepp-calldata?

在项目目录运行 npm install @aeternity/aepp-calldata,或使用 pnpm add / yarn add / bun add。

@aeternity/aepp-calldata 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@aeternity/aepp-calldata 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@aeternity/aepp-calldata 可以商用吗?

@aeternity/aepp-calldata 使用 ISC 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@aeternity/aepp-calldata 的下载量有多少?

根据 npm 官方下载统计,@aeternity/aepp-calldata 在 2026/10/05 – 2026/11/03 这 30 天内被下载 5,532 次,日均约 184 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@aeternity/aepp-calldata 还在维护吗?

最新版本 1.10.0 发布于 2026/10/27(11 天前);至今共发布 17 个版本,其中过去 12 个月发布了 1 个;首次发布于 2021/08/04。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。