Learn about decision making, managing ETH, the require
function, tracking trades, and enforcing terms of a smart contract.
By the end of this post, readers will be able to:
payable
function's role in smart contracts.require
function works in Solidity smart contracts.require
function to enforce smart contract terms.In the previous lesson, we defined the basic structure of a smart contract, and wrote a function as well as variables for storing data. In this lesson, we’ll create functions that add functionality to a smart contract.
In order for our functions to receive ether, they must be attached to a modifier called payable
. payable
is a reserved keyword in Solidity. Usually, there is a no name
function that accepts ether that is to be sent to a contract. This is called a fallback function, which we’ll dive into a bit later.
function () payable {}
An exception is when you have more than one payable
function that is used to perform different tasks, such as registering a deposit to your contract:
function deposit() payable {
deposits[msg.sender] += msg.value;
};
Each time you deploy a smart contract, a public Ethereum address is assigned to it.
In the contract below, anyone can add ETH via the contract address or the deposit
function. Anyone can also send any amount of ETH to any address that we specify to the withdraw
function, as long as we have enough in our balance.
pragma solidity ^0.5.0;
contract CustomerSavings {
function withdraw(uint amount, address payable recipient) public {
return recipient.transfer(amount);
}
function deposit() public payable {}
function() external payable {}
}
The function at the end without a name is known as a fallback function. If we don't add the fallback function, and ETH gets sent to our contract address, the ETH will be returned. This forces other users to send ETH via the deposit
function.
A fallback function is used in two scenarios:
external
keyword so that other contracts or transactions can call this contract. We also add the payable
keyword so that the contract can collect any amount of ETH that gets sent to it via the contract address.Below, you will gain practical experience with using conditional statements in Solidity. We’ll use basic logical operators and a control flow—an order of statements and functions—to build a smart contract that tracks trades in the Ethereum blockchain.
The code snippet below showcases using if/else statements and stacked conditionals:
pragma solidity ^0.5.0;
contract TradeController {
uint previousPrice;
string tradeType;
function makeTrade(uint currentPrice, bool buyAnyway) public {
if (currentPrice < previousPrice || buyAnyway) {
tradeType = "Buy";
previousPrice = currentPrice;
}
else if (currentPrice > previousPrice) {
tradeType = "Sell";
previousPrice = currentPrice;
}
else {
tradeType = "Hold";
}
}
}
An alternative to conditionals in Solidity is the require
function. Use cases for the require
function include:
The require
function checks a condition just like an if
statement does. But if the condition is false, it will return the unused gas and any ETH and roll back the entire transaction. Consider it a hard stopping point: you require a specific condition to be true to continue.
pragma solidity ^0.5.0;
contract BankAccount {
address payable accountOwner = 0xc3879B456DAA348a16B6524CBC558d2CC984722c;
function withdraw(uint amount, address payable recipient) public {
require(recipient == accountOwner, "You don’t own this account!");
return recipient.transfer(amount);
}
function deposit() public payable {}
function() external payable {}
}
In the preceding code, we use the require
function to check if the recipient is the account owner. If the conditional statement is false, the recipient isn’t the account owner. So, the code raises (returns) an exception that throws (displays) a message reading "You don't own this account!"
Until next time, here’s a twitter thread summary of this post: