Recently, I have been revisiting Solidity, consolidating the finer details, and writing "WTF Solidity" tutorials for newbies.
Twitter: @0xAA_Science | @WTFAcademy_
Community: Discord|Wechat|Website wtf.academy
Codes and tutorials are open source on GitHub: github.com/AmazingAng/WTF-Solidity
Function
Here's the format of a function in Solidity:
It may seem complex, but let's break it down piece by piece (square brackets indicate optional keywords):
-
function
: To write a function, you need to start with the keywordfunction
. -
<function name>
: The name of the function. -
(<parameter types>)
: The input parameter types and names. -
[internal|external|public|private]
: Function visibility specifiers. There is no default visibility, so you must specify it for each function. There are 4 kinds of them:-
public
: Visible to all. -
private
: Can only be accessed within this contract, derived contracts cannot use it. -
external
: Can only be called from other contracts. But can also be called bythis.f()
inside the contract, wheref
is the function name. -
internal
: Can only be accessed internally and by contracts deriving from it.
Note 1:
public
is the default visibility for functions.Note 2:
public|private|internal
can be also used on state variables. Public variables will automatically generategetter
functions for querying values.Note 2: The default visibility for state variables is
internal
. -
-
[pure|view|payable]
: Keywords that dictate a Solidity functions behavior.payable
is easy to understand. One can sendETH
to the contract viapayable
functions.pure
andview
are introduced in the next section. -
[returns (<return types>)]
: Return variable types and names.
WTF is Pure
and View
?
When I started learning solidity
, I didn't understand pure
and view
at all, since they are not common in other languages. solidity
added these two keywords, because of gas fee
. The contract state variables are stored on the blockchain, and the gas fee
is very expensive. If you don't rewrite these variables, you don't need to pay gas
. You don't need to pay gas
for calling pure
and view
functions.
The following statements are considered modifying the state:
-
Writing to state variables.
-
Emitting events.
-
Creating other contracts.
-
Using selfdestruct.
-
Sending Ether via calls.
-
Calling any function not marked view or pure.
-
Using low-level calls.
-
Using inline assembly that contains certain opcodes.
I drew a Mario cartoon to visualize pure
and view
. In the picture, the state variable is represented by Princess Peach, keywords are represented by three different characters.

-
pure
: Functions containingpure
keywords cannot read nor write state variables on-chain. Just like the little monster, it can't see or touch Princess Peach. -
view
: Functions containingview
keyword can read but cannot write on-chain state variables. Similar to Mario, able to see Princess but cannot touch. -
Without
pure
andview
: Functions can both read and write state variables. Like theboss
can do whatever he wants.
Code
1. pure v.s. view
We define a state variable number = 5
Define an add()
function, add 1 to number
on every call.
If add()
contains pure
keyword, i.e. function add() pure external
, it will result in an error. Because pure
cannot read state variables in contract nor write. So what can pure
do? i.e. you can pass a parameter _number
to function, let function returns _number + 1
.
Example:

If add()
contains view
, i.e. function add() view external
, it will also result in an error. Because view
can read, but cannot write state variables. We can modify the function as follows:
Example:

2. internal v.s. external
Here we defined an internal minus()
function, number
will decrease 1 each time the function is called. Since the internal
function can only be called within the contract itself, we need to define an external
minusCall()
function to call minus()
internally.
Example:

3. payable
We defined an external payable minusPayable()
function, which calls minus()
and return ETH
balance of the current contract (this
keyword can let us query the current contract address). Since the function is payable
, we can send 1 ETH
to the contract when calling minusPayable()
.

We can see that the contract balance is 1 ETH
in the return message.

Example:

Summary
In this section, we introduced solidity
function type. pure
and view
keywords are difficult to understand since they are not common in other languages. You don't need to pay gas fees for calling pure
or view
functions, since they don't modify the on-chain data.