Skip to content

JuLC API Reference

This document covers all supported Java operations in the JuLC compiler, the standard library functions, and the typed ledger access API.

Java Type UPLC Representation Notes
int, long, BigInteger Integer All mapped to arbitrary-precision integers
boolean Bool (Constr 0/1) false = Constr(0,[]), true = Constr(1,[])
byte[] ByteString Raw bytes
String String (UTF-8) Converted via EncodeUtf8/DecodeUtf8
PlutusData Data Opaque on-chain data
List<T>, JulcList<T> BuiltinList Builtin list of Data
Map<K,V>, JulcMap<K,V> BuiltinList(Pair) Map encoded as list of pairs
Optional<T> Constr 0/1 Some = Constr(0,[x]), None = Constr(1,[])
Tuple2<A,B> Constr(0, [a, b]) Generic pair with auto-unwrap
Tuple3<A,B,C> Constr(0, [a, b, c]) Generic triple with auto-unwrap
Records Constr(0, fields) Each field is a Data element
Sealed interfaces Constr(tag, fields) Tag based on permit order
@NewType records Underlying type Zero-cost alias (identity on-chain)
PubKeyHash, PolicyId, TokenName, TxId, ScriptHash, ValidatorHash, DatumHash ByteString Ledger hash types
Value Map(Pair) Named RecordType with instance methods
JulcArray<T> (PV11) BuiltinArray O(1) random access array (CIP-138). PV11+ only

JulcList<T> and JulcMap<K,V> are interfaces in julc-core/types/ that resolve to the same ListType/MapType as List/Map. They provide IDE autocomplete for on-chain methods (.contains(), .size(), .get(), etc.).

JulcList<PubKeyHash> signers = txInfo.signatories(); // typed list of PubKeyHash
JulcMap<Credential, BigInteger> withdrawals = txInfo.withdrawals();

Protocol Version 11+ only. Base Array operations use CIP-138 builtins and are not available on PV10 networks.

JulcArray<T> is an immutable array interface providing O(1) random access on-chain. Create from a list via list.toArray() or JulcArray.fromList(list).

JulcList<BigInteger> list = ...;
JulcArray<BigInteger> arr = list.toArray(); // ListToArray builtin
BigInteger elem = arr.get(0); // IndexArray builtin (O(1))
long len = arr.length(); // LengthOfArray builtin

Off-chain: backed by JulcArrayImpl, wrapping java.util.List with O(1) index access.

Builtins.multiIndexArray (tag 101, CIP-156) is a separate future/unreleased operation. It is not valid under Plutus V3/PV11, and the current compiler rejects it. Its retained experimental placeholder uses the legacy (array, indices) order rather than CIP-156’s proposed indices-first signature and is not a conformant preview. See the release notes for migration guidance.

Generic tuples with auto-unwrapping field access based on type arguments.

Tuple2<BigInteger, BigInteger> result = MathLib.divMod(a, b);
BigInteger quotient = result.first(); // auto-generates UnIData
BigInteger remainder = result.second(); // auto-generates UnIData
// Construction auto-wraps
var t = new Tuple2<BigInteger, BigInteger>(val1, val2); // auto-wraps via IData

Raw Tuple2 (no type args) defaults to DataType for backward compatibility. Tuple2/Tuple3 are not switchable (registered as RecordType, but switch requires SumType). Use field access instead.

Zero-cost type aliases for single-field records with a supported underlying type (byte[], BigInteger, String, boolean).

@NewType
public record AssetClass(byte[] policyId) {}
// On-chain: identity (no ConstrData wrap)
// AssetClass.of(bytes) is auto-registered

Seven ledger hash types have .of(byte[]) factory methods:

Type Usage On-chain
PubKeyHash.of(bytes) Create from raw bytes Identity
ScriptHash.of(bytes) Identity
ValidatorHash.of(bytes) Identity
PolicyId.of(bytes) Identity
TokenName.of(bytes) Identity
DatumHash.of(bytes) Identity
TxId.of(bytes) Identity

These replace the ugly (PubKeyHash)(Object) bytes casts in user code.

Signature On-chain Off-chain
PlutusData.cast(data, TargetType.class) Identity (zero cost) Unchecked cast

