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 15: Solidity Design Patterns

Solidity is a contract-based language. You might wonder what a language has to do with entity modeling. On the face of it, it does not sound right; however, after security, entity modeling is probably one of the most important activities for writing smart contracts. But why is entity modeling an important exercise for smart contracts? To understand this question, we must understand the purpose of smart contracts. Smart contracts comprise two important facets:

  1. Entities
  2. Logic

Data stored in smart contracts is stored permanently within Ethereum storage. The use of storage comes with the cost of reading and writing to it. It is for this reason that it is very important to store optimal data that is necessary for the functioning of the smart contract and use case. In this chapter, we will understand how entities should be modeled for smart contracts, the different data types used for storing data, the read and write patterns, the redundancy...

Technical requirements

For this chapter, you'll need the following:

  • A web browser with an internet connection
  • Access to the Remix portal from the web browser

The code files for this chapter can be found on GitHub at https://github.com/PacktPublishing/Solidity-Programming-Essentials-Second-Edition/tree/main/Chapter15.

Introducing entity modeling

Entity modeling is not a new concept. It is an age-old practice employed whenever large amounts of data are stored in any system. Entity modeling is used for data stores, such as SQL Server and Oracle. Entity modeling is required for two reasons:

  • Increase the performance of an application while reading and writing data to a data store.
  • Optimize storage to reduce the cost of storage.

Data stores such as SQL Server or Oracle do not have a cost associated with them while reading and writing data. However, Ethereum has a cost of 5,000 gwei for reading and 20,000 gwei for writing data. There is a recurring cost every time data is accessed.

Entity modeling refers to determining the global storage for smart contracts that serve a particular use case.

Ethereum storage

Ethereum provides multiple types of storage:

  • Global storage: This is permanent storage in Ethereum and the data is persisted permanently. This data can be read in...

Understanding data modeling in Solidity

Data stored in Ethereum has a fixed schema and layout. Once a smart contract is created with global storage and deployed, it cannot be modified. Its layout is determined, and it remains the same for the lifetime of the contract.

All data required by a decentralized application can be stored within a single smart contract. However, managing such a smart contract can easily become a nightmare and there can be more than one reason for versioning the smart contract and redeploying. A better strategy is to divide all the required data into smaller data buckets and put them in separate smart contracts. This will ensure that even in the case of changes, only part of the application and smart contract will be redeployed instead of the entire application.

However, this approach poses a different set of challenges, such as how should related data be retrieved together from multiple smart contracts, how can we put related data in multiple smart contracts...

Exploring types of relationships

In terms of references between two structures, there are three different possibilities, which we will explore in the next sections.

One-to-one relationships

In a one-to-one relationship, two structures are related to each other, with each having a single entity, and they are related using an identifier. The related instance contains a single record of data for each main structure. It is to be noted that the relationship can be navigated from both the related structure to the main structure and the main structure to the related structure. However, it is mandatory to have a relationship from the main to the related structure. The following code block shows that there is a main structure and a related structure. Both structures have a common property, familyId, through which they are related and interconnected:

struct Main {
      address customerEtherAddress;
      uint256 familyId;...

Reviewing the rules for embedding structures

By now, we understand both references and nested/embedded structures at a conceptual level. It is important to also know the rules for using nested structures compared to references. It is to be noted that these rules represent best practices and can change depending on the context:

  • The embedded structure is not going to change anytime in the near future.
  • There is a containment relationship between structures.
  • There are one-to-few relationships between structures.
  • The data that is embedded does not change frequently.
  • The embedded data is needed frequently along with the parent structure.
  • The embedded data will not grow out of bounds.

Let's understand each of these rules in detail.

Data cohesion

If the data from multiple structures is read together, it is wise to put it together as well such that it can be read in a single step. Otherwise, the application must invoke multiple calls to different...

Performing data modeling using an example

The previous discussion should ignite your minds with thoughts that data modeling is an extremely important exercise for smart contracts and using the right data types for storing the values is equally important.

Let's understand the entire process using an example and assume that we again want to store employee and address information as part of a decentralized application.

Structures

The structure for employee is quite simple and it has been purposely kept so. You can add as many elements to it as you deem necessary:

struct Employee {
    address identifier,
    bytes32 name,
    uint8 age,
    bytes32 email
}

An Address struct is shown next:

