policy object ergonomics — property access, asset binding, and auto-witness
Summary
The policy constructor supports hash, script, and ref fields, but these fields are currently only used as metadata in the TII output. They can't be referenced from expressions, can't be used in asset definitions, and aren't leveraged by the compiler to reduce boilerplate. This makes the constructor form only marginally more useful than the assign form (policy X = 0x...).
Current behavior
policy NativeScriptPolicy {
hash: 0xbd3ae991...777,
script: 0x820181820400,
}
// Can't reference the policy name in asset definitions
asset NativeToken = NativeScriptPolicy."NATIVE"; // ERROR: invalid type (Undefined)
asset NativeToken = 0xbd3ae991...777."NATIVE"; // must repeat the hex literal
// Can't access sub-fields in expressions
cardano::native_witness {
script: NativeScriptPolicy.script, // ERROR: not in scope: script
script: 0x820181820400, // must repeat the hex literal
}
// Policy name resolves to hash in expressions (this works)
mint {
amount: AnyAsset(NativeScriptPolicy, "NATIVE", 10), // OK — resolves to hash
}
This means that when defining a policy with script: or ref:, the user must manually repeat those same values in asset definitions, cardano::native_witness, cardano::plutus_witness, and reference blocks. The policy object doesn't reduce duplication.
Missing validation: policy constructor without hash passes check but crashes build
The grammar allows a policy constructor with any subset of fields, so this is valid syntax:
policy ScriptOnly {
script: 0x820181820400,
}
trix check passes — the analyzer doesn't validate that hash is present. But trix build panics at the lowering stage:
called `Result::unwrap()` on an `Err` value: InvalidAst("Missing policy hash")
The analyzer should either:
- Require
hash in every policy constructor and emit a diagnostic if it's missing, or
- Derive the hash from the script CBOR when only
script is provided (which would also address the ergonomic gap of needing to know/specify both)
Proposed improvements
Workaround
Today, users must duplicate hex literals across the policy definition and the tx body. The policy_variants.tx3 example documents this pattern with comments explaining the limitation.
Context
Discovered while auditing example coverage for all grammar features. The policy_def_constructor grammar rule supports subsets of fields (hash-only, hash+script, hash+ref), but the value of defining these extra fields is limited without being able to reference them.
policyobject ergonomics — property access, asset binding, and auto-witnessSummary
The
policyconstructor supportshash,script, andreffields, but these fields are currently only used as metadata in the TII output. They can't be referenced from expressions, can't be used inassetdefinitions, and aren't leveraged by the compiler to reduce boilerplate. This makes the constructor form only marginally more useful than the assign form (policy X = 0x...).Current behavior
This means that when defining a policy with
script:orref:, the user must manually repeat those same values inassetdefinitions,cardano::native_witness,cardano::plutus_witness, andreferenceblocks. The policy object doesn't reduce duplication.Missing validation: policy constructor without
hashpassescheckbut crashesbuildThe grammar allows a policy constructor with any subset of fields, so this is valid syntax:
trix checkpasses — the analyzer doesn't validate thathashis present. Buttrix buildpanics at the lowering stage:The analyzer should either:
hashin every policy constructor and emit a diagnostic if it's missing, orscriptis provided (which would also address the ergonomic gap of needing to know/specify both)Proposed improvements
hashfield in analyzer — A policy constructor withouthashshould produce a clear error attrix checktime, not a panic attrix buildtimeMyPolicy.hash,MyPolicy.script,MyPolicy.refas expressions so policy fields can be referenced without repetitionassetdefinitions accept policy names —asset Token = MyPolicy."NAME"should resolveMyPolicyto its hash, the same wayAnyAsset(MyPolicy, ...)already does in tx bodiesassetdefinitions accept env vars —asset Token = my_env_var."NAME"currently fails type resolution whenmy_env_varis aBytesenv varmintreferencing a policy that has ascript:field, it could automatically inject the correspondingcardano::native_witnessorcardano::plutus_witnessblock. Similarly forref:andreferenceblocks. This would be the biggest ergonomic win but also the most complex change.Workaround
Today, users must duplicate hex literals across the policy definition and the tx body. The
policy_variants.tx3example documents this pattern with comments explaining the limitation.Context
Discovered while auditing example coverage for all grammar features. The
policy_def_constructorgrammar rule supports subsets of fields (hash-only, hash+script, hash+ref), but the value of defining these extra fields is limited without being able to reference them.