Replaces the (TargetType)(Object) data double-cast pattern. Works with records, sealed interfaces, ledger types, JulcMap, byte[], and hash types. The second argument must be a literal ClassName.class expression.

For generic collections (JulcList, JulcMap), use an explicit type declaration to preserve element types:

JulcList<MyRecord> items = PlutusData.cast(data, JulcList.class); // element type: MyRecord
JulcMap<BigInteger, MyRecord> m = PlutusData.cast(data, JulcMap.class); // typed keys + values
var items2 = PlutusData.cast(data, JulcList.class); // element type: DataType (avoid)

float, double, char, arrays (T[] — use JulcArray<T> on PV11+ or List<T>), null, collections other than List/Map/Optional/JulcArray, generic classes, inheritance (use sealed interfaces instead).

Operator Java Example UPLC Builtin Notes
+ a + b AddInteger For BigInteger/int/long operands
+ s1 + s2 AppendString For String operands
+ b1 + b2 AppendByteString For byte[] operands
- a - b SubtractInteger
* a * b MultiplyInteger
/ a / b QuotientInteger Truncates toward zero, matching Java
% a % b RemainderInteger

The + operator is type-aware: the compiler infers the operand type and dispatches to the correct builtin.

Operator Java Example UPLC Builtin Notes
== a == b EqualsInteger For BigInteger/int/long (default)
== s1 == s2 EqualsString For String operands
== b1 == b2 EqualsByteString For byte[] operands
== d1 == d2 EqualsData For PlutusData, records, sealed interfaces
== x == y IfThenElse For boolean operands
!= a != b negated equality Same type dispatch as ==
< a < b LessThanInteger
<= a <= b LessThanEqualsInteger
> a > b LessThanInteger (swapped)
>= a >= b LessThanEqualsInteger (swapped)
Operator Java Example UPLC Translation
&& a && b IfThenElse(a, b, false) (short-circuit)
|| a || b IfThenElse(a, true, b) (short-circuit)
! !a IfThenElse(a, false, true)
if (condition) {
return x;
} else {
return y;
}
return condition ? x : y;

Switch Pattern Matching (Sealed Interfaces)

Section titled “Switch Pattern Matching (Sealed Interfaces)”
sealed interface Action permits Deposit, Withdraw {}
record Deposit(BigInteger amount) implements Action {}
record Withdraw(BigInteger amount) implements Action {}
// In validator:
return switch (action) {
case Deposit d -> d.amount() > 0;
case Withdraw w -> w.amount() > 0 && hasSigner;
};

Switch expressions check exhaustiveness at compile time. All variants of the sealed interface must be covered. The default -> branch can be used as a catch-all for uncovered variants, but prefer explicit cases for clarity.

if (action instanceof Deposit d) {
return d.amount() > 0;
}

The pattern variable is bound when the instanceof test is the whole condition of an if statement outside a loop; elsewhere use a switch until #204. It may not reuse the name of a field or @Param (JULC0059).

boolean found = false;
for (var item : list) {
if (item == target) {
found = true;
}
}

Desugared to a recursive fold. Supports single/multi-accumulator, break, and nesting. See For-Loop Patterns.

BigInteger sum = 0;
BigInteger i = 0;
while (i < 10) {
sum = sum + i;
i = i + 1;
}

Desugared to tail-recursive call via Z-combinator.

C-style for(;;), do-while, try-catch-finally, throw, continue.

All variables are immutable (functional semantics). Reassignment is only supported inside for-each and while loop bodies (accumulator pattern).

// OK
BigInteger x = 42;
var y = x + 1;
// NOT OK - assignment not supported
x = x + 1;

The var keyword is supported and types are inferred from the initializer.

Records compile to Constr-encoded Data with fields in declaration order.

record VestingDatum(byte[] beneficiary, BigInteger deadline) {}
// Construction
var datum = new VestingDatum(pkh, 1000);
// Field access
byte[] b = datum.beneficiary();
BigInteger d = datum.deadline();

Static methods in the validator class (without @Entrypoint) are compiled as helper functions. Recursive helper methods use Z-combinator transformation.

