Reader small image

You're reading from  Solidity Programming Essentials. - Second Edition

Product typeBook
Published inJun 2022
PublisherPackt
ISBN-139781803231181
Edition2nd Edition
Concepts
Right arrow
Author (1)
Ritesh Modi
Ritesh Modi
author image
Ritesh Modi

Ritesh Modi is a technologist with more than 18 years of experience. He holds a master's degree in science in AI/ML from LJMU. He has been recognized as a Microsoft Regional Director for his contributions to building tech communities, products, and services. He has published more than 10 tech books in the past and is a cloud architect, speaker, and leader who is popular for his contributions to data centers, Azure, Kubernetes, blockchain, cognitive services, DevOps, AI, and automation.
Read more about Ritesh Modi

Right arrow

Chapter 6: Writing Smart Contracts

Solidity is an object-oriented programming language used to write smart contracts. This chapter will discuss the design aspects of writing smart contracts, defining and implementing a contract, and deploying and creating contracts using different mechanisms—using the new keyword and contract addresses. Object orientation is based on four concepts—abstraction, encapsulation, inheritance, and polymorphism—and this chapter will delve deep into object-oriented concepts and implementations.

This chapter covers the following topics:

  • Writing a simple contract
  • Creating contracts
  • Creating contracts via the new and existing address
  • Contract constructor
  • Contract composition
  • Inheritance
  • Encapsulation
  • Polymorphism
  • Method overloading
  • Abstract contracts
  • Interfaces
  • Advance interfaces
  • Library

Technical requirements

To follow the instructions in this chapter, you will need the following:

  • The Chrome or Firefox browser
  • The Remix editor

You can find the code files for this chapter on GitHub at https://github.com/PacktPublishing/Solidity-Programming-Essentials-Second-Edition/tree/main/Chapter06.

Smart contracts

Smart contracts are programs (bytecode) deployed and executed in the Ethereum Virtual Machine (EVM). A contract is a term generally used in the legal world and has little relevance in the programming world. But writing a smart contract in Solidity does not mean writing a legal contract. Instead, contracts are like any other programming code, containing Solidity code, and are executed when someone invokes them.

There is nothing smart about smart contracts. It is a blockchain term; a piece of jargon used to refer to programming logic and code that executes within a blockchain virtual machine. A blockchain virtual machine is an interpreter that understands programming constructs related to smart contracts.

A smart contract is very similar to a C++, Java, or C# class. Just as a class is composed of state (variables) and behaviors (methods), contracts contain state variables and functions. The purpose of state variables is to store data within a contract. Functions...

Writing a smart contract

A contract is declared using the contract keyword, along with an identifier, as shown in the following code snippet:

contract SampleContract {
}

