# How do Solidity functions work?

Solidity functions use `function` keyword, can be `view` or `pure`, and have visibility levels: `public`, `external`, `internal`, `private`.

Intro to Solidity Functions

Previous Section Recap
In the previous section, we learned the basics of the [Solidity](https://docs.soliditylang.org/en/v0.8.17/) smart contract programming language. Here are some of the important takeaways we looked at:
• In Solidity, a `contract` is very similar to a JavaScript `class`
• The syntax to declare state variables is:
``````// data_type + visibility + variable_name = some_value;
bool public isHappy = true;
``````
• `msg.sender`: who is the `from` in the current calling tx?
• `msg.value`: what is the `value` in the current calling tx?

## Solidity Functions

In Solidity, a function is generally defined by using the `function` keyword. Functions are where actual logic is contained on a smart contract. Let's dive in...

### Solidity Functions - Syntax

The most common way to define a function in Solidity is by using the `function` keyword:

``````// function_keyword + function_name(paramter_list) + visibility {}
function helloWorld(bool _saysHello) public {
// statements
}
``````

If the function returns a value, the syntax of a function header includes a `returns` statement, as shown below:

Let's get some Solidity up in this place! Here's a quick function in a sample `MyContract`:

``````contract MyContract {
function myFunction() external pure {
uint x = 5;
}
}
``````

The`myFunction` above doesn't really do much! Once called, the function will just declare a new variable `x` with a value of `5` in local memory, then execution will end which means local memory is wiped. Nothing happens! 🤷

This is what a script call to this function would look like in JavaScript:

``````const myTx = await contract.myFunction();
``````

The above script call will send a transaction to the `MyContract` address with a specific call to the `myFunction()` endpoint. The EVM will execute the statements inside until it reaches the closing bracket. Once the logic in a function completes, the transaction is mined and any effects are indexed in the tx's own receipt.

What about a function that actually does something? Here is one example:

``````function changeOwner(address _newOwner) public {
owner = _newOwner;
}
``````

The above function lives in a smart contract containing an `owner` state variable. By calling the `changeOwner()` function and passing a new `address` to it, the contract will overwrite the current contract `owner` with the passed-in `_newOwner` value.

### Solidity Functions - Declarations

You will sometimes see functions in Solidity contain one of the following keywords: `view` and `pure`.

`view`: this function promises that NO state will be changed, only read

This is basically a keyword that can be seen as the function itself saying: "I promise to just "view", not change state!" 🙋‍♂️

`pure`: this function promises that NO state will be changed nor read

This is basically a keyword that can be seen as the function itself saying: "I promise to act completely independent of the smart contract I am in!" 🙋‍♂️

#### View Function Example

Let's set up a simple contract with two state variables...

``````pragma solidity 0.8.4;
contract MyContract {
uint x = 5;
uint y = 10;
}
``````

Let's then add a new function called `sum()` and declare it as `view`:

``````pragma solidity 0.8.4;
contract MyContract {
uint x = 5;
uint y = 10;

function sum() external view returns(uint) {
return x + y;
}
}
``````

Notice how the `sum()` function, declared as `view`, keeps it promise? It is only reading from state because it uses the `x` and `y` state variable values in order to return their sum. It is reading from state to produce a new value but it is not changing any state.

A `view` cannot write to storage. 🔏

#### Pure Function Example

If you noticed in the first contract example, there is already a `pure` function used:

``````contract MyContract {
function myFunction() external pure {
uint x = 5;
}
}
``````

The keyword `pure` means this function does not read or write storage. It is function completely independent from contract state. But again, the function above is not really useful at all...

### Solidity Functions - Returns

A more useful `pure` function would be one that `returns` something:

``````contract MyContract {
function add(uint x, uint y) external pure returns(uint) {
return x + y;
}
}
``````

`pure` functions like the one shown above are typically used in libraries or for functionality that is not specific to a smart contract's state but is still needed for independent contract operations.

Notice the syntax required for functions that actually `return` a value? You must indicate the return type in the `returns(data_type)` block.

#### Implicit Return

The `returns` syntax in Solidity can also look like this:

``````contract MyContract {
function add(uint x, uint y) external pure returns(uint z) {
z = x + y;
}
}
``````

Believe it or not, `z` is implicitly returned here! 🤯

#### Return Multiple Values

``````contract MyContract {
function mathTime(uint sum, uint product) external pure returns(uint sum, uint product) {
sum = x + y;
product = x * y;
}
}
``````

In this case, both the `sum` and `product` are returned.

#### Return Multiple Values Using `return`

``````contract MyContract {
function mathTime(uint sum, uint product) external pure returns(uint, uint) {
uint sum = x + y;
uint product = x * y;

return (sum, product);
}
}
``````

The returned value is referred to as a tuple.

### Functions - Writing to Storage

A function can write (fancy term for changing some state) if it is NOT `pure` or `view`:

``````contract MyContract {
uint x = 5;
uint y = 10;
uint z;

function storeSum() external {
z = x + y;
}
}
``````

Since this function is writing to storage via directly assigning a value to the `z` state variable, it will always cost gas to execute on the Ethereum network.

Storage is expensive on the Ethereum network! 💸 As a developer, you must always be optimizing for the least friction possible when changing state so that you do not incur large gas costs to you or your users!

### Solidity Functions - Visibility

We've only seen the `public` visibility so far. Function signatures always contain a visibility identifier... basically, how accessible to do you want this function to be?

Functions can be declared, from most-public to least-public, as:

• `public` - any contract or EOA can call into this function
• `external` - only other contracts (external to the current contract) and EOAs can call, no internal calling
• `internal` - only this contract along with its inheritance chain can call
• `private` - only this contract can call

🚨 State variables work off the same exact criteria for visibility. State variables can be declared as `public`, `private`, or `internal` but not `external`.