@SpendingValidator
class MyValidator {
static boolean isPositive(BigInteger x) {
return x > 0;
}
@Entrypoint
static boolean validate(BigInteger redeemer, PlutusData ctx) {
return isPositive(redeemer);
}
}
ListsLib.any(list, x -> x > 0)
ListsLib.filter(list, x -> Builtins.unIData(x) > 100)
ListsLib.foldl((acc, x) -> acc + Builtins.unIData(x), BigInteger.ZERO, list)

Lambda bodies can be a single expression or a block:

ListsLib.filter(items, item -> {
var threshold = new BigInteger("100");
return Builtins.unIData(item) > threshold;
});

Equivalent instance method syntax (lambda types auto-inferred):

list.any(x -> x.compareTo(BigInteger.ZERO) > 0)
list.filter(x -> Builtins.unIData(x).compareTo(BigInteger.valueOf(100)) > 0)
// foldl is only available as ListsLib.foldl (no instance method)

When using ScriptContext as a parameter type, the compiler provides typed access to all ledger fields without manual Data decoding.

@Entrypoint
static boolean validate(MyDatum datum, PlutusData redeemer, ScriptContext ctx) {
TxInfo txInfo = ctx.txInfo();
PlutusData redeemer2 = ctx.redeemer();
ScriptInfo scriptInfo = ctx.scriptInfo();
// ...
}
Method Return Type Field Index Description
txInfo.inputs() List<TxInInfo> 0 Transaction inputs
txInfo.referenceInputs() List<TxInInfo> 1 Reference inputs
txInfo.outputs() List<TxOut> 2 Transaction outputs
txInfo.fee() BigInteger 3 Transaction fee (lovelace)
txInfo.mint() Value 4 Minted/burned value
txInfo.certificates() JulcList<TxCert> 5 Certificates
txInfo.withdrawals() JulcMap<Credential, BigInteger> 6 Reward withdrawals
txInfo.validRange() Interval 7 Validity time range
txInfo.signatories() JulcList<PubKeyHash> 8 Required signers
txInfo.redeemers() JulcMap<ScriptPurpose, PlutusData> 9 All redeemers
txInfo.datums() JulcMap<DatumHash, PlutusData> 10 Datum hash map
txInfo.txId() TxId 11 Transaction hash
txInfo.votes() JulcMap<Voter, JulcMap<GovernanceActionId, Vote>> 12 Governance votes
txInfo.proposalProcedures() JulcList<ProposalProcedure> 13 Proposal procedures
txInfo.currentTreasuryAmount() Optional<BigInteger> 14 Current treasury
txInfo.treasuryDonation() Optional<BigInteger> 15 Treasury donation
  • TxInInfo: outRef() (TxOutRef), resolved() (TxOut)
  • TxOut: address() (Address), value() (Value), datum() (OutputDatum), referenceScript() (Optional)
  • TxOutRef: txId() (byte[]), outputIndex() (BigInteger)
  • Address: credential() (Credential), stakingCredential() (Optional)
  • Credential: sealed interface with PubKeyCredential(byte[] hash) and ScriptCredential(byte[] hash)
  • OutputDatum: sealed interface with NoOutputDatum, OutputDatumHash(byte[]), OutputDatum(PlutusData)
  • ScriptInfo: sealed interface with MintingScript(byte[]), SpendingScript(TxOutRef, Optional), RewardingScript(Credential), CertifyingScript(BigInteger, TxCert), VotingScript(Voter), ProposingScript(BigInteger, ProposalProcedure)
  • Interval: from() (IntervalBound), to() (IntervalBound)
  • IntervalBound: boundType() (IntervalBoundType), isInclusive() (boolean)
  • IntervalBoundType: sealed with NegInf, Finite(BigInteger), PosInf