    struct ContactAddress {
      string city;
      string state;
    }

The employee struct in...

Ownership in smart contracts

Ownership is an important concept in smart contracts. Smart contracts are custodians of digital assets. These assets are of value and can be traded on exchanges as well. Smart contracts are capable of transferring these assets between addresses. It is also possible to have certain logic within smart contracts where only privileged users should be able to execute it. These functions are not meant for all other users of smart contracts. Again, instead of one, there could be multiple owners of a contract, also known as multisignature (MultiSig) contracts. Approvals or signatures of all the owners within a MultiSig contract are required to execute the privileged function. Now, we will explore ownership-related patterns within Solidity.

Exploring ownership in Solidity

Solidity has some unique features that are not available in other programming languages, and it requires us to rethink it from a design patterns perspective. Solidity provides unique constructs, such as modifiers, which have a different way of handling and throwing exceptions, and has unique concepts, such as gas, Ether, consumption of gas, payable functions, and fallback functions.

Solidity was envisioned to provide a means to write contracts, although writing a contract looks very similar to writing an object-oriented class along with its methods and variables. In essence, contracts are a completely different genre and provide implementations that are unique to contract-based languages.

In this chapter, we will investigate design patterns that do not demand a complete chapter on their own but are very important from the usage and implementation perspectives. We will first understand what ownership is, and then cover the following:

  • Ownable...

Establishing ownership of a smart contract

A smart contract can be owned and controlled by an externally owned or another contract account.

Sometimes, a smart contract needs to be owned by someone. For example, if you are deploying a smart contract to store your employee details, it should be possible for you to manage some of its operations exclusively. Moreover, you should have control over the lifetime of the smart contract. There are many other use cases, such as in the case of Initial Coin Offerings (ICOs), Decentralized Autonomous Organizations (DAOs), and other industry-related use cases.

The next example shows one of the ways to own a smart contract. It is named ownable and contains a single state variable, owner, of the address type. There is a constructor that gets executed at the time of deployment of the contract. Within the constructor, the externally owned address deploying the contract is captured using the msg.sender global property and is assigned to the state...

Stoppable/haltable smart contract pattern

The next pattern we will discuss is used heavily with smart contracts related to ICOs. We all know that smart contracts deployed on public Ethereum can be accessed by anyone. Thus, these contracts can be subjected to multiple types of hacking attacks. There have been several occasions, either because of the shortcomings of a smart contract or the hacker being able to find vulnerabilities, where smart contracts have been hacked, their balances siphoned off, and even the ownership being changed to some other externally owned account. We also know that smart contracts are immutable and there is no way they can be deactivated or activated at will. At such times, it is important that the smart contract execution can be stopped to minimize losses. The pattern we will discuss next is known as the haltable, stoppable, or pausable pattern.

This pattern stops the execution of functions within a smart contract and can resume the execution after the...

Summary

The focus of this chapter was to understand data modeling with regard to smart contracts. Smart contracts contain state variables, and they are costly in terms of their usage. This chapter introduced concepts related to nested or embedded structures viz-a-viz reference structures and concepts related to the use of references versus nested structures. However, modeling structures and storing them in mappings viz-a-viz arrays can make big differences in terms of access and write patterns. Looping plays a big role in deciding whether arrays or mappings should be used.

We also saw a complete example of a smart contract with multiple structures used in various operations, such as reading, writing, and looping. In this chapter, two other important patterns were discussed. The first set of patterns was related to establishing and transferring ownership of both assets and contracts, and the next pattern was to stop executing functions in a contract in the event of an emergency....

Questions

  1. What kind of relationship between structs, implemented in the child structs, can have an unlimited number of instances?
  2. What feature of Solidity helps in implementing the ownership of contracts?

Further reading

To learn more about common patterns in Solidity, visit here: https://docs.soliditylang.org/en/latest/common-patterns.html

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