pragma is a keyword in solidity, that is used to specify the version a smart contract is written for. It can also be used to enable certain features or checks of the compiler.
Scope of Pragma
The scope of the pragma is always local. If another file is imported, the pragma of the imported file doesn't apply to the importing file. Therefore, the pragma has to be added to every single file of the project, if necessary.
Source code should include a version pragma, to make sure that the code is not compiled with a future compiler version that might introduce incompatibilities. In Solidity releases with breaking changes, have the versions of 0.x.0 or x.0.0.
The most common way to notate version pragma is in the following form:
pragma solidity ^0.8.5
The source file can be compiled with compiler version 0.8.5 and above, but not 0.9 and above. The condition that it does not work with the next version with breaking changes is added by the caret (^) symbol.
If the pragma version is specified without the caret (^) symbol, it allows only the exact compiler version. For example, the following code allows only compilation with the exact version 0.8.5.
pragma solidity 0.8.5
It's also possible to specify more complex rules, they are very similar to the syntax used by npm. The following code specifies the compiler versions allowed as 0.4.0 and newer but not including 0.6.0.
pragma solidity >=0.4.0 <0.6.0
ABI Coder Pragma
The version of the ABI encoder and decoder can be specified by using the pragma abicoder directive. ABI coder 2 allows encoding and decoding of arbitrarily nested arrays and structs. Since Solidity version 0.6.0 it is not considered experimental, however, it has to be explicitly activated.
For version 1:
pragma abicoder v1
For version 2:
pragma abicoder v2
The experimental pragma allows enabling features of the compiler or Solidity language that are not enabled by default because they are considered experimental. For example in earlier compiler version the ABI coder v2 was enabled by an experimental pragma:
pragma experimental ABIEncoderV2;
Another example is the SMTChecker, which can be enabled by using:
pragma experimental SMTChecker;