// Full typed chain from context to list methods
boolean hasSigner = ctx.txInfo().signatories().contains(datum.beneficiary());
Method Return Type UPLC Translation
.abs() BigInteger IfThenElse(x < 0, 0 - x, x)
.negate() BigInteger SubtractInteger(0, x)
.max(other) BigInteger IfThenElse(a < b, b, a)
.min(other) BigInteger IfThenElse(a <= b, a, b)
.equals(other) boolean EqualsInteger
.add(other) BigInteger AddInteger
.subtract(other) BigInteger SubtractInteger
.multiply(other) BigInteger MultiplyInteger
.divide(other) BigInteger QuotientInteger
.remainder(other) BigInteger RemainderInteger
.mod(other) BigInteger ModInteger
.signum() BigInteger IfThenElse chain
.compareTo(other) BigInteger IfThenElse chain
.intValue() int Identity
.longValue() long Identity
Method Return Type Description
.isEmpty() boolean Returns true if empty
.size() BigInteger Returns the number of elements
.head() T Returns the first element (decoded)
.tail() List<T> Returns the list without the first element
.get(index) T Returns element at index (decoded)
.contains(target) boolean Recursive search with type-aware equality
.reverse() List<T> Returns a reversed copy
.concat(other) List<T> Concatenates two lists
.take(n) List<T> Returns first n elements
.drop(n) List<T> Returns list after dropping first n elements
.prepend(elem) List<T> Prepends element with auto-wrap (BigInteger->IData, byte[]->BData, etc.)
.map(f) JulcList<PlutusData> Apply function to each element (wraps results to Data)
.filter(pred) JulcList<T> Keep elements matching predicate
.any(pred) boolean True if any element matches
.all(pred) boolean True if all elements match
.find(pred) T First matching element (error if none)

Chaining is supported: sigs.tail().isEmpty(), sigs.tail().contains(pkh).

foldl is only available as a static call (ListsLib.foldl), not as an instance method.

Method Return Type Description
.get(key) Optional<V> Lookup value by key
.containsKey(key) boolean Check if key exists
.size() BigInteger Number of entries
.isEmpty() boolean True if no entries
.keys() List<K> All keys as list
.values() List<V> All values as list
.insert(key, value) Map<K,V> Insert/update entry (returns pair list)
.delete(key) Map<K,V> Remove entry (returns pair list)

MapType variables always hold pair lists internally. insert and delete return pair lists (not MapData-wrapped).

Method Return Type Description
.lovelaceOf() BigInteger Extract ADA amount
.isEmpty() boolean True if value is empty
.assetOf(policy, token) BigInteger Extract specific token amount

Caveat: value.assetOf(policyId, tokenName) uses EqualsData internally. If policyId/tokenName are byte[] (ByteStringType), wrap with Builtins.bData() before passing.

Method Return Type Description
.key() K First element with auto-decode
.value() V Second element with auto-decode
Method Return Type UPLC Translation
.equals(other) boolean EqualsString
.length() BigInteger LengthOfByteString(EncodeUtf8(s))
Method Return Type UPLC Translation
.equals(other) boolean EqualsByteString
.length() BigInteger LengthOfByteString
.length BigInteger LengthOfByteString (field access form)
.hash() byte[] UnBData (for list iteration context)
Method Return Type Description
.isPresent() boolean True if Some (tag == 0)
.isEmpty() boolean True if None (tag == 1)
.get() T Unwrap the inner value (decoded)

Raw PlutusData variables support .equals() and ==/!= operators using EqualsData.

Import from org.julclang.stdlib.lib.* in validators. See Standard Library Guide for comprehensive documentation.

