What is pragma and why it matters

One of the first things that you will see when you look at a Solidity smart contract is the annotated pragma version. It looks a bit like this:

pragma solidity ^0.5.2;

The term pragma comes from the greek πρᾶγμα (prâgma) which means "deed" or "act". It is used as a directive or a special instruction to the compiler. In other words, the pragma keyword says "Hey, compiler! Listen up!.

The pragma directive exists in other programming languages like C/C++ and Python. However in the case of Solidity, pragma declares rules about the which compiler version can be used to translate the Solidity code to Byte code. To give some additional context, we should review exactly what the compiler is doing.

Smart contract developers use a human readable language like Solidity (at least us nerdy humans can read it) to write code. However, Ethereum's blockchain only understands bytecode - a series of machine instructions. The compiler, converts human readable Solidity code into the raw, bytecode form that Ethereum needs in order to execute on the network.

If we don't set the compiler version with pragma, the compiler doesn't know what rules to follow when translating the contract to machine code.

In the above example, we state “Use Solidity version 0.5.2 or anything newer up to (but not including) 0.6.0.”. This is because 0.6.0 is a major version which might cause a breaking change.

Updates are made to the Solidity compiler(solc) for the same reason that Apple continues pushing updates to their cars - it is about fixing bugs, optimizing performance, improving security, and adding new features. For example, in Solidity 0.8.x, improvements were made to how arithmitec operations work, removing the need for additional libraries like SafeMath which protect agains overflows (numbers getting too big) and underflows (numbers getting too small).

Before Solidity 0.8 was introduced doing some math like this:

uint8 x = 255;  
x += 1;  

would result in x being 0 instead of 256 as one might expect. This might cause all sorts of issues in a production environment. Whenever using a solc version of 0.8.0 or above, overflow and underflow protection is added by default. If an operation goes out of range, it automatically reverts the transaction instead of silently wrapping around.

Hopefully this example makes it a bit clear why updates are made to the compiler. Once the compiler translates Solidity into bytecode and deployed on to Ethereum, all transactions are executed with the Ethereum Virtual Machine. The only thing that the EVM cares about is the byte code, so whatever compiler was used is irrelevant.

So, while the pragma specification at the beginning of every Solidity file might feel a bit like an annoying extra step, it has very important implications and it is your responsibility as a smart contract engineer to stay up to date on the current release logs to check for any breaking changes.