This project demonstrates an issue with Aiken validators where equality checks between datums fail when comparing canonical and non-canonical CBOR representations of the same data.
Aiken validators currently do not support checking equality while ignoring the CBOR data representation (canonical vs. non-canonical). This means that even though two datums represent the same logical data, they will be considered unequal if one is encoded in canonical CBOR format and the other is not.
This project consists of two packages:
A simple Aiken validator (canonical.ak) that checks that the input datum matches the continuing output datum. The validator uses a direct equality check (expect datum == output_datum) which fails when comparing canonical and non-canonical representations of the same data.
Contains a test suite that demonstrates the issue:
- Creates a UTxO at the script address with a non-canonical datum
- Attempts to consume that output with a continuing datum that is canonical
The test will fail with the trace: "Expect the input datum to match the output datum."
To build and run the test:
-
Navigate to the
packages/offchaindirectory:cd packages/offchain -
Install dependencies:
pnpm i
-
Run the test:
pnpm test
The test will fail, demonstrating that the Aiken validator cannot match datums that have the same logical content but different CBOR encodings.
The test (canonical.test.ts) works as follows:
-
Create a UTxO with non-canonical datum: An output is created at the script address with a datum serialized in non-canonical CBOR format (
datumN). -
Attempt to consume with canonical datum: The test attempts to consume that UTxO and create a continuing output with the same logical datum, but serialized in canonical CBOR format (
datumC). -
Validation fails: The Aiken validator's equality check (
datum == output_datum) fails because the CBOR representations differ, even though they represent identical data.
The test is expected to succeed, as we'd expect Aiken to ignore the comparison of the raw CBOR bytes, and instead compart the logical content of the data.
- Validator:
packages/onchain/validators/canonical.ak- The Aiken validator that performs the equality check - Test:
packages/offchain/tests/canonical.test.ts- The test that demonstrates the issue - Serialization:
packages/offchain/src/index.ts- Contains theserialiseCanonicalDatumfunction that can serialize datums in canonical or non-canonical format