- Proposal Name: Improve view/change methods in contracts
- Start Date: 2019-09-26
- NEP PR: nearprotocol/neps#0000
Currently the separation between view methods and change methods on the contract level is not very well defined and causes quite a bit of confusion among developers. We propose in the NEP to elucidate the difference between view methods and change methods and how they should be used. In short, we would like to restrict view methods from accessing certain context variables and do not distinguish between view and change methods on the contract level. Developers have the option to differentiate between the two in frontend or through near-shell.
From the feedback we received it seems that developers are confused by the results they get from view calls, which are
mainly caused by the fact that some binding methods such as
do not make sense in a view call.
To avoid such confusion and create better developer experience, it is better if those context variables
are prohibited in view calls.
Among binding methods that we expose from nearcore, some do make sense in a view call, such as
while the majority does not.
Here we explicitly list the methods are not allowed in a view call and, in case they are invoked, the contract will panic with
<method_name> is not allowed in view calls.
The following methods are prohibited:
From the developer perspective, if they want to call view functions from command line on some contract, they would just
near view <contractName> <methodName> [args]. If they are building an app and want to call a view function from the
frontend, they should follow the same pattern as we have right now, specifying
To implement this NEP, we need to change how binding methods are handled in runtime. More specifically, we can rename
is_view and use that to indicate whether we are processing a view call. In addition we can add
HostError so that if
is_view is true,
then all the access to the prohibited
methods will error with
In terms of not allowing context variables, I don't see any drawback as those variables do not have a proper meaning in view functions. For alternatives, see the section below.
This design is very simple and requires very little change to the existing infrastructure. An alternative solution is to distinguish between view methods and change methods on the contract level. One way to do it is through decorators, as described here. However, enforcing such distinction on the contract level requires much more work and is not currently feasible for Rust contracts.