Method Args Description
signedBy(txInfo, pkh) TxInfo, ByteString Check if pkh is in signatories
getTxInfo(ctx) ScriptContext Extract TxInfo (legacy — prefer ctx.txInfo())
getRedeemer(ctx) ScriptContext Extract redeemer
getSpendingDatum(ctx) ScriptContext Extract optional spending datum
txInfoInputs(txInfo) TxInfo Get inputs list
txInfoOutputs(txInfo) TxInfo Get outputs list
txInfoSignatories(txInfo) TxInfo Get signatories list
txInfoValidRange(txInfo) TxInfo Get validity time range
txInfoMint(txInfo) TxInfo Get minted/burned value
txInfoFee(txInfo) TxInfo Get transaction fee
txInfoId(txInfo) TxInfo Get transaction hash
txInfoRefInputs(txInfo) TxInfo Get reference inputs
txInfoWithdrawals(txInfo) TxInfo Get withdrawals map
txInfoRedeemers(txInfo) TxInfo Get redeemers map
findOwnInput(ctx) ScriptContext Find the input being validated → Optional<TxInInfo>
getContinuingOutputs(ctx) ScriptContext Get outputs to same script → JulcList<TxOut>
ownInputScriptHash(ctx) ScriptContext Get script hash of own input → byte[]
findDatum(txInfo, datumHash) TxInfo, ByteString Lookup datum by hash
valueSpent(txInfo) TxInfo Total value of all inputs
valuePaid(txInfo, address) TxInfo, Address Value paid to an address
ownHash(scriptInfo) ScriptInfo Get own script hash
scriptOutputsAt(txInfo, hash) TxInfo, ByteString Outputs at script hash
listIndex(list, index) List, Integer Get element at index
trace(msg) String Emit trace message
Method Args Description
isEmpty(list) List Check if list is empty
length(list) List Count elements
head(list) List First element
tail(list) List Rest of list
reverse(list) List Reverse a list
concat(a, b) List, List Concatenate two lists
nth(list, n) List, Integer Get element at index
take(list, n) List, Integer First n elements
drop(list, n) List, Integer Drop first n elements
contains(list, elem) List, Data Check membership (EqualsData)
containsInt(list, n) List, Integer Check integer membership
containsBytes(list, bs) List, ByteString Check bytestring membership
hasDuplicateInts(list) List Check for duplicate integers
hasDuplicateBytes(list) List Check for duplicate bytestrings
empty() (none) Create empty list
prepend(elem, list) Data, List Prepend element to list
any(list, pred) List, Lambda True if any element matches
all(list, pred) List, Lambda True if all elements match
find(list, pred) List, Lambda Find first matching (Optional)
foldl(f, init, list) Lambda, init, List Left fold
map(list, f) List, Lambda Transform elements
filter(list, pred) List, Lambda Keep matching elements
zip(a, b) List, List Pair elements from two lists
Method Args Description
geqMultiAsset(a, b) Value, Value Multi-asset >= comparison
leq(a, b) Value, Value Multi-asset <= comparison
eq(a, b) Value, Value Multi-asset equality
isZero(value) Value Check if value is zero
singleton(policy, token, amount) BS, BS, Integer Create single-token value
negate(value) Value Negate all amounts
flatten(value) Value Flatten to list of triples
flattenTyped(value) Value Flatten to typed JulcList<AssetEntry>
add(a, b) Value, Value Add two values
subtract(a, b) Value, Value Subtract values
countTokensWithQty(mint, policy, qty) Value, BS, Integer Count tokens with exact quantity under policy
findTokenName(mint, policy, qty) Value, BS, Integer Find token name with exact quantity under policy
Method Args Description
lookup(map, key) Map, Data Lookup value by key
member(map, key) Map, Data Check key membership
insert(map, key, value) Map, Data, Data Insert/update entry
delete(map, key) Map, Data Remove entry by key
keys(map) Map Get all keys
values(map) Map Get all values
toList(map) Map Convert to pair list
fromList(list) List Convert pair list to map
size(map) Map Count entries
Method Args Description
txOutAddress(txOut) TxOut Get output address
txOutValue(txOut) TxOut Get output value
txOutDatum(txOut) TxOut Get output datum
outputsAt(outputs, address) List, Address Filter outputs by address
countOutputsAt(outputs, addr) List, Address Count outputs at address
uniqueOutputAt(outputs, addr) List, Address Get exactly one output at address
outputsWithToken(outs, pol, tn) List, BS, BS Filter by token
valueHasToken(val, pol, tn) Value, BS, BS Check if value has token
lovelacePaidTo(outputs, addr) List, Address Total lovelace to address
paidAtLeast(outs, addr, min) List, Address, Integer Check minimum payment
getInlineDatum(txOut) TxOut Get inline datum
resolveDatum(txOut, datumsMap) TxOut, Map Resolve datum (inline or by hash)
findOutputWithToken(outputs, scriptHash, policy, token) List, BS, BS, BS Find output at script address with specific token
findInputWithToken(inputs, scriptHash, policy, token) List, BS, BS, BS Find input at script address with specific token
Method Args Description
abs(x) Integer Absolute value
max(a, b) Integer, Integer Maximum
min(a, b) Integer, Integer Minimum
pow(base, exp) Integer, Integer Exponentiation
sign(x) Integer Sign (-1, 0, or 1)
floorDiv(a, b) Integer, Integer Floor division
floorMod(a, b) Integer, Integer Floor modulo
divMod(a, b) Integer, Integer Returns Tuple2(floor division, floor modulo)
quotRem(a, b) Integer, Integer Returns Tuple2(quotient, remainder)
expMod(base, exp, mod) Integer, Integer, Integer Modular exponentiation (PV11 only)

