forked from IntersectMBO/cardano-ledger
-
Notifications
You must be signed in to change notification settings - Fork 0
/
transactions.tex
302 lines (263 loc) · 13.3 KB
/
transactions.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
\section{Transactions}
\label{sec:transactions}
This section outlines the changes that are needed to the transaction
structure to enable phase-2 scripts to validate
the minting of tokens, spending outputs, verifying certificates, and
verifying withdrawals.
%
Figure \ref{fig:defs:utxo-shelley-1} gives the modified transaction types and helper functions.
We make the following changes and additions:
\begin{itemize}
\item $\ScriptIntegrityHash$ is the type of a hash of script execution
related data. It is the hash of $\fun{txrdmrs}$ and relevant protocol parameters.
\item $\ScriptPhOne$ is the type of phase-1 scripts.
\item $\ScriptPhTwo$ is the type of phase-2 scripts.
\item $\Data$ is a type for communicating data to script. It is kept abstract here.
\item $\Script$ is the type of all scripts, both phase-1 and phase-2.
\item $\IsValid$ is a tag that indicates that a transaction
expects that all its phase-2 scripts will be validated.
This tag is added by the block creator when
constructing a block, and its correctness is verified as part of the script execution.
\item $\Datum$ is a type alias for the $\Data$ type, used to signify that
terms of this type are intended to be used strictly as datum objects.
\item $\Redeemer$ is also a type alias for the $\Data$ type, used to signify that
terms of this type are intended to be used strictly as redeemers.
\item $\TxOut$ is the type of transaction outputs. These are extended to include
an optional hash of a datum. Note that \emph{any} output can
optionally include such a hash, even though only phase-2 scripts
can actually use the hash value. Since it is in general impossible for the ledger implementation to
know at the time of transaction creation whether or not an output belongs to a phase-2
script, we simply allow any output to contain a hash of a datum.
\item $\Tag$ lets us differentiate what a script
can validate, i.e. \\
\begin{tabular}{l@{~to validate~}l}
$\mathsf{Spend}$ & spending a script UTxO entry; \\
$\mathsf{Mint}$ & minting tokens; \\
$\mathsf{Cert}$ & certificates with script credentials; and \\
$\mathsf{Rewrd}$ & reward withdrawals from script addresses.
\end{tabular}
\item $\RdmrPtr$ is a pair of a tag and an index. This type is
used to index the Plutus redeemers that are included in a transaction, as discussed
below.
\end{itemize}
We add the following helper functions:
\begin{itemize}
\item $\fun{language}$ selects the language of a phase-2 script, and $\Nothing$ in case
the script is phase-1.
\item $\fun{hashData}$ hashes a value of type $\Data$.
\item $\fun{hashScriptIntegrity}$ hashes the protocol parameters and data relevant to script execution.
In particular, the redeemer structure, and the datum objects.
\end{itemize}
\begin{figure*}[htb]
\emph{Abstract types}
%
\begin{equation*}
\begin{array}{l@{\quad\quad\quad\quad}r}
\ScriptIntegrityHash & \text{Script data hash}\\
\ScriptPlutus & \text{Plutus core scripts} \\
\Data & \text{Generic script data}
\end{array}
\end{equation*}
%
\emph{Script types}
%
\begin{equation*}
\begin{array}{l@{\qquad=\qquad}lr}
\ScriptPhTwo & \ScriptPlutus \\
\Script & \ScriptPhOne \uniondistinct \ScriptPhTwo \\
\IsValid & \Bool \\
\Datum & \Data \\
\Redeemer & \Data
\end{array}
\end{equation*}
%
\emph{Derived types}
%
\begin{equation*}
\begin{array}{l@{\qquad=\qquad}lr}
\ValidityInterval
& \Slot^? \times \Slot^?
\\
\TxOut
& \Addr \times \Value \times \hldiff{\DataHash^?}
\\
\Tag
& \{\mathsf{Spend},~\mathsf{Mint},~\mathsf{Cert},~\mathsf{Rewrd}\}
\\
\RdmrPtr
& \Tag \times \Ix
\end{array}
\end{equation*}
%
\emph{Helper Functions}
%
\begin{align*}
\fun{language}& : \Script \to \Language^?\\
\fun{hashData}& : \Data \to \DataHash
\nextdef
\fun{getCoin}& : \TxOut \to \Coin \\
\fun{getCoin}&~\hldiff{{(\_, \var{v}, \_)}} = \fun{valueToCoin}~{v}
\end{align*}
%
\begin{align*}
&\fun{hashScriptIntegrity} : \PParams \to \powerset{\Language} \to (\RdmrPtr \mapsto \Redeemer \times \ExUnits) \\
&~~~~ \to (\DataHash \mapsto \Datum) \to \ScriptIntegrityHash^? \\
&\fun{hashScriptIntegrity}~{pp}~{langs}~{rdmrs}~{dats} = \\
&~~~~ \begin{cases}
\Nothing & rdmrs = \emptyset \land langs = \emptyset \land dats = \emptyset \\
\fun{hash} (rdmrs, dats, \{ \fun{getLanguageView}~pp~l \mid l \in langs \}) & \text{otherwise}
\end{cases}
\end{align*}
\caption{Definitions for Transactions}
\label{fig:defs:utxo-shelley-1}
\end{figure*}
\begin{figure*}[htb]
\emph{Transaction Types}
%
\begin{equation*}
\begin{array}{r@{~~}l@{~~}l@{\qquad}l}
\TxWitness =
& (\VKey \mapsto \Sig) & \fun{txwitsVKey} & \text{VKey signatures}\\
& \times ~(\ScriptHash \mapsto \Script) & \fun{txscripts} & \text{All scripts}\\
& \times~ \hldiff{(\DataHash \mapsto \Datum)} & \hldiff{\fun{txdats}} & \text{All datum objects}\\
& \times ~\hldiff{(\RdmrPtr \mapsto \Redeemer \times \ExUnits)}& \hldiff{\fun{txrdmrs}}& \text{Redeemers/budget}
\end{array}
\end{equation*}
%
\begin{equation*}
\begin{array}{r@{~~}l@{~~}l@{\qquad}l}
\TxBody =
& \powerset{\TxIn} & \fun{txins}& \text{Inputs}\\
& \times ~\hldiff{\powerset{\TxIn}} & \hldiff{\fun{collateral}} & \text{Collateral inputs}\\
& \times ~(\Ix \mapsto \TxOut) & \fun{txouts}& \text{Outputs}\\
& \times~ \seqof{\DCert} & \fun{txcerts}& \text{Certificates}\\
& \times ~\Value & \fun{mint} &\text{A minted value}\\
& \times ~\Coin & \fun{txfee} &\text{Total fee}\\
& \times ~\ValidityInterval & \fun{txvldt} & \text{Validity interval}\\
& \times~ \Wdrl & \fun{txwdrls} &\text{Reward withdrawals}\\
& \times ~\Update^? & \fun{txUpdates} & \text{Update proposals}\\
& \times ~\hldiff{\powerset{\KeyHash}} & \hldiff{\fun{reqSignerHashes}} & \text{Hashes of VKeys passed to scripts}\\
& \times ~\hldiff{\ScriptIntegrityHash^?} & \hldiff{\fun{scriptIntegrityHash}} & \text{Hash of script-related data}\\
& \times ~\AuxiliaryDataHash^? & \fun{txADhash} & \text{Auxiliary data hash}\\
& \times ~\hldiff{\Network^?} & \hldiff{\fun{txnetworkid}} & \text{Tx network ID}\\
\end{array}
\end{equation*}
%
\begin{equation*}
\begin{array}{r@{~~}l@{~~}l@{\qquad}l}
\Tx =
& \TxBody & \fun{txbody} & \text{Body}\\
& \times ~\TxWitness & \fun{txwits} & \text{Witnesses}\\
& \times ~\hldiff{\IsValid} & \hldiff{\fun{isValid}}&\text{Validation tag}\\
& \times ~\AuxiliaryData^? & \fun{auxiliaryData}&\text{Auxiliary data}\\
\end{array}
\end{equation*}
\caption{Definitions for transactions, cont.}
\label{fig:defs:utxo-shelley-2}
\end{figure*}
\textbf{Auxiliary Data. } The auxiliary data in an Alonzo transaction has the same structure as
in a ShelleyMA transaction, but can additionally contain phase-2 scripts.
\subsection{Witnessing}
Figure \ref{fig:defs:utxo-shelley-2} defines the witness type, $\TxWitness$. This contains everything
in a transaction that is needed for witnessing, namely:
\begin{itemize}
\item VKey signatures;
\item a map of scripts indexed by their hashes, including phase-2 scripts;
\item a map of terms of type $\Datum$ indexed by their hashes, containing all required datum objects
as well as any optional ones that are posted for communication; and
\item a map of a pair of a $\Redeemer$ object and an $\ExUnits$ value indexed by $\RdmrPtr$,
containing the redeemers and execution units budgets.
\end{itemize}
Note that there is a difference between the way scripts and datum objects are included in
a transaction (as a set) versus how redeemers are included
(as an indexed structure).
\begin{description}
\item
[Hash reference (script/datum object):]
Scripts and datum objects are referred to explicitly via their hashes,
which are included in the $\UTxO$ or the transaction. Thus, they can be
looked up in the transaction without any key in the data structure.
\item[No hash reference (redeemers):] For redeemers,
we use a reverse pointer approach and
index the redeemer by a pointer to the item for which it will be used.
For details on how a script finds its redeemer, see Section~\ref{sec:scripts-inputs}.
\end{description}
\subsection{Transactions}
\label{sec:transctions}
We have also made the following changes to
the body of the transaction:
\begin{itemize}
\item The new field $\fun{collateral}$ is used to specify the \emph{collateral inputs}
that are collected (into the fee pot) to cover a percentage of
transaction fees (usually $100$ percent or more)
\emph{in case the transaction contains failing phase-2 scripts}. They are not collected otherwise.
The purpose of the collateral is to cover the resource use costs
incurred by block producers running scripts that do not validate.
Collateral inputs behave like regular inputs, except that they
must be VKey locked and can only contain Ada. See \ref{fig:functions:utxo}.
It is permitted to use the same inputs as both collateral and a regular inputs, as exactly
one set of inputs is ever collected: collateral ones in the case of script failure, and regular inputs
in the case when all scripts validate.
\item There is a new field called $\fun{reqSignerHashes}$ that is used to specify a set of hashes
of keys that must sign the transaction in addition to the signatures required to validate
spending from VKey addresses, checking certificate validity, and validating reward withdrawals.
This field is there to allow users to add signatures that
\begin{itemize}
\item cannot be stripped from a transaction without invalidating it in phase 1 (ie. the
validation phase where fees are not collected for the validation work done)
\item are not attached to any validation being done in phase 1, such as VKey output spending
\end{itemize}
This is a field where users can add signatures that a phase-2 script requires internally -
the transaction and the ledger are otherwise unaware of what signatures are expected by these scripts.
\item We include a hash of some script-related data, specifically the redeemers and protocol parameters,
with accessor $\fun{scriptIntegrityHash}$.
\item We include the ID of the network on which the transaction lives, $\fun{txnetworkid}$.
This is in addition to the network ID's already included in the reward and output addresses.
\end{itemize}
A complete transaction is comprised of:
\begin{enumerate}
\item the transaction body,
\item all the information that is needed to witness transactions,
\item the $\IsValid$ tag, which indicates whether all scripts
that are executed during the script execution phase validate.
The correctness of the tag is verified as part of the ledger rules, and the block is
deemed to be invalid if it is applied incorrectly.
It can be used to re-apply blocks without script re-validation.
Since this tag is not part of the body, i.e. it is not signed, the block producer can
(and must) choose the correct value.
\item any auxiliary data.
\end{enumerate}
\begin{note}
In the implementation the $\IsValid$ tag is part of a user-submitted
transaction, but it is ignored and re-computed by the block
producer.
\end{note}
\subsection{Additional Role of Signatures on TxBody}
The transaction body and the UTxO must uniquely determine all the data
that can influence on-chain transfer of value.
This is so that the signatures can ensure that this data is not tampered with.
As before, a transaction that does not include the correct signatures is completely invalid.
Thus, all data that influences script validation outcomes must also be determined by the body.
Scripts and datum objects whose hashes are specified on-chain do not require to be
signed when included in a transaction. That is, script hashes locking UTxOs (as well as
with the datum hashes these UTxOs contain), and also the posted
certificates, minting policies, and reward addresses do not need to be signed.
The optional datum objects, however, could be stripped from the transaction without making
it invalid. The optional datums are stored in the same map the required ones, so,
for this reason, we do include all datum objects in the script integrity hash calculation.
%
The hash of the indexed redeemer structure and the protocol parameters that are used by
script interpreters are included in the body of the transaction, as these are composed
by the transaction author rather than
fixed via a hash on the ledger. In the future, other parts of the ledger
state may also need to be included in this hash, if they are passed as
arguments to a new script interpreter.
\subsection{Data required for script validation.}
\label{sec:script-data}
The body of the transaction, alongside the witness data, are required for script validation.
Script validation should not depend on the auxiliary data in any way. Script validation
may require certain optional datums to be posted. For this reason, we include optional
datums in the part of the transaction (the witnesses) which scripts do see.
Any metadata that a user wants to expose to a transaction can be included in the
redeemer, whose purpose is to contain all user-supplied data relevant to validation.
For more about what scripts do and do not inspect, see Section~\ref{sec:txinfo}.