diff --git a/examples/gift_card/validators/multi.ak b/examples/gift_card/validators/multi.ak
new file mode 100644
index 00000000..8c4b7894
--- /dev/null
+++ b/examples/gift_card/validators/multi.ak
@@ -0,0 +1,168 @@
+use aiken/bytearray
+use aiken/cbor
+use aiken/dict
+use aiken/hash.{blake2b_256}
+use aiken/list
+use aiken/transaction.{
+ InlineDatum, Input, Output, ScriptContext, Spend, Transaction,
+} as tx
+use aiken/transaction/credential.{Address, PaymentCredential, ScriptCredential}
+use aiken/transaction/value
+
+type Action {
+ Mint(Int)
+ Burn
+}
+
+type SpendTokenName =
+ ByteArray
+
+validator(creator: ByteArray) {
+ fn redeem(
+ // Each spend input checks for a token name matching the datum being burned
+ datum: SpendTokenName,
+ _r: Data,
+ ctx: ScriptContext,
+ ) {
+ let ScriptContext { transaction, purpose } =
+ ctx
+
+ let Transaction { inputs, mint, .. } =
+ transaction
+
+ expect Spend(own_ref) =
+ purpose
+
+ expect Some(own_input) =
+ list.find(inputs, fn(input) { input.output_reference == own_ref })
+
+ let Input {
+ output: Output { address: Address { payment_credential, .. }, .. },
+ ..
+ } =
+ own_input
+
+ expect ScriptCredential(own_validator_hash) =
+ payment_credential
+
+ value.quantity_of(mint, own_validator_hash, datum) == -1
+ }
+
+ fn gift_card(rdmr: Action, ctx: ScriptContext) -> Bool {
+ // get values from transaction and purpose
+ let ScriptContext { transaction, purpose } =
+ ctx
+
+ expect tx.Mint(policy_id) =
+ purpose
+
+ let Transaction { inputs, mint, extra_signatories, outputs, .. } =
+ transaction
+
+ let minted_assets =
+ mint
+ |> value.tokens(policy_id)
+ |> dict.to_list()
+
+ when rdmr is {
+ Mint(total) -> {
+ expect [input, ..] =
+ inputs
+ // Base is created from serializing a utxo ref being spent. Thus this guarantees a unique base
+ let base =
+ cbor.serialise(input.output_reference)
+ // Create a list of expected token names
+ let expected_minted_token_names =
+ create_expected_minted_nfts(base, total, [])
+ // Check contract creator is a signer of this tx
+ let signature_check =
+ list.any(extra_signatories, fn(n) { creator == n })
+ // Support multiple gift card creation by allowing a
+ // 'number of tokens minted' == 'outputs with datum being token name'
+ signature_check && check_mint_and_outputs(
+ minted_assets,
+ outputs,
+ expected_minted_token_names,
+ ScriptCredential(policy_id),
+ )
+ }
+ Burn ->
+ list.all(
+ minted_assets,
+ fn(asset) {
+ let (_, amount) =
+ asset
+ amount == -1
+ },
+ )
+ }
+ }
+}
+
+fn insert(self: List, e: a, compare: fn(a, a) -> Ordering) -> List {
+ when self is {
+ [] ->
+ [e]
+ [x, ..xs] ->
+ if compare(e, x) == Less {
+ [e, ..self]
+ } else {
+ [x, ..insert(xs, e, compare)]
+ }
+ }
+}
+
+// Check each minted token name is in the expected list, has quantity of 1,
+// and has a corresponding ouput with datum containing token name.
+// Otherwise fail
+fn check_mint_and_outputs(
+ minted_assets: List<(ByteArray, Int)>,
+ outputs: List