Current section
Files
Jump to
Current section
Files
lib/sutra/uplc.ex
defmodule Sutra.Uplc do
@moduledoc """
Handle UPLC
"""
alias Sutra.Cardano.Gov
alias Sutra.Cardano.Gov.CostModels
alias Sutra.Cardano.Transaction
alias Sutra.Cardano.Transaction.{Input, Output, OutputReference, TxBody, Witness}
alias Sutra.Data
use Rustler, otp_app: :sutra, crate: "sutra_uplc"
def evaluate_raw(tx_cbor, inputs, %CostModels{} = cost_models, slot_config)
when is_binary(tx_cbor) do
utxos =
Input.sort_inputs(inputs)
|> Enum.map(fn input = %Input{} ->
{OutputReference.to_cbor(input.output_reference) |> CBOR.encode(),
Output.to_cbor(input.output) |> CBOR.encode()}
end)
cost_models_bytes = Gov.encode_cost_models(cost_models)
case eval_phase_two(
tx_cbor,
utxos,
cost_models_bytes,
# TODO: use from params
{10_000_000_000, 14_000_000},
slot_config
) do
{true, result} ->
# TODO: print logs
redeemers =
Enum.map(result, fn %{redeemer_info: r, logs: _logs} ->
{:ok, decoded, _} = :erlang.list_to_binary(r) |> CBOR.decode()
Witness.decode({5, decoded})
end)
{:ok, redeemers}
{false, error} ->
{:error, error}
end
end
def evaluate(
%Transaction{tx_body: %TxBody{inputs: inputs, reference_inputs: ref_inputs}} = tx,
cost_models,
slot_config
) do
ref_inputs = ref_inputs || []
tx
|> Transaction.to_cbor()
|> CBOR.encode()
|> evaluate_raw(inputs ++ ref_inputs, cost_models, slot_config)
end
# NIF function stub - actual implementation in Rust
def eval_phase_two(_tx_bytes, _utxos, _cost_models, _initial_budget, _slot_config),
do: :erlang.nif_error(:nif_not_loaded)
def do_apply_params_to_script(_script, _params), do: :erlang.nif_error(:nif_not_loaded)
def apply_params_to_script(script, params) when is_binary(script) do
# script_raw = Base.decode16!(script, case: :mixed)
encoded_params = Data.encode(params)
case do_apply_params_to_script(script, encoded_params) do
{true, applied_script} ->
:erlang.list_to_binary(applied_script) |> Base.encode16()
{false, error} ->
raise """
Apply params error
#{error}
"""
end
end
end