top of page
  • Writer's pictureJeffrey Scholz

Function modifiers (view, pure, payable) and fallback functions in Solana: why they don't exist


view, pure, payable, fallback, and receive in Solana

Solana does not have fallback or receive functions

A Solana transaction must specify in advance the accounts it will modify or read as part of a transaction. If a “fallback” function accesses an indeterminant account, then the entire transaction will fail. This would put an onus on the user to anticipate the accounts the fallback function will access. It’s much simpler as a result to simply disallow these kinds of functions.


Solana does not have a notion of a “view” or “pure” function

A “view” function in Solidity creates a guarantee that the state will not change using two mechanisms:

  • All external calls in a view function are staticcalls (calls that revert if a state change happens)

  • If the compiler detects state-changing opcodes, it throws an error

A pure function takes this even further by the compiler checking if there are opcodes that view the state.


These function restrictions happen mostly at the compiler level, and Anchor does not implement any of these compiler checks. Anchor is not the only framework for building Solana programs. Seahorse is another one. Perhaps some other framework will come along with function annotations explicitly stating what functions can and cannot do, but for now we can rely on the following guarantee: if an account is not included in the Context struct definition, that function won’t access that account.


This does not mean that the account cannot be accessed at all. For example, we could craft a separate program to read in an account and somehow forward that data to the function in question.


Finally, there is no such thing as a staticcall in the Solana virtual machine or runtime.


View functions aren’t necessary in Solana anyway

Because a Solana program can read any account passed to it, it can read an account owned by another program.


The program owning the account does not need to implement a view function to grant access for another program to view that account. The web3 js client — or another program — can view the Solana account data directly.


This has a very important implication:


It is not possible to use reentrancy locks to directly defend against read only reentrancy in Solana. The program must expose flag for readers to know if the data is reliable.


Read only reentrancy happens when a victim contract accesses a view function that is showing manipulated data. This can be defended against in Solidity by adding a nonReentrant modifier to the view function. However, in Solana there is no way to prevent another program from viewing data in an account.

However, Solana programs can still implement the flags reentrancy guards use. Programs consuming the account of another program can check those flags to see if the account might currently be in a reentrant state and should not be trusted.


There are no custom modifiers in Rust

Custom modifiers like onlyOwner or nonReentrant are a Solidity construct, and not a feature available in Rust.


Custom units are not available in Rust or Anchor

Because Solidity is intertwined with Ethereum, it has handy keywords like ethers or wei to measure Ethereum. Not surprisingly, LAMPORTS_PER_SOL is not defined in Rust, but somewhat surprisingly, it is not defined in the Anchor Rust Framework either. It is available in the Solana web3 js library however.


Similarly, Solidity has days as a convenient alias for 84,600 seconds, but no such equivalent exists in Rust/Anchor.


There is no such thing as “payable” functions in Solana. Programs transfer SOL from the user, users do not transfer SOL to the program

This is the subject of the next tutorial.


Learn more Solana with RareSkills

See our Solana development course for the next chapter



292 views0 comments

Comments


bottom of page