UPLC Converter¶
Overview¶
UPLC Converter is a tool that transpiles Untyped Plutus Core (UPLC) scripts to arithmetic circuits. It makes it possible to use UPLC scripts in the zkFold Symbolic framework on par with Symbolic smart contracts.
According to the Plutus Core specification, a UPLC program is a tree where nodes are UPLC terms. UPLC Converter recursively traverses the UPLC program and converts each term to the corresponding zkFold Symbolic expression.
The resulting Haskell expression is then converted to an arithmetic circuit using the zkFold Symbolic framework. The circuit outputs 1
if and only if the UPLC program executes successfully on the given input.
Specification¶
In this section, we describe the rules for converting UPLC terms to arithmetic circuits.
Variables¶
Every variable must first be defined in a \(\lambda\)-abstraction term. When we encounter a variable term, we look up the associatedSymbolicData
object in the environment that is defined as a Map
.
Constants¶
Every constant in UPLC is constructed using the predefined built-in types and type operators. All those types and type operators have their counterparts in Haskell base library. Thus, constants can be converted to SymbolicData
objects using the fromConstant
function.
Built-in functions¶
Every version of UPLC has a fixed set of built-in functions. We can, therefore, define zkFold Symbolic counterparts for each of them. For example, a UPLC built-in function ifThenElse
is converted to the function of the same name in zkFold Symbolic.
\(\lambda\)-abstraction¶
Lambda abstraction term adds a new variable to the environment and converts the body of the lambda term.
Function application¶
Function application term simply converts to the function application in Haskell.
m :: (SymbolicData x, SymbolicData y) => x -> y
n :: SymbolicData x => x
m n :: SymbolicData y => y
Delay and force¶
Delay and force implement type abstraction and type application in UPLC. They are skipped during the conversion process.
Error¶
Unlike with other terms, the error term cannot be directly converted to an expression in a statically typed language, such as Haskell. For example, in UPLC it can be used as an argument to a function that expects an integer or a list making it impossible to assign a type to such expression. The explicit usage of the error term is tricky for smart contract developers as the UPLC program may output an unexpected result due to the fact that the evaluation order is not clear from the program representation in a high-level language such as Aiken or PlutusTx. Luckily for us, the only real purpose of this term is to save some execution units for the Plutus CEK machine, which do not matter in the ZK smart contract verification. As a result, we prefer to explicitly forbid the usage of the error term in the convertible UPLC programs.
CLI Commands¶
Below we provide the list of available commands for UPLC Converter.
Convert UPLC to Circuit¶
The command expects the path to the input UPLC script in CBOR and the path to the output zkFold Circuit file. The output file will contain the generated arithmetic circuit.
Convert a Plutus V3 Script to a Symbolic Verifier Script¶
This command converts a Plutus V3 script to a Symbolic Verifier script. The input file should be a zkFold Circuit file, and the output file will contain the symbolic verifier script in CBOR.
Generate a Forwarding Script¶
This command generates a forwarding script that forwards the validation to the given UPLC script. The input file should be a zkFold Circuit file, and the output file will contain the symbolic verifier script in CBOR.