aiken_design_patterns/merkelized_validator

Since transaction size is limited in Cardano, some validators benefit from a solution which allows them to delegate parts of their logics. This becomes more prominent in cases where such logics can greatly benefit from optimization solutions that trade computation resources for script sizes (e.g. table lookups can take up more space so that costly computations can be averted).

This design pattern offers an interface for off-loading such logics into an external withdrawal script, so that the size of the validator itself can stay within the limits of Cardano.

Be aware that total size of reference scripts is currently limited to 200KiB (204800 bytes), and they also impose additional fees in an exponential manner. See here and here for more info.

Types

Datatype for a delegated validation. Compared to WithdrawRedeemerIO, this datatype only carries input argument(s), and simply validates whether the computation passes.

Constructors

  • WithdrawRedeemer { input_arg: a }

Datatype for redeemer of the “computation stake validator” to represent input argument(s) and output value(s).

As a simple example, a summation logic where it adds all its inputs together, can work with a redeemer of type WithdrawRedeemerIO<List<Int>, Int>, and a valid redeemer data would be:

let valid_summation_io =
  WithdrawRedeemerIO {
    input_arg: [1, 2, 3, 4, 5],
    result: 15,
  }

Constructors

  • WithdrawRedeemerIO { input_arg: a, result: b }

Functions

delegated_compute(
  function_input: a,
  staking_validator: ScriptHash,
  input_data_coercer: fn(Data) -> a,
  output_data_coercer: fn(Data) -> b,
  redeemers: Pairs<ScriptPurpose, Redeemer>,
) -> b

Given an arbitrary Data as input, this function expects to find a Withdraw script purpose in redeemers for staking_validator, with a redeemer of type WithdrawRedeemer<Data, Data>, which will be coerced into your custom datatypes using your provided Data validators (input_data_coercer and output_data_coercer).

delegated_validation(
  function_input: a,
  staking_validator: ScriptHash,
  input_data_coercer: fn(Data) -> a,
  redeemers: Pairs<ScriptPurpose, Redeemer>,
) -> Bool

Similar to delegated_compute, with the difference that now values are expected to be returned by the staking script.

withdraw_io(function: fn(a) -> b, redeemer: WithdrawRedeemerIO<a, b>) -> Bool

Helper function for defining your “computation stake validator.” The resulting stake validator will carry out the provided function’s logic, and redeemer must contain the input(s) and expected output(s).

withdraw(validation: fn(a) -> Bool, redeemer: WithdrawRedeemer<a>) -> Bool

Helper function for defining your delegated validation. The resulting stake validator will carry out the provided validation’s logic with given input(s) through its redeemer.

Search Document