Functions

Functions in Solidity are pretty similar in syntax to those in JavaScript, but they have some key differences that you must understand, such as the fact that you must specify return types, the visibility of the function, and the modifiers that apply to each particular function, if any. The syntax is the following:

function example() public returns(uint256) { }

Functions have visibility just as variables do, where public functions can be executed by external users, contracts, and in the contract itself. External functions can only be by external entities, not by the contract itself. Internal functions can only be executed by the containing contract. Private functions can be executed only inside the current contract, or by inherited contracts.

Now, a function can have special modifiers that determine the type of function it is. This includes modifiers such as the following:

  • View: A view function is one that doesn't modify state variables but can read them. Remember that state variables are declared at the beginning of the contract, and they are used to store information directly on the blockchain. So, if your function doesn't modify any state variable, you have to mark it as view.
  • Pure: A pure function is even more restrictive. It applies to those functions that don't even read state variables. Pure functions are normally functions that make some type of calculation inside them without relying on external data. This usually includes mathematical functions or formatting functions.
  • Payable: A payable function is able to receive Ether when it is executed. It will store that Ether inside the contract, so it's very important that you create systems to extract the Ether that gets sent to the smart contract, otherwise the money will be stuck inside there forever. If your function is not marked as payable, when you send Ether alongside the function execution, you'll receive an error and the transaction will revert.

Here's how it looks:

string public myStateString = 'Hi';
function exampleOfView() public view returns(string memory) {
return myStateString;
}

In that function, we are simply reading and returning the myStateString state variable, so we can mark it as view. Note that we must use the memory keyword for string types, since they are a type of array internally like an array of each individual character.

Another example is as follows:

function sumTwoNumbers(uint256 numberA, uint256 numberB) public pure returns(uint256) {
uint256 result = numberA + numberB;
return result;
}

This pure function is simply adding two numbers and returning the result to the caller. It doesn't modify the state and it doesn't read the state variables.

Here's a payable function:

function receiveDonation() public payable {}

The receiveDonation function is empty because we only need to receive the Ether. We don't have to do anything with it.