5 min read

Tuples

Introduction

Solidity is a contract-oriented programming language that is used to write smart contracts on the Ethereum blockchain. It is a statically typed language that supports various data types, such as integers, strings, arrays, mappings, and structs. With the release of Solidity 0.8.0, the language also introduced a new data type called "Tuple," which provides a way to group multiple values into a single variable.

Tuples are a powerful data type that allows you to group together multiple values of different data types. They are similar to structs, but unlike structs, they do not require you to define a new type for each set of related values. Instead, you can create a tuple variable on the fly, and assign values to it without having to define a new struct type.

In this blog post, we'll take a deep dive into the Tuple data type in Solidity 0.8.16, and explore how it can be used in smart contract development.

What is a Tuple?

In Solidity, a Tuple is a data structure that groups together multiple values of different data types into a single variable. It is a way of creating a temporary type that allows you to group values together without defining a new struct.

Tuples can be created by enclosing a comma-separated list of values within parentheses. Here is an example:

pragma solidity 0.8.16;

contract MyContract {
    function getTuple() public pure returns (uint, string memory) {
        return (123, "Hello world");
    }
}

In this example, we define a function getTuple() that returns a tuple with two values: a uint and a string. The returns statement in the function signature specifies the types of the values returned by the function.

We can then call the function and receive the values in a tuple variable, like this:

(uint myUint, string memory myString) = myContract.getTuple();

In this case, we use a tuple assignment to assign the values returned by getTuple() to two separate variables: myUint and myString.

Tuple Syntax

The syntax for creating a Tuple in Solidity is similar to that of other programming languages. You enclose a comma-separated list of values within parentheses, like this:

(uint, string) myTuple = (123, "Hello world");

In this example, we create a Tuple called myTuple that contains two values: a uint with the value 123, and a string with the value "Hello world".

You can also use named values in a Tuple, like this:

(uint myUint, string myString) = (123, "Hello world");

In this example, we define two named values myUint and myString in the Tuple. When we assign the Tuple to the variables, the values are assigned to the corresponding named variables.

Accessing Tuple Values

To access the values in a Tuple, you can use the dot notation to access the individual values by their index or name. Here's an example:

pragma solidity 0.8.16;

contract MyContract {
    struct Person {
        string name;
        uint age;
        bool isEmployed;
    }

    function createPerson(string memory name, uint age, bool isEmployed) public pure returns (Person memory) {
        return Person(name, age, isEmployed);
    }

    function getPerson() public pure returns (string memory, uint, bool) {
        Person memory person = Person("John Doe", 30, true);
        return (person.name, person.age, person.isEmployed);
    }
}

In the above example, we define a Person struct that contains three values: nameage, and isEmployed. We then define a function createPerson that returns a Person struct.

The getPerson function creates a Person struct with the values "John Doe", 30, and true, and returns a Tuple containing these values.

We can access individual values in the returned Tuple using the dot notation, like this:

pragma solidity 0.8.16;

contract MyContract {
    struct Person {
        string name;
        uint age;
        bool isEmployed;
    }

    function createPerson(string memory name, uint age, bool isEmployed) public pure returns (Person memory) {
        return Person(name, age, isEmployed);
    }

    function getPerson() public pure returns (string memory, uint, bool) {
        Person memory person = Person("John Doe", 30, true);
        return (person.name, person.age, person.isEmployed);
    }

    function getPersonName() public pure returns (string memory) {
        (string memory name, , ) = getPerson();
        return name;
    }

    function getPersonAge() public pure returns (uint) {
        (, uint age, ) = getPerson();
        return age;
    }

    function isPersonEmployed() public pure returns (bool) {
        (, , bool isEmployed) = getPerson();
        return isEmployed;
    }
}

In the above example, we define three additional functions getPersonNamegetPersonAge, and isPersonEmployed that return individual values from the Person struct by accessing them using the dot notation.

Returning Tuples

You can also return a Tuple from a Solidity function. To do this, simply specify the return type as a Tuple. Here's an example:

pragma solidity 0.8.16;

contract MyContract {
    function returnTuple() public pure returns (string memory, uint) {
        return ("Hello, World!", 42);
    }
}

In the above example, the returnTuple function returns a Tuple containing a string and an unsigned integer.

You can also use a Tuple to return multiple values from a function, like this:

pragma solidity 0.8.16;

contract MyContract {
    function returnMultipleValues() public pure returns (string memory, uint) {
        string memory hello = "Hello, World!";
        uint answer = 42;
        return (hello, answer);
    }
}

In the above example, the returnMultipleValues function returns a Tuple containing a string and an unsigned integer.

Tuple as Function Input

You can also use a Tuple as a function input. This allows you to pass multiple variables to a function in a single argument.

Here's an example using our Person struct and a function that creates a new Person:

pragma solidity 0.8.16;

contract MyContract {
    struct Person {
        string name;
        uint age;
    }

    function createPerson(tuple string _name, uint _age) public pure returns (Person memory) {
        Person memory newPerson = Person(_name, _age);
        return newPerson;
    }
}

In this example, the createPerson function takes a tuple as an input, with the first element of the tuple being a string representing the person's name, and the second element being a uint representing the person's age.

The function creates a new Person struct using the input values and returns it as a memory reference.

Note that we use the memory keyword to indicate that the Person struct should be stored in memory rather than storage. This is because the createPerson function is a pure function, which means it does not modify the state of the contract and should not have any permanent effect.

Tuple as Function Return Value

You can also use a Tuple as a return value from a function. This allows you to return multiple values from a function in a single return statement.

Here's an example using our Person struct and a function that returns a new Person:

pragma solidity 0.8.16;

contract MyContract {
    struct Person {
        string name;
        uint age;
    }

    function createPerson(string memory _name, uint _age) public pure returns (tuple string, uint) {
        Person memory newPerson = Person(_name, _age);
        return (newPerson.name, newPerson.age);
    }
}

In this example, the createPerson function creates a new Person struct using the input values and returns a tuple containing the person's name and age.

Note that we use the memory keyword to indicate that the Person struct should be stored in memory rather than storage. We also use the tuple keyword to indicate that we are returning a tuple from the function.

Conclusion

In Solidity, Tuples provide a convenient way to group multiple variables together and can be used as inputs, return values, and local variables in functions. They are particularly useful when you need to pass multiple variables to a function or when you need to return multiple values from a function.

Tuples can be declared with or without named elements, and their values can be accessed using dot notation. When declaring Tuples with named elements, you can also use them to create Structs.

Overall, Tuples are a powerful feature in Solidity that can help you write cleaner and more efficient code.

Feedback

Have feedback? Found something that needs to be updated, accurate, or explained?

Join our discord and share what can be improved.

Any and all feedback is welcomed.