3 min read

Mastering Solidity Pragma: 6 Ways to Specify Compiler Versions

There are many ways to define pragma version in solidity and you will know them all!
Mastering Solidity Pragma: 6 Ways to Specify Compiler Versions

Intro

When you’re just starting out with Solidity smart contract development, the pragma line at the top of every .sol file might seem like just another piece of boilerplate. But don’t ignore the pragma — it’s an essential part of your Solidity code that tells the compiler which version to use.

Moreover solidity follows same syntax to define versions as used by `npm` package manager, which means that we have multiple ways to define version ranges.

SemVer

But before we begin, let’s briefly discuss Semantic Versioning (SemVer) to ensure we’re on the same page. The Solidity compiler adheres to the SemVer convention, meaning each version number carries specific compatibility details.

Here is how it looks like

{MAJOR}.{MINOR}.{PATCH}

MAJOR version when you make incompatible API changes
MINOR version when you add functionality in a backward compatible manner
PATCH version when you make backward compatible bug fixes

The current version of Solidity is 0.8.26, indicating that the major version is still 0. This typically means the project is considered to be in its initial development phase, despite being around for 10 years. As such, backward compatibility is not guaranteed for minor versions. Therefore, it’s crucial to specify the compiler version precisely in your contracts.

Now that we’ve got the basics of semantic versioning covered, let’s dive into the fun part — exploring the different ways to define your compiler of choice!

6 ways to specify version

1. Exact Version

The simplest way to set a pragma is by specifying the exact Solidity compiler version you want to use. Let’s say you just want to use version 0.8.25, then your pragma will look like this:

pragma solidity 0.8.25;

But in fact patch version can change really fast and it usually backward compatible, so if you want you fine with any patch version you can just leave it out and only define major and minor versions like this.

pragma solidity 0.8;

2. Less Than / Greater Than Ranges

You can also define a range of acceptable versions using the less than (<) or greater than (>) operators.

pragma solidity >=0.7.0;

Or if you want to only include specific range of patch versions you can define it in this way.

pragma solidity >=0.7.1 <0.7.5;

3. Hyphen Ranges

There is another way to define ranges more concisely via hyphens like this:

pragma solidity 0.8.0–0.8.20;

This accepts versions from 0.8.0 to 0.8.20 inclusive.

4. X-Ranges

In some cases X-ranges can be more readable. The idea is that any of `X`, `x`, or `*` symbols may be used as a wildcard to substitute major, minor or patch versions. Here is the example:

pragma solidity 0.8.x; // >=0.8.0 <0.9.0 
pragma solidity 0.*; // >=0.0.0 <1.0.0

5. Tilde Ranges

Tilde ranges is another way to define compiler version. They let you apply patch-level updates if you specify a minor version in the comparator.

In this example we accept all versions from 0.7.3 included up to 0.8.0 excluded. So basically it locks major and minor versions.

pragma solidity ~0.7.3; // >=0.7.3 <0.8.0

6. Caret Ranges

And the final way which is the most popular by far is caret ranges. They allow for updates that don’t change the first non-zero digit in the version number. This means they can accept more updates, providing greater flexibility.

pragma solidity ^0.2.3; // >=0.2.3 <0.3.0

Conclusion

Understanding the various ways to define version ranges in Solidity is crucial for smart contract development. It not only ensures compatibility with the intended compiler version but also provides flexibility to accommodate future updates and patch fixes. Whether you choose to specify exact versions or use ranges like hyphens, X-ranges, tilde, or caret notation, each method has its place depending on your project’s requirements and stability needs.

By mastering these versioning techniques, you can avoid common pitfalls and ensure that your contracts remain functional and secure as the Solidity language evolves. Remember, the pragma statement is more than just a line of code — it’s a key part of maintaining the integrity and reliability of your smart contracts. Happy coding!