add cip-118

This commit is contained in:
waalge 2025-07-22 14:46:45 +00:00
parent 62b4aa0523
commit 960e6c478a
7 changed files with 418 additions and 117 deletions

316
content/posts/cip-118.md Normal file
View File

@ -0,0 +1,316 @@
---
title: "CIP 118: Too much solution for not enough need"
date: 2025-07-21
---
## Abstract
CIP 118 fails to demonstrate sufficient need for the ledger changes it proposes.
The use cases CIP 118 cites can already be supported.
No evidence is provided that the specific contexts which cannot be supported are critical,
nor is there an attempt to quantify the claimed performance improvements.
Accepting CIP 118 will not only add to ledger complexity,
it is an open invitation for a series of subsequent ledger changes,
both tweaks and fixes of missteps, and as more of the inexhaustible list of intents
gets shoe horned in.
Efforts and energies would be much better spent making accessible and utilizing what we already have.
## Context
### Of the CIP
CIP 118 proposes ledger changes to accommodate "nested transactions". At
present, a participant of a transaction must sign the transaction body, complete
byte for byte. With CIP 118, a participant could provide witness to an "intent"
or "subtransaction". A subtransaction does not need to follow the same ledger
rules as a transaction. For example, a subtransaction does not need to be
balanced.
### Of the author
All solutions worth the time of day ought to be solving actual problems. It may
be highly subjective as to whether or not something is a problem. Some say
feature others say bug. Even if we agree that something is a problem, we may
still disagree on its relative severity. What to me is a mild annoyance, may to
you be an absolute deal breaker.
The problems I think are the ones most worth solving are generally the ones that
have caused me the most trauma. While it is not so hard to extrapolate from
personal experience and otherwise sympathize with other people's problems, it is
harder to judge their relative severity, and thus a solution's relative
importance.
While working on Cardano, designing dapps, I have no shortage of pain points to
point at. I have spent relatively little time architect-ing systems that might
be described as something along the lines of "singular, many to many". Token
swaps would be an example: a participant wishes to partake in a singular event,
potentially with any other participant(s). By the end of the transaction, a user
has no further expectation of, nor obligations to, other users. I have spent
much more time thinking about "on-going, few to few" systems such as Lightning
Networks, where engagements are p2p enduring and with only a small subset of the
overall network, or Subbit.xyz, where a consumer pays their provider repeatedly
over a long period of time.
### Of the piece
This piece came about in preparation to participating in
[this](https://www.youtube.com/watch?v=p8uJ_4ydoBU) roundtable discussion.
## Main
Making ledger changes is not something to be undertaken lightly. One should ask:
1. Is the problem addressed sufficiently important?
2. Does the proposal adequately address the problem(s) claimed?
3. What are other consequences of the proposal?
4. What are the alternatives?
The following is mainly concerned with question one, with three and four
considered in passing. We do not dwell on question two.
### Use cases can already be accommodated
It is immediate that any unsafe behavior found in the ledger is a problem
sufficiently important that the ledger ought to be changed. For example, a way
to submit transactions that can result in a DDOS style attack. The case for a
set of ledger changes that only add or augment features and functionality is
much less immediate, and should be demonstrated with receipts.
The use cases cited by the proposal can be feasibly accommodated with the
current ledger rules. The proposed use cases are outlined in a
[CPS](https://github.com/cardano-foundation/CIPs/pull/779), referenced in
CIP 118. They are: atomic swaps including limit orders, market orders, and babel
fees; dapp fee sponsorship; and access to yet to be determined data. Some
implementations, albeit nascent, are or will soon be available (Aquarium,
Bullet).
CIP 118 is not sufficiently explicit which characteristics of the use cases the
authors deem necessary to support. For example, if it includes that a user must
be able to spend a UTXO at a payment key address with only a partial witness,
then a ledger change is of course necessary. If this requirement is relaxed by,
say, we can assume it is a validator address, or there can be some multi step
communication between parties, then such functionality can be supported without
ledger changes, as it is in the aforementioned examples.
At the time of writing the proposal states:
> There are off-chain solutions being developed for the purpose of achieving the
> same (major) goals, including fee coverage, atomic swaps, DApp fee
> sponsorship, collateral sponsorship, etc.
This seems reasonable, but its continuation is more moot:
> This gives us indication that it is a worthy pursuit to solve this problem at
> the ledger level, in a way that is cheaper, more convenient, maintains formal
> guarantees, requires less off-chain communication, and does not require
> deposits or interaction with smart contracts.
This is insufficient. All dapp logic can be cheaper, more convenient, _etc_ if
it is written into the ledger.
Token swapping is dominant because we can already do it relatively well, and we
still find other applications very hard to build. In some respect the "singular,
many to many" paradigm is what L1s are designed to handle. You are free to send
funds to anyone and they to you, but its expensive and slow - a necessary
consequence of a secure, decentralised system. (Insert joke here about mockchain
that solves the blockchain trilemma.) Token swapping is one of the few problems
for which we've actually got some solutions. Not perfect (too centralised, too
siloed, too expensive, _etc_), but they exist. Moreover, any such problem could
be solved with vanilla transaction signatures, tooling permitting. Meanwhile,
"on-going, few to few" paradigms have so much potential that is being stifled by
other problems.
Neither of us are providing receipts for our contradictory interpretation of the
dominance of token swapping. The difference is, this is not a CIP.
The onus is on the proposers to make a strong case that either there is some
specific formulation of the use case that is not currently supported and is
critical, or that the proposal will make game changing improvements to what is
already feasible. Neither of these are presented.
### Complexity is the root of some evil
When building software, the primary questions are commonly "what happens if
...". The difficulty to address these questions is directly related to the
scope/ complexity of the execution context. For Cardano dapps, the Plutus script
context has been kept intentionally narrow (ie simple) so that answering "what
happens if ..." questions remains manageable. It is still wide enough to build
many many things.
Each change to the ledger generally increases complexity. Backwards
compatibility is supposedly a must: if the Plutus Code runs today, it should run
"forever". There are many terms and conditions applied to this. The legacy of
Byron has been a ball and chain on many a tool developers' foot. Two different
types of address, different rules on transaction logic _etc_. Since Vasil, we
have two different ways to handle datum; with Chang, three. The more cases that
need to be handled, the more code is needed to the handle them, the higher the
maintenance burden and the higher cognitive load when reasoning about them.
We do not always have the luxury to restrict the aspects of the ledger we are
concern with. When building from scratch and no need to interop with existing
scripts, we likely do have this luxury. We'll use the newest version of Plutus,
and have no concern about what came before. But what happens if the tool we want
to build is a general transaction composer to reduce user fees and chain
traffic? What happens if we're trying to build an application, that will consume
funds from an existing validator address? These are not very exotic examples,
and the differing versions and behaviours are now our problems. What happens if
someone did compose a Plutus V3 and Plutus V4 script in a single transaction? It
couldn't be a nested transaction, but a normal one? An intent might cover
burning tokens, but now the end user, and/ or the tooling, need to know to
handle these different cases. Complexity can grow exponentially, and erodes
confidence that we have made the right assumptions or reasoned correctly.
A ledger change proposal must justify the complexity cost they will "forever"
leave with maintainers and developers.
### Justifying previous changes
There have been multiple previous changes to the ledger. How do previous changes
compare to CIP 118 in terms of scale of problem, and scale of ledger change?
Let's consider Vasil. Three CIPs implemented in Vasil include 31 Reference
Inputs, 32 Inline Datums, and 33 Reference Scripts. Claim: The change was demand
led, it addressed a fundamental and widely shared problem, and it was a
relatively small perturbation of the current design.
The changes were user demand led. Transaction size was **the** bottleneck and it
was for everyone. Transaction size still is frequently the bottleneck in
applications. Of course, one can produce scripts that exhaust ex units, but in
my experience once other factors are optimized for, the hard bound is often the
transaction size. It is still the case that a medium complexity script will
easily be three quarters of the max transaction size.
CIP 31 purportedly addressed the problem of broadcasting state. Plutus script
execution is narrow. When an application needed data from the chain, it has to
be included in the form of spending an input. This was awkward when it came to
making the same state available to concurrent transactions. CIP 31 provided a
much easier and cheaper mechanism for broadcasting state in this sense. The
transaction referencing the input pays in fees and bytes only a fraction of what
it would otherwise cost, particularly with CIP 32.
CIP 32 purports to address the inconvenience caused by the former design's
support only of datum hashes at tip. Quote: "This is also inconvenient for the
spending party, who must watch the whole chain to spot it.". Were it not for CIP
31, then I would find this argument incredibly weak. Without CIP 31 but with CIP
32, this is simply a tooling issue. To create a transaction, a user already
needs access to the chain via functions `getUtxosAtTip` and `submitTx`. Having
another `getDatumByHash` is not a big deal. With CIP 31 but without CIP 32, the
referencing transaction would also need to include the datum as part of the
redeemer which would then be hashed, and then matched with that of the
referenced inputs datum hash. With both CIP 31 and 32, a referencing transaction
does not pay in fees nor bytes for the inclusion of the datum, and the
additional logic is avoided.
CIP 33 allowed scripts to be referenced, rather than having to be included in
the transaction. As mentioned, scripts can easily exhaust most if not all the
transaction size limit. Referencing scripts dramatically reduces the size of
script heavy transactions.
The ledger changes in Vasil were a small perturbation of what had come before.
CIPs 32 and 33 did not introduce new functionality in and of themselves. They
shifted the need to provide data from the transaction submitter, to the
verifying Cardano node. Nodes already did recall for transaction inputs. Adding
recall for datums and scripts adds a little extra workload to the nodes. It
unlocked new functionality, only in the sense that the same transaction could be
much smaller. It also had network performance benefits with respect to
potentially higher effective throughput, and/or lower bandwidth and storage
requirements. CIP 31, is arguably a slightly larger perturbation than the other
two with respect to ledger design change. It is still, however, small.
A brief comparison with Chang and the changes introducing governance: Chain
governance has long been a key milestone in the vision of Cardano. In many ways
Cardano's focus on governance is the USP in an oversaturated sea of competitor
cryptocurrencies. Governance could not have been reasonably implemented without
substantial changes to ledger rules. These changes are justified because of the
significance of the capability they introduced.
### Ledger change record is wanting
It is a direct trade-off: additional functionality (complexity); additional ways
to shoot yourself in the foot. We do not have a stellar record when it comes to
ledger changes. There are multiple cases in which ledger designs were introduced
only to be deemed incorrect. We list a few.
The Alonzo hardfork brought Plutus v1. Plutus V1 permitted a mint value that had
a zero entry for ada. This is confusing because ada is impossible to mint by
smart contract. A correction was later pushed through.
Plutus v1 permitted 0 value withdraws. It was proposed by the ledger maintainers
that this mistake ought to be fixed, only for it to be pointed out that such a
change would have broken a bunch of dapps.
Reference scripts were introduced in Vasil. They left open a moderate attack
vector resulting in a DDOS attempt. A fix was pushed through in which the new
fee calculation was, afaics, whatever the Haskell code said it was. Reference
inputs were introduced in Vasil. In either Chang 1 or Plomin, these were "fixed"
to prevent an input being both referenced and spent. This broke a dapp I had
previously written.
It is unrealistic to believe there won't ever be mistakes. It is moot whether
these mistakes, or "mistakes", were preventable had more consideration been
given to the changes. Perhaps if there was more demand and more demand driven
development, then these problems might have been addressed before they reached
mainnet.
### Current ledger assumptions are still un- or underdocumented
It is a misdiagnosis to read the lack of products and solutions as the lack of
supported functionality at the ledger level. Cardano development is notorious
for the fraught difficulty it entails. The current ledger assumptions are still
un- or underdocumented. This is a massive hole, down which developers sink their
valuable time. Time that could be spent making better tooling and better
product.
Cardano developers seemingly must perform a rite of passage. Through their own
painful journey each will learn: inputs are lexicographically ordered and lists
are encoded as indefinite length. They will mull:
- Is this fixed behaviour I can rely on or an implementation quirk?
- Where are the docs on the datum integrity hash computation, for which version?
- Which version of Plutus and the ledger was it that the mint value stop
including ada?
There are probably a few dozen people who would be able to answer these. They
would do so with ease since the knowledge gained though trauma is written into
cerebral scar tissue. For everyone else, bon courage: the answers are in Github
issues, dangling code comments, and code itself. Before we dig this hole still
deeper by adding further to ledger complexity, we ought to prioritise
documenting its current behaviour, in a way developers can self serve.
### Systems of intents are always incomplete
CIP 118 would open us up to an never ending drip of ledger changes,
each bringing additional intents yet supported. CIP 118, does not limit us: any
intent not supported can be expressed in an invoked Plutus script. However, I'm
not confident that interested parties would not lobby to have their particularly
favoured intents entrenched in the ledger. Were CIP 118 to be accepted, the bar
for inclusion would seem to be relatively low.
Intents are often an excellent abstraction. The code can clearly communicate the
consequences of the logic they represent, even to non-experts, which is a
particularly admirable goal in relation to smart contracts. A key reason why I
used Plutus Apps long after many others had abandoned it was that its system of
intents (constraints in their vernacular) resulted in code that was far clearer
to a keen reader compared to the few alternatives we had at the time (eg
Plutarch).
Intents are never complete. Until it was abandoned, the list of supported
intents in Plutus Apps kept growing. Worse still, it was not designed to be
extensible. If the logic you required was not supported by the intents exposed,
you were left to fork the repo and add your own. In the long ago era, when I
used Plutus Apps this became my problem when the intents did not support
addresses with stake credentials. It was a massive time sink. I am highly wary
of libraries that use system of intents that aren't extensible via, say, the use
of Rust traits or Haskell classes pattern. Every system of intents I have seen
has grown the list of things it originally intended to support. As addressed,
CIP 118 is extensible via Plutus but in this way it creates a two tier system.
It seems inevitable there would forever be pressure to grow the list of ledger
supported intents.
## Conclusion
CIP 118 needs to make a stronger case that it's a solution worth implementing. I
am skeptical this can be made, but would be happily proved wrong. It would be
far more beneficial to put the efforts and energies that would be spent on
implementing CIP 118 on improving the tooling and accessibility around the
functionality we already have.

View File

@ -5,11 +5,10 @@ status: published
---
There are a collection of disparate thoughts on what makes for good design that
inform the decisions we make when designing dapps.
We thought it helpful to articulate them for ourselves, for any future
collaborators, and any wider audience interested.
These thoughts are expressed as diktats but are intended as perspective
from which to pick through there shortcomings.
inform the decisions we make when designing dapps. We thought it helpful to
articulate them for ourselves, for any future collaborators, and any wider
audience interested. These thoughts are expressed as diktats but are intended as
perspective from which to pick through there shortcomings.
These "principles" don't fit neatly into some SOLID like framework. Some are
high-level general security concious software dev stuff, others are quite
@ -39,9 +38,8 @@ ledger, "dapps". Typically the term has other assumptions: a decentralised
application should be run-able by anyone with internet access, reasonable
hardware, and without need to seek permission from some authority.
On-chain code takes form as Plutus validators. Writing validators as
**extreme programming**.
Lets immediately disambiguate with the [XP methedology][xp-wiki].
On-chain code takes form as Plutus validators. Writing validators as **extreme
programming**. Lets immediately disambiguate with the [XP methedology][xp-wiki].
It's extreme in the sense that it is highly unusual.
[xp-wiki]: https://en.wikipedia.org/wiki/Extreme_programming
@ -113,9 +111,9 @@ On-chain code **is** responsible for keeping the user safe from others. It is
its fundamental responsibility.
On-chain code is **not** responsible for keeping the user safe from themselves.
A user can compromise themselves completely and totally by, say, publishing their signing key,
voiding any guarantees provided by on-chain code.
Thus such guarantees are generally superfluous.
A user can compromise themselves completely and totally by, say, publishing
their signing key, voiding any guarantees provided by on-chain code. Thus such
guarantees are generally superfluous.
Off-chain code is responsible for keeping the user safe, and it is off-chain
code that should make it hard for them to shoot themselves in the foot.
@ -126,22 +124,23 @@ stop responding for legitimate or malicious reasons. We do not need to
speculate; we need only ensure that the other partner's funds are safe and can
be recovered.
Suppose there is a dapp that requires the depositing of funds, with a pathway in which the funds
may be returned. Further, that this return is verified by a signature belonging
associated to key provided by the depositor.
Suppose there is a dapp that requires the depositing of funds, with a pathway in
which the funds may be returned. Further, that this return is verified by a
signature belonging associated to key provided by the depositor.
Some may wish on-chain code to check everything it is possible to check.
This includes keeping the user safe from themself.
From this perspective the validator should
have a constraint that this key has signed the tx, verifying that the depositor
has the associated signing key.
Some may wish on-chain code to check everything it is possible to check. This
includes keeping the user safe from themself. From this perspective the
validator should have a constraint that this key has signed the tx, verifying
that the depositor has the associated signing key.
According to this principle, the validator should not.
The larger code base should.
The documentation should be crystal clear what this key is for and how it should be managed.
But the on-chain code should be solely focused on keeping the user safe from others, and other from the user.
According to this principle, the validator should not. The larger code base
should. The documentation should be crystal clear what this key is for and how
it should be managed. But the on-chain code should be solely focused on keeping
the user safe from others, and other from the user.
There is a loose sense of the [streetlight effect](https://en.wikipedia.org/wiki/Streetlight_effect) bourne out in code.
There is a loose sense of the
[streetlight effect](https://en.wikipedia.org/wiki/Streetlight_effect) bourne
out in code.
### Simplicity invites security
@ -154,18 +153,19 @@ principle then becomes a little grey on application. In places it translates to:
develop an abstraction in which the features become simple. In other places, we
will have to find the happy compromise between simple-ness and feature-ful-ness.
For example, in the case of designing [Cardano Lightning](cardano-lightning.org)
can a partner close two of their channels in a single transaction?
This might be important but perhaps could be handled by an abstraction in the application
hiding this detail to the user.
can a partner close two of their channels in a single transaction? This might be
important but perhaps could be handled by an abstraction in the application
hiding this detail to the user.
There is overlap here with the previous principle.
By having the on-chain code laser focused, we don't have nice-to-haves,
cluttering the code base, possibly obscuring our view from otherwise glaring bug.
There is overlap here with the previous principle. By having the on-chain code
laser focused, we don't have nice-to-haves, cluttering the code base, possibly
obscuring our view from otherwise glaring bug.
The current principle further justifies excluding logic in the validator
that a self interested participant would be motivated from ensuring themselves.
For example: a validator must check that a thread token never leaves a script address;
it need not check that a participant has paid themselves their due funds.
The current principle further justifies excluding logic in the validator that a
self interested participant would be motivated from ensuring themselves. For
example: a validator must check that a thread token never leaves a script
address; it need not check that a participant has paid themselves their due
funds.
### Prioritise user autonomy
@ -181,33 +181,30 @@ other partner's tx would output the correct funds. It would potentially save a
transaction in the winding down process. However, it also invites questions of
double satisfaction, and resolutions to this make it harder to reason about.
Instead, following this principle,
the design prioritises multi-channel management.
A fundamental participant type in a healthy Lightning network is the Gateway.
A gateway participant is highly
connected within the network and is (financially) motivated to route payments
between participants. A gateway node in particular needs to manage their
channels, and manage their capital amongst channels as efficiently as possible.
This in the whole network's interest.
Instead, following this principle, the design prioritises multi-channel
management. A fundamental participant type in a healthy Lightning network is the
Gateway. A gateway participant is highly connected within the network and is
(financially) motivated to route payments between participants. A gateway node
in particular needs to manage their channels, and manage their capital amongst
channels as efficiently as possible. This in the whole network's interest.
Cardano Lightning does permit mutual agreed actions.
However, such actions is considered as a secondary
pathway. Any channel has (at most) the funds of only the two partners of the
channel. Mutual actions are verified by the presence of both partners'
signatures on a transaction. As we assume that any participant will act in a
self interested manner, and is responsible for keeping themselves safe, few
checks are done beyond this.
Cardano Lightning does permit mutual agreed actions. However, such actions is
considered as a secondary pathway. Any channel has (at most) the funds of only
the two partners of the channel. Mutual actions are verified by the presence of
both partners' signatures on a transaction. As we assume that any participant
will act in a self interested manner, and is responsible for keeping themselves
safe, few checks are done beyond this.
### Distinguish safety from convenience
Safety comes first, but we also need things to be practical and preferably even
convenient. Make explicit when a feature has been included for safety, or is to
do with convenience.
do with convenience.
In some respects, this is restating of the first and or second principles.
The on-chain code is precisely what keeps users safe.
The small distinction is that this extends to off-code too.
There are aspects of off-chain code that are integral, and other parts that are convenient.
In some respects, this is restating of the first and or second principles. The
on-chain code is precisely what keeps users safe. The small distinction is that
this extends to off-code too. There are aspects of off-chain code that are
integral, and other parts that are convenient.
### Spec first, implement second
@ -242,10 +239,10 @@ understand how to interface with the code. Again - not to be justify any
obscurity of design or code, but a validator is not simply just another library
they'd be interfacing with. The stakes are too high. They must read the spec.
We suffer less from docs/code divergence than is experienced in "normal" development.
For the same reason that we have un-patch-ablity we have a fixed feature set.
It is in evolving software and its code base, by adding new features or modifying existing ones,
when code diverges from docs.
We suffer less from docs/code divergence than is experienced in "normal"
development. For the same reason that we have un-patch-ablity we have a fixed
feature set. It is in evolving software and its code base, by adding new
features or modifying existing ones, when code diverges from docs.
A spec helps expel ambiguity early. It provides an opportunity to check that
everyone is on the same page before any lines of code are written, and without
@ -264,9 +261,9 @@ what the feature requirements are (and as importantly what they aren't).
## Summary
The principles have been arrived up over numerous projects,
most explicitly and recently while working on Cardano Lightning.
As alluded to in the introduction, these principles should ...
well, be treated more like [guidelines](https://youtu.be/k9ojK9Q_ARE).
The principles have been arrived up over numerous projects, most explicitly and
recently while working on Cardano Lightning. As alluded to in the introduction,
these principles should ... well, be treated more like
[guidelines](https://youtu.be/k9ojK9Q_ARE).
If you comments, questions, suggested, or criticisms, please get in touch.

View File

@ -7,54 +7,54 @@ draft: true
A typical dapp has a number of components:
- Validators: also called the _on-chain_ part.
The decentralized network of nodes that maintain the chain run this code as part of the process of deciding
- Validators: also called the _on-chain_ part. The decentralized network of
nodes that maintain the chain run this code as part of the process of deciding
whether a tx is to be added to the chain or rejected.
- Chain indexing: watches the chain and records the data relevant to the dapp.
- Pretty front-end: typically how a user interacts with a dapp.
- Tx-building code: A component of the frontend.
It takes data from the user, the user's wallet, the chain-indexer and possibly elsewhere
to construct txs to be submitted to the chain that the validators will deem acceptable.
- Tx-building code: A component of the frontend. It takes data from the user,
the user's wallet, the chain-indexer and possibly elsewhere to construct txs
to be submitted to the chain that the validators will deem acceptable.
Here we have really described a browser-based plutus dapp.
Considering the term _dapp_ more generally, the Daedalus wallet is a dapp which is neither browser based nor involves any Plutus.
Cli-based dapps also exist, such as multi-sig using native scripts.
Here we have really described a browser-based plutus dapp. Considering the term
_dapp_ more generally, the Daedalus wallet is a dapp which is neither browser
based nor involves any Plutus. Cli-based dapps also exist, such as multi-sig
using native scripts.
## What is a tx?
At its core, the chain is a list of transaction outputs.
The chain is changed by submitting a tx which "spends" existing unspent transaction outputs (utxos) and appending new ones.
(There's other possible modifications too, like minting native assets and staking _etc_, but the key part is spending.)
At its core, the chain is a list of transaction outputs. The chain is changed by
submitting a tx which "spends" existing unspent transaction outputs (utxos) and
appending new ones. (There's other possible modifications too, like minting
native assets and staking _etc_, but the key part is spending.)
The on-chain part is where the dapp has its integrity, but users can only interact with the on-chain part of the dapp by submitting txs.
The on-chain part is where the dapp has its integrity, but users can only
interact with the on-chain part of the dapp by submitting txs.
The on-chain part is relatively simple.
It inspects each tx that it is concerned with, and if it does not like what it sees, it fails.
Cardano is, in this sense, a lean chain.
The on-chain part is relatively simple. It inspects each tx that it is concerned
with, and if it does not like what it sees, it fails. Cardano is, in this sense,
a lean chain.
The off-chain part is relatively complex.
There may be no, one, or many potential valid txs that would satisfy the user's intent.
The off-chain part is relatively complex. There may be no, one, or many
potential valid txs that would satisfy the user's intent.
At its core, a transaction is a list of inputs and outputs.
The inputs are spent, and the outputs created.
It must also contain the necessary signatures.
At its core, a transaction is a list of inputs and outputs. The inputs are
spent, and the outputs created. It must also contain the necessary signatures.
## Some history
When Plutus was first dreamed up, it wasn't just a language.
It was whole environment in which dapps would be engaged with.
The on-chain and off-chain code were coupled into a single framework with seamless extensive testing.
Dapps ran in the _PAB_, Plutus Application Backend.
Everything was great.
When Plutus was first dreamed up, it wasn't just a language. It was whole
environment in which dapps would be engaged with. The on-chain and off-chain
code were coupled into a single framework with seamless extensive testing. Dapps
ran in the _PAB_, Plutus Application Backend. Everything was great.
Except that it didn't work.
The chain-indexer would periodically fall-over,
it required users had to maintain a full node,
and the api never matured in to something stable, complete, and bug-free.
In addition, the validators it produced were bloated and un-optimized and would quickly hit the constraints of the cardano blockchain.
Except that it didn't work. The chain-indexer would periodically fall-over, it
required users had to maintain a full node, and the api never matured in to
something stable, complete, and bug-free. In addition, the validators it
produced were bloated and un-optimized and would quickly hit the constraints of
the cardano blockchain.
As a result teams turned to coming up with alternatives.
One of the first was MLabs and co in creating pluto and plutarch.
Later Aiken appeared to meet similar needs.
These began resolving issues with the on-chain part.
This left the off-chain part wanting.
As a result teams turned to coming up with alternatives. One of the first was
MLabs and co in creating pluto and plutarch. Later Aiken appeared to meet
similar needs. These began resolving issues with the on-chain part. This left
the off-chain part wanting.

View File

@ -2,7 +2,7 @@
id="footer"
class="py-12 px-2 flex flex-row gap-12 mx-2 sm:mx-4 items-start justify-between text-gray-800 dark:text-gray-200 dark:fill-white"
>
<div class="text-sm">&reg; 2023 kompact.io &trade; All Rights Reserved.</div>
<div class="text-sm">&reg; 2025 Kompact.io &trade; All Rights Reserved.</div>
<div class="flex flex-row gap-4">
<a href="https://www.linkedin.com/in/dominic-algernon-wallis-123b42187/">
<svg

View File

@ -1,7 +1,2 @@
<div class="text-1xl font-bold">
$title$
</div>
<div class="text-gray-800 dark:text-gray-200 mt-4">
$body$
</div>
<div class="text-1xl font-bold">$title$</div>
<div class="text-gray-800 dark:text-gray-200 mt-4">$body$</div>

View File

@ -1,7 +1,2 @@
<div class="text-1xl font-bold">
$title$
</div>
<div class="text-gray-800 dark:text-gray-200 mt-4">
$body$
</div>
<div class="text-1xl font-bold">$title$</div>
<div class="text-gray-800 dark:text-gray-200 mt-4">$body$</div>

View File

@ -1,5 +1,3 @@
<div class="index flex flex-col justify-between gap-4 sm:gap-8">
$for(sections)$
$body$
$endfor$
</div>
<div class="index flex flex-col justify-between gap-4 sm:gap-8">
$for(sections)$ $body$ $endfor$
</div>