In the previous articles, we looked at some of the representative examples of smart contracts representing possible real-world scenarios.
Our main focus was on capturing the essence of each case, without particular attention given to the general structure, i.e. layout of the respective source files.
However, in this mini-series starting with this article, we will focus particularly on the source file layout.
The articles will continue with our tradition of going hand in hand with the official Solidity documentation, with the particular topic of our current interest available here.
Info: As we’ve reached such a nice, round number of articles on Solidity, I have a small foreword for my faithful audience.
For those of us who missed or skipped previous articles, the intent behind the content is to supplement and clarify the original documentation and even present it in a style that I find to be more appropriate to us as the audience.
Given that we come from various backgrounds, some less and some more technical, it is my permanent goal to soften the material and make it as close as possible to each reader. Sometimes, completely unannounced and unprovoked, I’ll even try and sprinkle some humor onto the content.
Will I succeed in making it funny and engaging? That’s whole another story 🙂
Smart contracts are somewhat a mystery to unfamiliar folks, and a mystery usually implies a certain amount of distrust. Even so, the more sensitive the subject is, the greater the amount of distrust. The best way to turn distrust into trust is to make the content in question open and available.
When we’re talking about smart contracts, the openness of a smart contract means the availability of its source code. However, making the source code available frequently triggers legal problems regarding copyright.
To alleviate these problems, the Solidity compiler instigates the use of SPDX license identifiers.
ℹ️ Info: SPDX stands for the Software Package Data Exchange, which is “An open standard for communicating software bill of material information, including components, licenses, copyrights, and security references. SPDX reduces redundant work by providing a common format for companies and communities to share important data, thereby streamlining and improving compliance.“
Yes, I agree, it’s a lengthy sentence, but the main takeaway ideas are a communication standard, an instrument of compliance, and a data exchange format:
- SPDX is a standard used for communicating the information about the software contents;
- SPDX reduces redundant work and improves compliance;
- SPDX provides a common format for data sharing between companies and communities;
An SPDX license identifier should be included at the beginning of the source file, e.g.
// SPDX-License-Identifier: GPL-3.0-or-later
Although SPDX license identifiers are machine-readable, the compiler does not check if the license part of the comment is in the list of licenses allowed by SPDX.
Instead, the compiler will just include the string in the bytecode metadata.
We will touch on the subject of contract metadata in future articles, but until then, let’s just remember that there is a thing called metadata.
ℹ️ Info: Metadata can be loosely defined as “data/information about data”, meaning it provides more information or description of certain data.
We don’t have to specify a license or if the case is that the source code is closed-source (opposite of open-source), the recommendation is that we use a special value UNLICENSED.
The UNLICENSED value implies that usage is not allowed, i.e. there is not a corresponding item in SPDX license list; it differs from the value UNLICENSE which grants all rights to everyone.
Solidity documentation authors note that Solidity adheres to the npm recommendation.
If we as developers supply the UNLICENSE comment, we are still tied by the obligation related to licensing, i.e. we have to mention a specific license header or the original copyright holder in the source files.
Although the compiler recognizes the comment placed at any location in the source file, the recommendation, and good practice is to put it at the top of the file.
We’ve mentioned the
pragma keyword somewhere in the first few articles, but now we’ll use the opportunity to say a few more words about it.
Pragma keyword is the element of the Solidity programming language that enables specific Solidity compiler (remember
solc) features or validations, i.e. checks.
pragma keyword scope is its source file, we’d have to add the pragma to all our files to enable it in our whole project.
💡 Note: A pragma from an imported file does not apply to the importer file, i.e. the file that imports the imported file.
We always use a version pragma for limiting the source file(s) compilation to a specific range of compiler versions.
The intention behind this step is the prevention of incompatible changes introduced with future versions of compilers.
According to the Solidity authors, occurrences of incompatible changes are reduced to an absolute minimum, meaning that in all other cases i.e. cases of compatible changes, the changes in Solidity language semantics visibly coincide with the changes in language syntax.
To stay on the safe side, the recommendation is to study the changelog at least for releases that carry breaking changes, marked
x.0.0 (major releases) or
0.x.0 (minor releases).
ℹ️ Info: semantic is relating to meaning in language or logic.
As in every our example so far, we’re using the version pragma as:
pragma solidity ^0.x.y; allows changes that do not modify the left-most non-zero digit in the [major, minor, patch] tuple (docs).
The following line instructs the compilation process to use a compiler with the lowest version of 0.5.2 and with the highest version not exceeding 0.6.0 (this condition is incorporated by a
pragma solidity ^0.5.2;
By recalling the article about semantic versioning, we’ll remember that no breaking changes are introduced until a minor version of
0.6.0 (in this specific case), therefore we can be sure that our code will compile just as we expect it to.
Also, by using the line above, we didn’t lock on the specific version, so the last part of the version label, i.e. the patch number can increase, leaving enough space for the compiler bug fixes.
Besides this most common way of expressing the allowed versions of the compiler, even more, complex rules are available by using the syntax available here.
version pragma just instructs the compiler to self-check if it is compliant with the version required by the source file. In case of a mismatch, the compiler will throw an (in)appropriate error. I mean, who ever saw an appropriate error, anyways?
With this introductory article to the topic of the layout of a Solidity source file, we covered a few very light concepts, including SPDX license identifier, reintroduced the pragma keyword, and retouched the version pragma.
In the next article, we will continue with the next two pragmas and other, very interesting topics.
In the SPDX License Identifier section, we were asking around inconspicuously about the SPDX. We wanted to find out what it is, how and when it is used, and how it can make our developing life easier.
In the Pragmas section, we proudly reminded ourselves of the knowledge from long ago, why do we have to slam a pragma at the beginning of each source file?
If at least they looked nice… Starting our coding masterpieces with a dangling comment seemed like a skewed joke (like most of mine do) – until we learned why 🙂
This tutorial is part of our extended Solidity documentation with videos and more accessible examples and explanations. You can navigate the series here (all links open in a new tab):
I’m an experienced computer science engineer and technology enthusiast dedicated to understanding how the world works and using my knowledge and ability to advance it. I’m focused on becoming an expert in Solidity and crypto technology, with a passion for coding, learning, and contributing to the Finxter mission of increasing the collective intelligence of humanity.