Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CIP-???? | On-Chain Parameter Application #934

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions CIP-param-application/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
---
CIP: ????
Title: On-Chain Parameter Application
rphair marked this conversation as resolved.
Show resolved Hide resolved
Status: Proposed
Category: Plutus
Authors:
- Philip DiSarro <[email protected]>
- Keyan M. <[email protected]>
- Microproofs <[email protected]>
Implementors: []
Discussions:
- https://github.com/cardano-foundation/CIPs/pull/934/
Created: 2024-11-06
License: CC-BY-4.0
---

## Abstract
We propose a new Plutus builtin function `builtinApplyParams` with the
signature `BuiltinByteString -> [BuiltinByteString] -> BuiltinByteString` in
order to enable simple and low cost on-chain check for validating instances of
unapplied scripts.

## Motivation: why is this CIP necessary?
Complex contracts tend to depend on multiple scripts, and in some cases,
validation from scripts with some unknown parameters are required.

As a simple example, assume a minting script which needs to validate that the
destination of its token is a parameterized spending script that is uniquely
instantiated for a user.

The [current solution](#alternatives), is costly and relatively complex. With
our proposed builtin function, the minting script of the example above can
be provided with the unapplied script (either directly or indirectly), and have
arbitrary values applied to it as parameters.

## Specification

### Function Definition

We propose the Plutus builtin function `builtinApplyParams`, with the following
type signature:
```hs
builtinApplyParams :: BuiltinByteString -> [BuiltinByteString] -> BuiltinByteString
```

Where the first argument is the unapplied script's CBOR, and
the `BuiltinByteString` list is CBOR bytes of all the parameters that are to be
applied in order. Finally, output will be the fully/partially applied script
CBOR.


### Cost Model

TODO
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder what the impact here would be, since this suggested built-in is effectively running the plutus machinery inside an already running instance of it.

My intuition tells me that this is okay, since the complexity of this calculation is always bound by the complexity of any possible other script. But looking forward to more insight from @kwxm :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also tagging @bezirg for his opinion



## Rationale: how does this CIP achieve its goals?

Using the [provided example](#motivation-why-is-this-cip-necessary), the minting
script can have access to the unapplied script:
* Either by direct inclusion as a parameter (which can lead to a large script size)
* Or providing a UTxO as a parameter that houses the unapplied script so that
the minting script can read it without becoming excessively large

Furthermore, arbitrary parameters can be provided via the redeemer which can be
used to generate an instance's script hash.

In short, we'll get:
* Easier and cheaper parameter verification on-chain
* A more automation-friendly build for such architectures
* Less error prone builds

### Alternatives

Implementing such a validation on-chain would involve a few steps.

First, the whole target contract has to be wrapped within an outer function
which the parameters will be applied to. This leads to single occurances of
the parameters throughout the script's CBOR.

Secondly, each parameter will be required to have fixed lengths in order to
allow validation of the bytes surrounding parameters. This can be achieved by
assuming these parameters are all hashes, and that their corresponding values
will be provided via the redeemer.

Next, in order to validate a given script is an instance of a known script,
first bytes of an instance must be provided (up until where the parameters are
placed). With this "prefix" at hand, the instance's CBOR can be constructed
on-chain as such:
```hs
let appliedCBOR =
prefix <> param0 <> paramHeader <> param1 <> paramHeader <> param2 <> postfix
```

Where `postfix` is similar to `prefix`, but for the rest of the script until its
end. Note that `paramHeader` can be reused based on the presumption that all
parameters are of equal lengths.

Finally, this `appliedCBOR` can be hashed to attain its corresponding script
credential.

## Path to Active

### Acceptance Criteria
- [] Fully implemented in Cardano.

### Implementation Plan
- [] Passes all requirements of both Plutus and Ledger teams as agreed to improve Plutus script efficiency and usability.

## Copyright
This CIP is licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode).

[CC-BY-4.0]: https://creativecommons.org/licenses/by/4.0/legalcode
[Apache-2.0]: http://www.apache.org/licenses/LICENSE-2.0