Solidity Tutorial: Enum & Struct

Solidity Tutorial: Enum & Struct

Enums and structs enhance the organization of data in Solidity, the programming language for EVM smart contracts.

In this episode, you will briefly learn a broad definition of Enums and Struct, Their applications and their usage in writing smart contracts.

Enum

Enums in Solidity is a way to define a new custom data type that maps a set of named values to an underlying type (e.g. uint8). They provide a more descriptive and human-readable alternative to using numerical values and can simplify the code by reducing the chance of making mistakes when handling the values.

In Solidity, enums can be declared inside a contract or at the global level outside of any contract. The named values within an enum must be unique and can be referred to using the enum type followed by the name of the value (e.g. State.Inactive).

Here is an example of a smart contract written with enums

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// Define a contract named Example
contract Example {
    // Define an enum named State with 3 possible values
    enum State { Inactive, Active, Cancelled }
    // Declare a state variable of type State and make it publicly accessible
    State public state;

    // Function to set the state to a new value
    function setState(State newState) public {
        // Set the state variable to the value passed as an argument
        state = newState;
    }

    // Function to retrieve the current state
    function getState() public view returns (State) {
        // Return the value of the state variable
        return state;
    }
}

Copy and paste this code on your remix

Understanding the code

  • enum State { Inactive, Active, Cancelled }: This line declares an enum named State with three named values Inactive, Active, and Cancelled. These values can be used to represent different states for the contract.

  • State public state;: This line declares a public state variable of type State. The state variable will be used to keep track of the current state of the contract.

  • function setState(State newState) public: This is a function to set the state of the contract to a new value. It takes a single input argument of type State named newState and sets the value of the state variable to newState. The public keyword makes this function callable from outside the contract.

  • function getState() public view returns (State): This is a function to get the current state of the contract. It returns the current value of the state variable. The public keyword makes this function callable from outside the contract, and the view keyword means that this function does not modify the state of the contract. The returns (State) part of the function signature specifies that the function returns a value of type State.

Click the deploy button

Enums in Solidity can be useful in several ways:

  • Representing a set of constant values: Enums can be used to define a set of constant values, such as a set of states in a contract, and avoid hard-coding the values in the contract code.

  • Improving readability and reducing mistakes: Enums provide a more descriptive and human-readable alternative to using numerical values, which can improve the readability of the code and reduce the chance of making mistakes when handling the values.

  • Making the code more maintainable: Enums can make the code more maintainable by centralizing the definition of a set of values in a single place and making it easier to update the values in the future.

Struct

Structs are composite data types that allow you to define custom data structures, similar to records or classes in other programming languages. They allow you to group multiple variables of different types into a single unit, making it easier to manage and organize data in a smart contract.

An example of a contract written with a struct

// Define the CarRegistry smart contract
contract CarRegistry {
  // Define a struct named Car that holds information about a car
  struct Car {
    string make;   // Car make
    string model;  // Car model
    uint year;     // Car year of manufacture
  }

  // Define a mapping from a unique identifier to a Car struct
  mapping(uint => Car) public cars;

  // Keep track of the number of cars in the registry
  uint public carCount;

  // Function to add a new car to the registry
  function addCar(string memory _make, string memory _model, uint _year) public {
    // Add the new car to the cars mapping using the current carCount as the identifier
    cars[carCount] = Car(_make, _model, _year);

    // Increment carCount to keep track of the number of cars in the registry
    carCount++;
  }
}

Copy and paste this code on your remix

Understanding the code

This contract is named CarRegistry. The contract implements a simple car registry system to store information about cars.

The code defines a struct Car that has three fields: make, model, and year. The struct represents a car and holds information about the car's make, model, and year of manufacture.

The contract uses a mapping data structure to store the cars in the registry. The mapping maps a unique uint identifier to a Car struct. The cars mapping is declared as public, which means it can be accessed by anyone.

The carCount variable is a uint that keeps track of the number of cars in the registry. It is also declared as public, so it can be accessed from outside the contract.

The addCar function allows you to add a new car to the registry. It takes three arguments: _make, _model, and _year. These arguments represent the make, model, and year of manufacture for the car.

The function starts by adding the new car to the cars mapping. The car is stored using the current value of carCount as its identifier, and the car's information is stored as a Car struct.

The function increments carCount to keep track of the number of cars in the registry.

Now deploy the code on your remix. You should get this.

Here are a few key points to keep in mind when using structs in Solidity:

  • Definition: Structs are defined within a contract and have a name, just like variables and functions. You can define multiple structs within a single contract, each with its unique name.

  • Structure: Structs are made up of variables of different types, such as strings, integers, booleans, and other structs. The order and type of variables within a struct determine its structure.

  • Usage: Structs can be used as a type for variables, function parameters, or return values. You can also store structs in arrays or mappings to create complex data structures.

  • Access: Struct variables can be accessed using dot notation, just like object-oriented programming. For example, if you have a struct Car, you can access its make variable as Car.make.

  • Memory allocation: Structs are stored in memory, which is a limited and expensive resource in Solidity. It's important to consider memory usage when defining and using structs in your contract, especially when storing large amounts of data.

Conclusion

Both enums and structs are used to store and manage complex data structures in smart contracts. They are especially useful when dealing with large amounts of data, as they allow you to organize and access data in a structured and efficient way. By using enums and structs, you can write more readable, maintainable, and secure smart contracts.

Thanks for reading.