On-chain Views#
Views are a mechanism that allows smart contracts to call smart contracts, and that:
are read-only: they may depend on the storage of the contract declaring the view but cannot modify it nor emit operations (but they can call other views),
take arguments as input in addition to the contract storage,
return results as output,
are synchronous: the result is immediately available on the stack of the caller contract.
Homonyms#
Beware that the term view has also been used for other kinds of mechanisms to access some data from the blockchain.
Off-chain views cannot be called from smart contracts but only by off-chain tools such as wallets.
Legacy on-chain views are a conventional way of making some contract data available. Their purpose is subsumed by that of the on-chain views defined here, but they are still referenced in FA1.2 and FA2 standards which predate the introduction of native on-chain views in the Hangzhou amendment.
In the following, the term “view” denotes the modern notion of on-chain views, described in this page.
Execution flow#
The execution of a view is included in the operation of the caller’s contract, but accesses the storage of the declarer’s contract, in read-only mode. Thus, in terms of execution, views are more like lambda functions rather than contract entrypoints, Here is an example:
code {
...;
TRANSFER_TOKENS;
...;
VIEW "view_ex" unit;
...;
}
This contract calls a contract TRANSFER_TOKENS
, and, later on, a view
called view_ex
. No matter if the callee view_ex
is defined in the
same contract with this caller contract or not, this view will be executed
immediately in the current operation, while the operations emitted by
TRANSFER_TOKENS
will be executed later on. As a result, although it
may seem that view_ex
receives the storage modified by
TRANSFER_TOKENS
, this is not the case. In other words, the storage of
the view is the same as when the execution of the contract calling the view started. In
particular, in case of re-entrance, i.e., if a contract A
calls a
contract B
that calls a view on A
, the storage of the view will be
the same as when B
started, not when A
started.
Declaration#
Views are declared at the toplevel of the script of the contract on
which they operate, alongside the contract parameter type, storage type,
and code. To declare a view, the view
keyword is used; its syntax is
view name 'arg 'return { instr; ... }
where:
name
is a string of at most 31 characters matching the regular expression[a-zA-Z0-9_.%@]*
; it is used to identify the view, hence it must be different from the names of the other views declared in the same script;'arg
is the type of the argument of the view;'return
is the type of the result returned by the view;{ instr; ... }
is a sequence of instructions of typelambda (pair 'arg 'storage_ty) 'return
where'storage_ty
is the type of the storage of the current contract. Certain specific instructions have different semantics in views:BALANCE
represents the current amount of mutez held by the contract where the view is declared;SENDER
represents the contract which is calling the view;SELF_ADDRESS
represents the contract declaring the view;AMOUNT
is always 0 mutez.
Forbidden types#
Note that in both view input (type 'arg
) and view output (type
'return
), the following types are forbidden: ticket
,
operation
, big_map
and sapling_state
.