Within the brackets comes the declaration of state variables and function definitions. Chapter 3, Introducing Solidity, introduced a smart contract that contained almost all important constructs to build a smart contract. The same contract is shown again for quick reference. This contract has state variables, struct definitions, enum declarations, function definitions, modifiers, and events. State variables, structs, and enums were discussed in detail in Chapter 4, Global Variables and Functions. Functions, modifiers, and events will be discussed in detail over the next two chapters. Take a look at the following code listing depicting the contract:

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract GeneralStructure { 
int public stateIntVariable; 
string stateStringVariable...

Creating contracts

There are the following two ways of creating and using a contract in Solidity:

  • Using the new keyword
  • Using the address of the already-deployed contract

Using the new keyword

The new keyword in Solidity deploys and creates a new contract instance. It initializes the contract instance by deploying the contract, initializing the state variables, running its constructor, setting the nonce value to 1, and, eventually, returning the address of the instance to the caller.

Deploying a contract involves checking whether the sender has provided enough gas to complete the deployment, generating a new account/address for contract deployment using the requestor's address and nonce values, and passing on any Ether sent along with it.

In the following code snippet, two contracts, HelloWorld and client, are defined. In this scenario, one contract (client) deploys and creates a new instance of another contract (HelloWorld). It does so using the new...

Contract constructor

Solidity supports declaring a constructor within a contract. They are optional and the compiler induces a default constructor when none is explicitly defined.

The constructor is executed once while deploying the contract. It is quite different from other programming languages. In other languages, a constructor is executed whenever a new object instance is created. Deployment of the contract also happens using the new keyword and each time it deploys a new contract instance with a new address. In short, constructor code is invoked every time a new contract instance is created using the new keyword, or it is deployed using frameworks such as Truffle/Hardhat.

Constructors should be used to initialize state variables and set up the context. The constructor code is the initial code executed for a contract. There can be at most one constructor in a contract, unlike constructors in other programming languages. Constructors can take parameters and corresponding...

Contract composition

Solidity supports contract composition. Composition refers to combining multiple contracts to create complex data structures and contracts. We have already seen numerous examples of contract composition before. Refer to the code snippet for creating contracts using the new keyword shown in the Using the new keyword section. In this example, the Client contract is composed of the HelloWorld contract. Here, HelloWorld is an independent contract and Client is a dependent contract. It is dependent on the HelloWorld contract for its completeness. It is a good practice to break down problems into multicontract solutions and compose them together using contract composition.

Inheritance

Inheritance is one of the pillars of object orientation and Solidity supports inheritance between smart contracts. Inheritance is the process of defining multiple contracts that are related to each other through parent-child relationships. In inheritance, there is a parent contract and child contracts deriving from the parent contract. Inheritance is defined using an is-a relationship between parent and child contracts. The child contract inherits all the functions of the parent contract. There is another terminology to refer to parent and child contracts—base (parent) contract and derived (child) contracts.

Inheritance is about code reusability. As mentioned before, there should be an is-a relationship between parent and child contracts, and all public-, external- and internal-scoped functions and state variables are available to derived contracts. In fact, internally, the Solidity compiler copies the base contract bytecode into the derived contract bytecode...

Encapsulation

Encapsulation is one of the most important pillars of OOP. It refers to the concept of declaring state variables that cannot be accessed directly by clients and can only be accessed and modified using functions. This helps in restricting access to variables but, at the same time, allows enough access to the class for taking action on it.

Solidity provides multiple visibility modifiers, such as external, public, internal, and private, which affect the visibility of state variables within the contract in which they are defined, inheriting child contracts or outside contracts.

After covering inheritance and encapsulation, the next important object-oriented concept is polymorphism, which is the next topic of discussion.

Polymorphism

Poly means many and morph means forms. Together, the word polymorphism means multiple forms. It means that contracts in inheritance can be accessed using a common interface. It also means that multiple functions with the same name can be defined and invoked using different objects. There are the following two types of polymorphism:

  • Function polymorphism
  • Contract polymorphism

Function polymorphism

Function polymorphism refers to declaring multiple functions within the same contract or inheriting contracts with the same name. The functions differ in the parameter data types or the number of parameters. Return types are not taken into consideration for determining valid function signatures for polymorphism. This is also known as method overloading.

The following code segment illustrates a contract that contains two functions that have the same name but different data types for incoming parameters. The first function, getVariableData, accepts int8...

Method overriding

Method overriding is the process of redefining a function available in the parent contract with the same name and signature in the derived contract. A parent contract contains two functions, SetInteger and GetInteger. A child contract inherits from the parent contract and implements GetInteger by overriding the function.

Now, when a call to the GetInteger function is made on the child contract, even while using a parent contract variable, the child contract instance function is invoked. This is because all functions in contracts are virtual and based on a contract instance; the most derived function is invoked.

Abstract contracts

Abstract contracts are contracts that have partial function definitions. You cannot create an instance of an abstract contract. An abstract contract must be inherited by a child contract to utilize its functions.

Abstract contracts help in defining the structure of a contract, and any class inheriting from it must ensure to provide an implementation for them. If the child contract does not provide the implementation for incomplete functions, its instance cannot be created. The function signature is terminated using a semicolon (;). Solidity provides an abstract keyword to mark a contract as abstract. This is a relatively new keyword addition and it was not part of prior versions. A contract becomes an abstract contract when it consists of functions without any implementation.

The following code snippet is an implementation of an abstract contract.

The abstractHelloWorld contract is an abstract contract as it contains a couple of functions without any...

Interfaces

Interfaces are like abstract contracts, but there are differences. Interfaces cannot contain any definitions; they can only contain function declarations. It means functions in interfaces cannot contain any code. They are also known as pure abstract contracts.

An interface can contain only the signature of functions. It also cannot contain any state variables. It cannot inherit from other contracts or contain enums or structures. However, interfaces can inherit other interfaces. The function signatures terminate using the semicolon (;) character. Interfaces are declared using the interface keyword followed by an identifier. The following code block shows an implementation of an interface. The IHelloWorld interface is defined, containing two function signatures—GetValue and SetValue. There are no functions containing any implementation. IHelloWorld is implemented by the HelloWorld contract. Contracts that intent to use this contract would create an instance as...

Library

Programming languages provide facilities to write reusable code and use it across multiple projects. Solidity has a similar concept through which code written once in a library can be reused across multiple smart contracts. A library in Solidity is created using the library keyword followed by the library code within a {} block:

library {
}

The concept of a library might sound very similar to that of a contract; however, there are differences. The similarity of a library with a contract is that they both consist of functions and they both can be deployed on the Ethereum network. They both generate unique addresses on the Ethereum network. However, a library can declare its own state variables. A library does not manage or maintain any state. It has a set of functions that are available for use as reusable code. So, ideally, they are best suited for implementing logic that is common across contracts without the involvement of state variables.

The code for a simple...

Summary

This brings us to the end of this chapter. It was a heavy chapter that focused primarily on smart contracts, the different ways to create an instance, and all the important object-oriented concepts related to them, including inheritance, polymorphism, abstraction, and encapsulation. Multiple types of inheritance can be implemented in Solidity. Simple, multiple, hierarchical, and multilevel inheritance were discussed, along with the usage and implementation of abstract contracts and interfaces. It should be noted that by using inheritance in Solidity, there is eventually just one contract that is deployed instead of multiple contracts. There is just one address that can be used by any contract with a parent-child hierarchy. You learned how to use object-oriented concepts, such as inheritance, abstraction, and polymorphism, with Solidity and contracts.

The next chapter will focus purely on functions within contracts. Functions are central to writing effective Solidity contracts...

Questions

  1. What are the different ways through which a contract instance can be created within a smart contract?
  2. Do smart contracts support both function- and contract-level polymorphism?
  3. What are the differences between abstract contracts and interfaces?
lock icon
The rest of the chapter is locked
You have been reading a chapter from
Solidity Programming Essentials. - Second Edition
Published in: Jun 2022Publisher: PacktISBN-13: 9781803231181
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Ritesh Modi

Ritesh Modi is a technologist with more than 18 years of experience. He holds a master's degree in science in AI/ML from LJMU. He has been recognized as a Microsoft Regional Director for his contributions to building tech communities, products, and services. He has published more than 10 tech books in the past and is a cloud architect, speaker, and leader who is popular for his contributions to data centers, Azure, Kubernetes, blockchain, cognitive services, DevOps, AI, and automation.
Read more about Ritesh Modi