From 299f4490a1c69f677f83a1ddfeff7e45af38da22 Mon Sep 17 00:00:00 2001 From: michele-nuzzi Date: Thu, 13 Apr 2023 01:07:45 +0200 Subject: [PATCH 1/7] initial CIP --- CIP-onchain-tx-chaining/README.md | 175 ++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 CIP-onchain-tx-chaining/README.md diff --git a/CIP-onchain-tx-chaining/README.md b/CIP-onchain-tx-chaining/README.md new file mode 100644 index 000000000..fcf532f38 --- /dev/null +++ b/CIP-onchain-tx-chaining/README.md @@ -0,0 +1,175 @@ +--- +CIP: ? +Title: ? +Category: ? +Status: Proposed +Authors: + - John Doe +Implementors: [] +Discussions: + - https://github.com/cardano-foundation/cips/pulls/? +Created: YYYY-MM-DD +License: CC-BY-4.0 +--- + + + +## Abstract + + +Thanks to the transaction determinism, in Cardano is possible to chain transactions so that new transaction can be created using transaction outputs of transactions that have not been included in the blockchain yet. + +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 + +## Motivation: why is this CIP necessary? + + +The changes proposed in this CIP are implemented would allow for composability between transactions while preserving the deterministic behaviour. + +The main stakeholders would be dApp developers; who would have access to the transacionm chaining functionality also on-chain in plutus scripts, on top of the off-chain guarantee of the transactions validity. + +## Specification + + +The core idea of the CIP is to add a new field in the transaction body representing the hash of the chained transaction (the transaction that uses the current transaction outputs as inputs). + +Despite being a simple idea it introduces a circular dependency of hashes; + +Infact the current transaction hash is used to descripe the input used in the chained transaction; +but the input of the chained transaction will determine the hash of the chained transaction; +and the hash of the chained transaction would be included in the previous transaction body; +and this would modify the hash of the initial transaction. + +(`current_tx_id` -> `utxo_input` -> `next_tx_id` -> `current_tx_id` ) + +To break the circular dependecy we can modify the definition of a valid transaction input so that it doesn't require a transaciton hash if it is an output of a previus transaction. + +In particular the current `transacion_input` definition is + +```cddl +transaction_input = [ transaction_id : $hash32 + , index : uint + ] +``` + +so we introduce a new `chainable_transaction_input` cddl definition + +```cddl +chainable_transaction_input = uint / transaction_input +``` + +so that if the transacion input is only an unsinged integer the hash is implied to be the one of the previous transaction (this being the chained transacion). + +the final `transaction_body` cddl (taking in consideration the conaway modifications) would then become: + +```cddl +; up to babbage transaction_input +transaction_input = [ transaction_id : $hash32 + , index : uint + ] + +chainable_transaction_input = uint / transaction_input + +transaction_body = + { 0 : set ; This CIP; modified inputs field + , 1 : [* transaction_output] + , 2 : coin ; fee + , ? 3 : uint ; time to live + , ? 4 : [* certificate] + , ? 5 : withdrawals + , ? 7 : auxiliary_data_hash + , ? 8 : uint ; validity interval start + , ? 9 : mint + , ? 11 : script_data_hash + , ? 13 : set ; collateral inputs + , ? 14 : required_signers + , ? 15 : network_id + , ? 16 : transaction_output ; collateral return + , ? 17 : coin ; total collateral + , ? 18 : set ; reference inputs + , ? 19 : [* voting_procedure] ; New; Voting procedures + , ? 20 : [* proposal_procedure] ; New; Proposal procedures + , ? 21 : $hash32 ; This CIP; Chained transaction_id + } +``` + +And also a modification to the [`ScriptContext`](https://github.com/input-output-hk/plutus/blob/c3918d6027a9a34b6f72a6e4c7bf2e5350e6467e/plutus-ledger-api/src/PlutusLedgerApi/V2/Contexts.hs#L72) would be needed, intorducing the `txInfoChainedTxId` field of type `Maybe TxId`. + +```hs +data TxInfo = TxInfo + { txInfoInputs :: [TxInInfo] -- ^ Transaction inputs; cannot be an empty list + , txInfoReferenceInputs :: [TxInInfo] -- ^ /Added in V2:/ Transaction reference inputs + , txInfoOutputs :: [TxOut] -- ^ Transaction outputs + , txInfoFee :: Value -- ^ The fee paid by this transaction. + , txInfoMint :: Value -- ^ The 'Value' minted by this transaction. + , txInfoDCert :: [DCert] -- ^ Digests of certificates included in this transaction + , txInfoWdrl :: Map StakingCredential Integer -- ^ Withdrawals + -- /V1->V2/: changed from assoc list to a 'PlutusTx.AssocMap' + , txInfoValidRange :: POSIXTimeRange -- ^ The valid range for the transaction. + , txInfoSignatories :: [PubKeyHash] -- ^ Signatures provided with the transaction, attested that they all signed the tx + , txInfoRedeemers :: Map ScriptPurpose Redeemer -- ^ /Added in V2:/ a table of redeemers attached to the transaction + , txInfoData :: Map DatumHash Datum -- ^ The lookup table of datums attached to the transaction + -- /V1->V2/: changed from assoc list to a 'PlutusTx.AssocMap' + , txInfoId :: TxId -- ^ Hash of the pending transaction body (i.e. transaction excluding witnesses) + , txInfoChainedTxId :: Maybe TxId -- This CIP; hash of the chained transaction based on this transaction outputs + } +``` + +Important to note that unlike the cddl specification; the `ScriptContext` `txInfoInputs` field doesn't need to change; since the creation of the script context is only needed at phase 2 validation and the transaction hash of the prevous transaction is fully defined. + +## Rationale: how does this CIP achieve its goals? + + +The proposed changes allow to enforce the transaction validation process to fail in the evenience one or more of the chained transaction fails too. + +In particular the phase 1 validation chan check for the exsistence of an other transaction with the specified hash in the local mempool (or whait if none is present) + +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. + +e.g.: +```ts +const MyDatum = pstruct({ + MyDatum: { + chainedTx: PTxId.type + } +}); +``` + +and then check the `chainedTx` in the example above to equal the `txInfoId` field of the `ScriptContext` of the chained transaction. + +## Path to Active + +The suggested changes would have to be implemented in a new version of the `cardano-node` + +### Acceptance Criteria + + +An hard fork enables the suggested changes. + +### Implementation Plan + + +## Copyright + + +[CC-BY-4.0]: https://creativecommons.org/licenses/by/4.0/legalcode +[Apache-2.0]: http://www.apache.org/licenses/LICENSE-2.0 \ No newline at end of file From 4b3dbbab3dd6d5fcc2cb4de47a699ad97d8476de Mon Sep 17 00:00:00 2001 From: michele-nuzzi Date: Thu, 13 Apr 2023 01:10:12 +0200 Subject: [PATCH 2/7] added CIP infos --- CIP-onchain-tx-chaining/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CIP-onchain-tx-chaining/README.md b/CIP-onchain-tx-chaining/README.md index fcf532f38..606a294fa 100644 --- a/CIP-onchain-tx-chaining/README.md +++ b/CIP-onchain-tx-chaining/README.md @@ -1,14 +1,14 @@ --- -CIP: ? -Title: ? -Category: ? -Status: Proposed +CIP: _??? +Title: onchain tx chaining +Category: Ledger | Plutus +Status: Draft Authors: - John Doe Implementors: [] Discussions: - https://github.com/cardano-foundation/cips/pulls/? -Created: YYYY-MM-DD +Created: 2023-04-13 License: CC-BY-4.0 --- From 15e77d4db6f5c0ad667d67cb0746f62b6cbbef31 Mon Sep 17 00:00:00 2001 From: michele-nuzzi Date: Thu, 13 Apr 2023 01:11:23 +0200 Subject: [PATCH 3/7] uopsie I forgot the mail --- CIP-onchain-tx-chaining/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-onchain-tx-chaining/README.md b/CIP-onchain-tx-chaining/README.md index 606a294fa..9f1310722 100644 --- a/CIP-onchain-tx-chaining/README.md +++ b/CIP-onchain-tx-chaining/README.md @@ -4,7 +4,7 @@ Title: onchain tx chaining Category: Ledger | Plutus Status: Draft Authors: - - John Doe + - Michele Nuzzi Implementors: [] Discussions: - https://github.com/cardano-foundation/cips/pulls/? From 49ccc455649d46727d2845de208106bfc1b1f3a6 Mon Sep 17 00:00:00 2001 From: michele-nuzzi Date: Thu, 13 Apr 2023 01:15:30 +0200 Subject: [PATCH 4/7] typo --- CIP-onchain-tx-chaining/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-onchain-tx-chaining/README.md b/CIP-onchain-tx-chaining/README.md index 9f1310722..1248ded84 100644 --- a/CIP-onchain-tx-chaining/README.md +++ b/CIP-onchain-tx-chaining/README.md @@ -49,7 +49,7 @@ The core idea of the CIP is to add a new field in the transaction body represent Despite being a simple idea it introduces a circular dependency of hashes; -Infact the current transaction hash is used to descripe the input used in the chained transaction; +Infact the current transaction hash is used to describe the input used in the chained transaction; but the input of the chained transaction will determine the hash of the chained transaction; and the hash of the chained transaction would be included in the previous transaction body; and this would modify the hash of the initial transaction. From 8def2d7633bd4865e12e7cbd7cb78a0de2933e34 Mon Sep 17 00:00:00 2001 From: michele-nuzzi Date: Fri, 21 Apr 2023 22:25:34 +0200 Subject: [PATCH 5/7] modified chained_tx_input to account for multiple chained transactions --- CIP-onchain-tx-chaining/README.md | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/CIP-onchain-tx-chaining/README.md b/CIP-onchain-tx-chaining/README.md index 1248ded84..fa7e3b97e 100644 --- a/CIP-onchain-tx-chaining/README.md +++ b/CIP-onchain-tx-chaining/README.md @@ -58,6 +58,8 @@ and this would modify the hash of the initial transaction. To break the circular dependecy we can modify the definition of a valid transaction input so that it doesn't require a transaciton hash if it is an output of a previus transaction. +The only information needed for a chained input is the (previous) transaction that generated it and the output index. + In particular the current `transacion_input` definition is ```cddl @@ -66,13 +68,26 @@ transaction_input = [ transaction_id : $hash32 ] ``` -so we introduce a new `chainable_transaction_input` cddl definition +We can define a new type of transaction input that here we call `chained_tx_input` + +```cddl +chained_tx_input = [ prev_tx_pointer: uint + , index : uint + ] +``` + +so that we can introduce a new `chainable_transaction_input` cddl definition ```cddl -chainable_transaction_input = uint / transaction_input +chainable_transaction_input = chained_tx_input / transaction_input ``` -so that if the transacion input is only an unsinged integer the hash is implied to be the one of the previous transaction (this being the chained transacion). +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) + +if otherwhise the first element of the array are bytes then it should be interpreted as the `transaciton_input` first element the final `transaction_body` cddl (taking in consideration the conaway modifications) would then become: @@ -82,7 +97,11 @@ transaction_input = [ transaction_id : $hash32 , index : uint ] -chainable_transaction_input = uint / transaction_input +chained_tx_input = [ prev_tx_pointer: uint + , index : uint + ] + +chainable_transaction_input = chained_tx_input / transaction_input transaction_body = { 0 : set ; This CIP; modified inputs field From 2ba1ba3d3ff1c5bbc9c4bc7fb467b4bb6184ca11 Mon Sep 17 00:00:00 2001 From: michele-nuzzi Date: Fri, 21 Apr 2023 22:28:23 +0200 Subject: [PATCH 6/7] modified chained_tx_input to account for multiple chained transactions --- CIP-onchain-tx-chaining/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CIP-onchain-tx-chaining/README.md b/CIP-onchain-tx-chaining/README.md index fa7e3b97e..00a3915a3 100644 --- a/CIP-onchain-tx-chaining/README.md +++ b/CIP-onchain-tx-chaining/README.md @@ -58,7 +58,7 @@ and this would modify the hash of the initial transaction. To break the circular dependecy we can modify the definition of a valid transaction input so that it doesn't require a transaciton hash if it is an output of a previus transaction. -The only information needed for a chained input is the (previous) transaction that generated it and the output index. +The only information needed for a chained input is the which previous transaction generated it and the output index. In particular the current `transacion_input` definition is @@ -92,15 +92,17 @@ if otherwhise the first element of the array are bytes then it should be interpr the final `transaction_body` cddl (taking in consideration the conaway modifications) would then become: ```cddl -; up to babbage transaction_input +; up to babbage only transaction_input transaction_input = [ transaction_id : $hash32 , index : uint ] +; new type of transaction input chained_tx_input = [ prev_tx_pointer: uint , index : uint ] +; all possible transaction input types chainable_transaction_input = chained_tx_input / transaction_input transaction_body = From a5fa198269d41a0ef2aa267fec6b0b4ce8fe3106 Mon Sep 17 00:00:00 2001 From: michele-nuzzi Date: Fri, 21 Apr 2023 22:29:12 +0200 Subject: [PATCH 7/7] modified chained_tx_input to account for multiple chained transactions --- CIP-onchain-tx-chaining/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CIP-onchain-tx-chaining/README.md b/CIP-onchain-tx-chaining/README.md index 00a3915a3..a99d20425 100644 --- a/CIP-onchain-tx-chaining/README.md +++ b/CIP-onchain-tx-chaining/README.md @@ -189,6 +189,8 @@ An hard fork enables the suggested changes. ### Implementation Plan +N/A + ## Copyright