-
Notifications
You must be signed in to change notification settings - Fork 323
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 Transaction Chaining #508
Conversation
Seems like this is basically batched transactions as described in IntersectMBO/cardano-ledger#768 |
The goal/problem they try to solve is the same; however, I would say this is a different implementation if compared to do the description of the cited issue |
We can distinguish the two types of inputs based on the type of the first element of the array; | ||
|
||
if it is an unsigned integer it should be interpreted as a pointer to a previous transaction (`chained_tx_input` first element) | ||
(`0` being the transaction immediately before the current chained one) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is too vague: you are suggesting we index backwards from a transaction in what? The mempool? The chain? Both of those are created non-deterministically, so that seems extremely unlikely to work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not really sure where this should happen if you have any suggestions that would be great.
regarding both being not deterministic the pointer to the previous transaction only makes sense if there is a previous transaction pointing to the current one.
If none is present the transaction should be considered invalid (or at least wait to be processed until some other transaction includes the current as chained).
In this sense transactions are referencing chained ones forwards; UTxO is referencing backward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then prev_tx_pointer
is not needed. Output index is sufficient if we rely on the fact there is another transaction referening this one.
Yes, this is quite different to the proposals there. I would like to see some analysis of the requirements and comparison with other solutions, since the various solutions all differ in terms of what they offer. Some requirements questions:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to me that the main difference between this and batch transactions is that this lets scripts "see" that other transactions will happen, which is a major power increase and I'm not sure what I think about it.
I think we could probably add that to batch transactions too, though: include a field like "otherTransactionsInBatch :: [TxIx]` to the script context. I don't think that gives us a hashing problem although it might make fee calculation annoying.
## Motivation: why is this CIP necessary? | ||
<!-- A clear explanation that introduces the reason for a proposal, its use cases and stakeholders. If the CIP changes an established design then it must outline design issues that motivate a rework. For complex proposals, authors must write a Cardano Problem Statement (CPS) as defined in CIP-9999 and link to it as the `Motivation`. --> | ||
|
||
The changes proposed in this CIP are implemented would allow for composability between transactions while preserving the deterministic behaviour. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please provide some actual usecases!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I concur with @michaelpj here, the motivation is a bit short. It's not clear to me "how is this a useful thing". Or more exactly, how is that different from chaining UTxO the way it's already possible?
|
||
phase 1 validation can also fail if some transaction input is defined using only an unsigned integer but no other transaction specifies the current transaction as chained. | ||
|
||
DApp developers can check on-chain for eventual chained transaction by exposing the `txInfoChainedTxId` `ScriptContext` field in the output datum going to be used in the chained transaciton. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would really help to have some usecases to see how this is useful. I think I can guess, but please just explain!
Doesn't this imply that the chain of transactions must all be within one block? I can't see how to enforce the guarantee otherwise. And if so, doesn't this end up being much the same as batched transactions? |
Not necessarily; transactions can still be included in multiple blocks; the only thing needed for a chain of transactions is the existence of an output of a previous one |
So this doesn't ensure that the following transaction is ever made? It's much less clear what the point is, then. I thought this would allow scripts to ensure that another transaction happens, but in this case it wouldn't. |
That is the main idea of the proposal. The main use case (that I will add as soon as I edit the proposal) is the composability of transactions; keeping every transaction atomic on its own but under all aspects provides a way to be sure some other action took place (based on the output of the current). In general this would give scripts the possibility to act like active entities. This, as an example, allows for datum validation when creating a brand new UTxO in a script; where the first transaction creates the UTxO and the second spends that UTxO only to be sure that the datum is valid; if the second fails the first fails too, so the UTxO is never created. Another use case, also based on the "acting like active entities" thing, is smart contract interaction; where a smart contract first performs an action (even expansive ones) and then forwards the validation to a script in a successive transaction that checks for the result of the previous and the presence of the target (external) contract; under all aspects emulating a contract call.
|
In order to be included in a block all the chained transactions have to be submitted an all have to be validated; if any of the transactions fails none is included; if all succeed then can be included as a normal transaction. If the above doesn't make sense then is likely I'm missing something so please let me know how can I improve there. |
|
||
Despite being extremly powerful this process as currently some limitations: | ||
- it gives no guarantees that all of the multiple transactions are valid | ||
- the process happens entrierly offchain; without the possibility for a plutus script to be aware of it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This last paragraph shall actually be part of the "Motivation" section IMO as it gives some clear justification for why is this CIP necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Little suggestion: I'd welcome some extra proof-reading on the document as there are many little typos 🤓
@michele-nuzzi after you've given this your best effort let us know & I'll give it a good editing review. 😇 |
That is my signature; at least we are sure I wrote it. Will go over it by tomorrow. |
@michele-nuzzi marking |
@michele-nuzzi Why can't you just use minting policies for this? That is what I have been using for my applications.
This is literally how I use the minting policy. For example, when a borrower creates a UTxO to ask for a loan, they must mint an Ask token and store it in the UTxO. This Ask token can only be minted if the datum in the UTxO is valid (among other things). A lender who then wants to offer a loan must create a UTxO with an Offer token. The Offer token can only be minted if the offer is valid (datum, value, etc must all be valid). To accept a loan, the borrower must match up an ask UTxO with an offer UTxO with the added requirement that they contain an Ask token and Offer token, respectively. The very fact that the tokens exist means the UTxOs are valid. To use the terminology here, the presence of the tokens is proof that a previous transaction occured. I have successfully been able to compose my applications using this approach. For example, you can safely compose my dex, options trading protocol, and secondary market in a single transaction. They either all succeed or the transaction fails.
The approach I mention above has this property already. Why is this approach not sufficient? |
yes that particular scenario is already possible without chaining transactions; as an example, I used a similar technique in this yield contract; however, the contract tends to be more complicated because in that particular case, I had a mutual dependency between the minting policy and the validator (policy checks for the asset to be sent to the validator and the validator checks for the policy to assert the validity of an utxo) that implies "unsafe" type coercion and ad-hoc data design. while the CIP won't remove the pattern (mutual dependencies are more common than I wish they were) it definitely makes the process much smoother and requires less mental gymnastic to achieve something like datum validation. There are also many advantages in chaining transactions and having the guarantee that there is some transaction happening after yours. In particular "batching" (but without third parties signing transactions) The above is also possible without third parties but that would imply having multiple users from all around the world having to sign the same exact transaction. If that was easy we wouldn't have batchers at all today, but of course, that is not the case. chaining transactions and having a guarantee of that on-chain allows contracts to act like active entities; without requiring an indefinite amount of users to sign the same exact transaction (they would sign theirs and then leave the contract to do its things) |
@michele-nuzzi we are trying to trim the abandoned proposals from the CIP PR queue but it looks like this one is still relevant... despite being in If you're standing by your proposal, and intend to carry it forward, please update the header & format according to the new CIP-0001 (I believe you are familiar with those specifics but please post if not). Then based on your posting whatever's happened in the last year, we can change the status to something other than (potentially) |
Once in a while, I see people raising issues that could be solved with transaction chaining if there where the possibility to have some additional guarantees on it.
There is no strict need for this proposal at the current state but I think it might prevent something more complex in the future.
(see rendered proposal in branch)