Use MathLib.floorDiv and MathLib.floorMod for BigInteger floor division. java.lang.Math.floorDiv and Math.floorMod are valid for normal Java int/long calls, but the JDK does not provide BigInteger overloads for those methods.

Method Args Description
between(interval, lower, upper) Interval, Integer, Integer Check if interval is within bounds
never() (none) Empty interval
isEmpty(interval) Interval Check if interval is empty
finiteUpperBound(interval) Interval Extract upper bound (if finite)
finiteLowerBound(interval) Interval Extract lower bound (if finite)
Method Args Description
verifyEcdsaSecp256k1(key, msg, sig) BS, BS, BS Verify ECDSA secp256k1 signature
verifySchnorrSecp256k1(key, msg, sig) BS, BS, BS Verify Schnorr secp256k1 signature
ripemd_160(bs) BS RIPEMD-160 hash

Note: sha2_256, sha3_256, blake2b_256, blake2b_224, keccak_256, and verifyEd25519Signature are available directly via Builtins.*.

Method Args Description
take(bs, n) BS, Integer Take first n bytes
lessThan(a, b) BS, BS Lexicographic less-than
lessThanEquals(a, b) BS, BS Lexicographic less-than-or-equal
integerToByteString(be, w, i) Bool, Integer, Integer Integer to byte string
byteStringToInteger(be, bs) Bool, BS Byte string to integer
at(bs, index) BS, Integer Get byte at index
cons(byte_, bs) Integer, BS Prepend a byte
slice(bs, start, length) BS, Integer, Integer Extract a slice
length(bs) BS Length of bytestring
drop(bs, n) BS, Integer Drop first n bytes
append(a, b) BS, BS Concatenate two bytestrings
empty() (none) Empty bytestring
zeros(n) Integer Bytestring of n zero bytes
equals(a, b) BS, BS Equality check
encodeUtf8(s) String Encode string to UTF-8 bytes
decodeUtf8(bs) BS Decode UTF-8 bytes to string
serialiseData(d) Data Serialize data to CBOR bytes
hexNibble(n) Integer Convert nibble (0-15) to hex ASCII code
toHex(bs) BS Convert bytestring to hex-encoded bytestring
intToDecimalString(n) Integer Convert integer to decimal digit bytestring
utf8ToInteger(bs) BS Parse UTF-8 decimal string to integer
Method Args Description
andByteString(pad, a, b) Bool, BS, BS Bitwise AND
orByteString(pad, a, b) Bool, BS, BS Bitwise OR
xorByteString(pad, a, b) Bool, BS, BS Bitwise XOR
complementByteString(bs) BS Bitwise complement
readBit(bs, index) BS, Integer Read single bit
writeBits(bs, indices, val) BS, List, Bool Write bits at indices
shiftByteString(bs, n) BS, Integer Shift by n bits
rotateByteString(bs, n) BS, Integer Rotate by n bits
countSetBits(bs) BS Count set (1) bits
findFirstSetBit(bs) BS Index of first set bit
Method Args Description
credentialHash(cred) Credential Extract hash from credential
isScriptAddress(addr) Address True if script address
isPubKeyAddress(addr) Address True if pub key address
paymentCredential(addr) Address Extract payment credential

BLS12-381 elliptic curve operations over the typed values JulcG1, JulcG2 and JulcMlResult (org.julclang.core.types; opaque, never byte[] or PlutusData). Base curve and pairing methods are available on PV10+; multi-scalar multiplication requires PV11 and takes the native lists JulcScalars and JulcG1Points/JulcG2Points built by Builtins.scalars, Builtins.g1Points/g2Points or decoded from Data lists by Builtins.scalarsFromList and Builtins.g1PointsFromCompressed/ g2PointsFromCompressed (ADR-047). See Standard Library Guide for full documentation.

