From 960e6c478a224382818390de1d247f517e3791c9 Mon Sep 17 00:00:00 2001 From: waalge Date: Tue, 22 Jul 2025 14:46:45 +0000 Subject: [PATCH] add cip-118 --- content/posts/cip-118.md | 316 +++++++++++++++++++++++ content/posts/principles.md | 121 +++++---- content/posts/why-building-tx-is-hard.md | 70 ++--- templates/footer.html | 2 +- templates/item.html | 9 +- templates/list.html | 9 +- templates/lists.html | 8 +- 7 files changed, 418 insertions(+), 117 deletions(-) create mode 100644 content/posts/cip-118.md diff --git a/content/posts/cip-118.md b/content/posts/cip-118.md new file mode 100644 index 0000000..7d0de9f --- /dev/null +++ b/content/posts/cip-118.md @@ -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. diff --git a/content/posts/principles.md b/content/posts/principles.md index 52af874..51a0d0d 100644 --- a/content/posts/principles.md +++ b/content/posts/principles.md @@ -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. diff --git a/content/posts/why-building-tx-is-hard.md b/content/posts/why-building-tx-is-hard.md index 107eddf..82eef0e 100644 --- a/content/posts/why-building-tx-is-hard.md +++ b/content/posts/why-building-tx-is-hard.md @@ -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. diff --git a/templates/footer.html b/templates/footer.html index c2e3a2b..3a31e6c 100644 --- a/templates/footer.html +++ b/templates/footer.html @@ -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" > -
® 2023 kompact.io ™ All Rights Reserved.
+
® 2025 Kompact.io ™ All Rights Reserved.
- $title$ -
-
- $body$ -
- +
$title$
+
$body$
diff --git a/templates/list.html b/templates/list.html index 91b2728..c785f17 100644 --- a/templates/list.html +++ b/templates/list.html @@ -1,7 +1,2 @@ -
- $title$ -
-
- $body$ -
- +
$title$
+
$body$
diff --git a/templates/lists.html b/templates/lists.html index 723299a..e814984 100644 --- a/templates/lists.html +++ b/templates/lists.html @@ -1,5 +1,3 @@ -
- $for(sections)$ - $body$ - $endfor$ -
+
+ $for(sections)$ $body$ $endfor$ +