Idioms of Solidity Smart Contract Programming

Kwang Yul Seo
CodeChain
Published in
3 min readApr 26, 2018

Solidity is a new and highly experimental programming language for writing Ethereum-flavoured smart contracts. When Solidity first came out, nobody likely knew how to write smart contracts. One could learn the syntax and semantics of the language, but it was impossible to refer to other idioms.

Fortunately, as developers started to write smart contracts over time, several patterns and idioms have emerged. For example, smart contract developers realized that they tended to write the same life cycle management and access control code again and again. So they started to create a reusable library that could be imported by other smart contracts.

The most popular library is OpenZeppelin. It provides secure, tested and community-audited code that can be reused. In this post, we will look at some of the most common idioms of Solidity smart contract programming through OpenZeppelin library.

Ownership

Many smart contracts have functions that only its owner can call. A common way of implementing this is to assign the value of msg.sender to a state variable. Then functions that need access control check if msg.sender is equal to the stored owner and throw if they do not match.

OpenZeppelin’s Ownable contract captures the essence of this idiom. onlyOwner modifier provided by Ownable throws if it is called by any account other than the owner. A smart contract inheriting Ownable can simply add onlyOwner modifier to the functions that need access control.

contract Ownable {  address public owner;  function Ownable() {    owner = msg.sender;  }  modifier onlyOwner() {    require(msg.sender == owner);    _;  }}

Ownable also provides transferOwnership function which transfers control to a new owner. It emits OwnershipTransferred event once the ownership is successfully transferred.

Lifecycle management

In addition to the ownership management, a lot of smart contracts need to be destroyed when they are no longer needed. selfdestruct operation removes the code from the blockchain and sends the remaining Ether stored at the contract address to a designated target. As this operation must be called by the owner of the contract, OpenZeppelin provides Destructible contract which is inherited from Ownable. Its member function destroy transfers the current balance to the owner while its sibling member destroyAndSend transfers the current balance to the given recipient.

contract Destructible is Ownable {  function Destructible() payable { }  function destroy() onlyOwner {    selfdestruct(owner);  }  function destroyAndSend(address _recipient) onlyOwner {    selfdestruct(_recipient);  }}

Another common idiom regarding the lifecycle management of a contract is circuit breaker. Any non-trivial contract has errors in it. Peer review and code auditing cannot guarantee the absence of bugs since new bugs and security risks are being constantly discovered. Therefore, you must be able to respond to bugs and vulnerabilities.

Circuit breaker provides a way of pausing a contract when things go wrong. OpenZeppelin’s Pausable contract is the implementation of circuit breaker idiom. Functions decorated with whenNotPaused modifier throw when the contract is paused by calling pause function. When you discover your smart contract is under attack, you can buy time to upgrade the contract by immediately pausing the contract.

contract Pausable is Ownable {  event Pause();  event Unpause();  bool public paused = false;  modifier whenNotPaused() {    require(!paused);    _;  }  modifier whenPaused() {    require(paused);    _;  }  function pause() onlyOwner whenNotPaused {    paused = true;    Pause();  }  function unpause() onlyOwner whenPaused {    paused = false;    Unpause();  }}

In this post, we covered only the most common idioms that are used in almost all contracts. This is not the end of story. There are other idioms for common smart contract usages such as crowdsale and token. If you are interested in knowing more, refer to the source code of OpenZeppelin.

Originally Posted by CodeChain Team on Wed, Oct 18, 2017

--

--