Method Args Description
g1Add(a, b) G1, G1 Add two G1 elements
g1Neg(a) G1 Negate a G1 element
g1ScalarMul(scalar, g1) Integer, G1 Scalar multiplication of G1
g1Equal(a, b) G1, G1 Check G1 equality
g1Compress(g1) / g1Uncompress(bs) G1 / BS G1 compression
g1HashToGroup(msg, dst) BS, BS Hash to G1
g2Add, g2Neg, g2ScalarMul, g2Equal, g2Compress, g2Uncompress, g2HashToGroup — G2 equivalents
millerLoop(g1, g2) G1, G2 Compute Miller loop pairing
mulMlResult(a, b) ML, ML Multiply two Miller loop results
finalVerify(a, b) ML, ML Final pairing verification
g1MultiScalarMul(scalars, points) JulcScalars, JulcG1Points Multi-scalar multiplication on G1 (PV11 only)
g2MultiScalarMul(scalars, points) JulcScalars, JulcG2Points Multi-scalar multiplication on G2 (PV11 only)

PV11 target only. Native MaryEra Value operations use the opaque JulcValue type. It is not PlutusData or the ledger API’s Data-encoded Value; cross the representation boundary explicitly with fromData and toData. See Standard Library Guide for full documentation.

Method Args Description
insertCoin(policy, token, amount, value) BS, BS, Integer, Value Insert/update token quantity
lookupCoin(policy, token, value) BS, BS, Value Look up token quantity (0 if absent)
union(a, b) Value, Value Merge two Values by adding quantities
contains(a, b) Value, Value Check a >= b element-wise
scale(scalar, value) Integer, Value Scale all quantities
fromData(mapData) Data Convert Map-encoded PlutusData to native Value
toData(value) Value Convert native Value back to Map encoding
Annotation Target Description
@SpendingValidator Class Single-purpose spending validator
@MintingValidator Class Single-purpose minting validator
@WithdrawValidator Class Single-purpose withdrawal validator
@CertifyingValidator Class Single-purpose certifying validator
@VotingValidator Class Single-purpose voting validator
@ProposingValidator Class Single-purpose proposing validator
@MultiValidator Class Multi-purpose validator (handles multiple script purposes)
@Entrypoint Method Marks the validator entrypoint method
@Entrypoint(purpose = Purpose.MINT) Method Purpose-specific entrypoint for multi-validators
@Param Field Parameterized field applied at deployment
@OnchainLibrary Class Reusable library class (auto-discovered from classpath)
@NewType Class Zero-cost type alias for single-field records

The Purpose enum controls dispatch in @MultiValidator classes:

Value ScriptInfo Tag Description
Purpose.DEFAULT — Manual dispatch (user switches on ScriptInfo)
Purpose.MINT 0 MintingScript
Purpose.SPEND 1 SpendingScript
Purpose.WITHDRAW 2 RewardingScript
Purpose.CERTIFY 3 CertifyingScript
Purpose.VOTE 4 VotingScript
Purpose.PROPOSE 5 ProposingScript

Type-safe evaluator for testing individual on-chain methods without a full ScriptContext.

Factory methods:

Method Description
JulcEval.forClass(Class<?>) Load source from src/main/java
JulcEval.forClass(Class<?>, Path) Load source from custom root
JulcEval.forSource(String) Use inline Java source

Proxy mode:

var proxy = JulcEval.forClass(MyHelper.class).create(MyInterface.class);

Fluent call mode:

var result = JulcEval.forClass(MyHelper.class).call("methodName", arg1, arg2);

CallResult extraction:

Method Return Type
.asInteger() BigInteger
.asLong() long
.asInt() int
.asByteString() byte[]
.asBoolean() boolean
.asString() String
.asData() PlutusData
.asOptional() Optional<PlutusData>
.asList() List<PlutusData>
.as(Class<T>) T
.auto() Object
.rawTerm() Term

Supported argument types: BigInteger, int, long, boolean, byte[], String, PlutusData, PlutusDataConvertible

import org.julclang.onchain.annotation.*;
import org.julclang.onchain.ledger.*;
import org.julclang.core.PlutusData;
import java.math.BigInteger;
@SpendingValidator
class VestingValidator {
record VestingDatum(byte[] beneficiary, BigInteger deadline) {}
@Entrypoint
static boolean validate(VestingDatum datum, PlutusData redeemer, ScriptContext ctx) {
TxInfo txInfo = ctx.txInfo();
boolean hasSigner = txInfo.signatories().contains(datum.beneficiary());
boolean pastDeadline = datum.deadline() > 0;
return hasSigner && pastDeadline;
}
}