Rust Static Analysis and Blockchain Licensing
What is static analysis?
Static analysis is an analysis of software artifacts. For example requirements or code, carried out without execution of these software development artifacts. Static analysis is usually carried out using supporting tools. In other words, we can say that static analysis is an examination of requirements, design, and code that differ from more traditional dynamic testing in several important ways. The main goal behind this analysis is to find the bugs, whether or not they may cause failures. As with reviews, static analysis finds bugs rather than failures.
The general name for static analysis is linting. lint, or a linter, is a tool that analyzes source code to flag programming errors, bugs, stylistic errors, and suspicious constructs. Simply put, a linter is a tool that programmatically scans your code with the goal of finding issues that can lead to bugs or inconsistencies with code health and style. Some can even help fix them for you!
How to analyse Rust code?
Clippy
Rust blockchain developers usually write in two main languages Javascript (or Typescript) and Rust (dah!). And there are standard tools like eslint to analyse your javascript code, Rust is somewhat left behind. This is of course due to the fact that Rust compiler is already quite strict, but Clippy goes a step further and helps prevent some things which are valid but bad practice. This can help prevent unexpected problems later in your code.
clippy requires nightly in order to run. Earlier we installed nightly alongside stable with rustup toolchain install nightly, so we can use it without any issues.
rustup run nightly cargo install clippy
Now let's create a test case. Run cargo init --bin test && cd test then modify the src/main.rs file to have to have the following:
fn main() { // Clippy warns on statements with no effect, like this one. true; }
Now we can run clippy with the following command:
rustup run nightly cargo clippy
This should yield a warning from clippy:
warning: statement with no effect --> src/main.rs:2:5 | 2 | true; | ^^^^^ | = note: #[warn(no_effect)] on by default = help: for further information visit https://github.com/Manishearth/rust-clippy/wiki#no_effect
Excellent. You can see the different lints which clippy detects here. You can configure various lints in the clippy.toml according to their options listed in the wiki.
rustfmt
Having consistent, standard automated styling in a project (and across many projects) can be useful for code review, attracting new contributors, and avoiding unproductive discussions. rustfmt is a code formatting tool akin to gofmt. Unlike clippy, it runs happily on stable. To install it:
cargo install rustfmt
Now let's edit the main.rs we made later to have some obviously poor style:
fn main () { true ; }
Then we can run cargo fmt --all and we can see that our file is correctly formatted again.
Licensing and copyrighting Rust code
What Is a Software License?
Every business uses software to manage business processes, communicate with employees, customers, and vendors, and for myriad other purposes. In most instances, software products require activating licenses or agreeing to “terms and conditions” before programs can be downloaded, installed, or accessed.
There are many types of software licenses, with different terms, support agreements, restrictions, and costs. Users need to understand the basics of software licenses, to ensure a full understanding of responsibilities and compliance with legal terms and limitations.
A software license is a contract between the entity that created and supplied an application, underlying source code, or related product and its end user. The license is a text document designed to protect the intellectual property of the software developer and to limit any claims against them that may arise from its use.
A software license also provides legally binding definitions for the distribution and use of the software. End-user rights, such as installation, warranties, and liabilities, are also often spelled out in the software license, including protection of the developer’s intellectual property.
Most software falls under one of two categories that have distinct differences in how they are viewed under copyright law:
- Proprietary – also referred to as “closed source”
- Free and open-source software (FOSS) – referred to as “open source”
FOSS software licenses – give rights to the customer that include modification and reuse of the software code, providing the actual source code with the software product(s). This open-source type of licensing affords the user authority to modify the software functions and freedom to inspect the software code.
Proprietary software licenses – provide no such authority for code modification or reuse and normally provide software with operational code only, and no source code. A proprietary software license often includes terms that prohibit “reverse engineering” of the object code with the intention of obtaining source code by the licensee.
In both cases, the software license will most often specify limitations of liability from use of the software product, any mutual responsibilities such as support, and any warranties or disclaimer of warranty.
Where software is not covered by any license, it is normally categorized as:
- Public domain software – freely available for use and not copyright protected
- Private unlicensed software – such as business applications that still falls under copyright protection
Open source and proprietary software licensing may also specify additional restrictions and terms:
- Transfer of ownership to the buyer or retention of ownership by the seller
- Any authorization for copying, selling, or distributing the software
- Definition of whether the license constitutes purchase or leasing of the software
How Does Software Licensing Work?
New users of a software will normally enter into an end-user license agreement (EULA) that constitutes a legal definition of the relationship between the licensor (provider) and licensee (user or business). The EULA is a contract that establishes the rights of the purchaser for installing and using the software.
Every EULA contains a clause that stipulates when its conditions are activated by an end user. This may be the moment the user opens the product packaging or, for example, when the user clicks on a button agreeing to accept the EULA’s terms to access it.
Cloud-based applications such as Software as a Service (SaaS) will often include license details in EULAs including:
- Monthly or annual charges per user
- Duration of the agreement
- Terms of cancellation of the agreement
- Recovery of any charges if canceled during the agreement
An additional use of software licensing is in cases where a software developer or firm grants authority for selling or distributing the software under the second party’s brand. The developer retains ownership, but the re-branding company is permitted to resell the software product. This method of licensing is called “white labeling.”
What about blockchain software?
In general, code deployed to the blockchain, even though it's seen publically, doesn't have any unique specifics - think about code written in javascript and run on the browser, which is also seen to public and yet have been covered by different licenses ages.
The problem is of course tooling. And while javascript community enjoyed an influx of libraries for any sort of purpose - blockchain tooling is known to be lagging. But before we dive into how to make your Rust code licensed, let's cover another term - copyright.
What is copyright?
Copyright is a legal construct that grants someone exclusive rights over creative work. In most places, you do not need to do anything to gain copyright. As soon as you make creative work, you (or your employer) instantly gain copyright over it.Copyrights and licenses are similar in that they both convey, or give specific rights to the people that hold them. Copyrights can only to be held by the people who create something, or to quote Wikipedia: Copyright is the set of exclusive rights granted to the author or creator of an original work, including the right to copy, distribute and adapt the work.
A license on the other hand, encapsulates the rights and privileges that a copyright holder grants to someone else vis a vis something they have created. In the world of software the license defines the terms and conditions of someone else's usage of that software, and their rights with regards to their ability to copy and redistribute that software.
This is why you need specifically to state via copyright who holds the rights to the code and how this code can be used via license.
REUSE
Copyright and licensing is difficult, especially when reusing software from different projects that are released under various different licenses. REUSE was started by the Free Software Foundation Europe (FSFE) to provide a set of recommendations to make licensing your Free Software projects easier. Not only do these recommendations make it easier for you to declare the licenses under which your works are released, but they also make it easier for a computer to understand how your project is licensed.
REUSE uses SPDX, which stands for Software Package Data Exchange. SPDX defines a standardized way to share copyright and licensing information between projects and people. It also maintains the SPDX License List, which defines standardized identifiers for a lot of licenses.
REUSE maintains that every single file should contain licensing information so that even the tiniest of files get a header, or are accompanied by a corresponding .license file for the binary files. If you don’t wish a file to be licensed (auto-generated files), than they should be in the codebase and added to the gitignore - REUSE doesn’t add licenses to the files mentioned in the gitignore.
Installation and Usage
The most common way to install REUSE is through pip, but you can use other packages managers if you wish as per here.
pip3 install --user reuse
To initiate the project, run reuse init and fill the requested information, which will result in .reuse/dep5 file with the following content:
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: SOMETEAM Upstream-Contact: Some Team someone@somewhere.com Source: https://www.somecorp.com/
reuse lint
This will run through all the files and check if licenses are in place, outputting something like this:
# MISSING COPYRIGHT AND LICENSING INFORMATION The following files have no copyright and licensing information: * some-script.js # SUMMARY * Bad licenses: * Deprecated licenses: * Licenses without file extension: * Missing licenses: * Unused licenses: * Used licenses: LicenseRef-SomeCorp * Read errors: 0 * Files with copyright information: 12 / 13 * Files with license information: 12 / 13 Unfortunately, your project is not compliant with version 3.0 of the REUSE Specification :-(
It will provide information on which files are not licensed and which are not copyrighted. To add license/copyright information, just run the add-licenses.sh script, which will go through all the files and add the required information, similar to the below with the language-specific comment style.
// SPDX-FileCopyrightText: 2021 SomeCorp Ltd // // SPDX-License-Identifier: LicenseRef-SomeCorp
LicenseRef-SomeCorp is the name of the license file located under the LICENSES folder. REUSE provides dozen of licenses, which can be dowloaded using the download command or you can use your own - something like this (not a legal advice). The first line can be changed through the script below. The year is updated automatically.
So to actually add the license and copyright to the files you need to run the addHeader method of the reuse tool, but as it only handles with one file at time - you need to write some bash script to feed the tool with your files, as follows:
find . -name "*.rs" ! -path "*/.git/*" -exec reuse addheader {} --license "LicenseRef-SomeCorp" --copyright "SomeCorp Ltd" \;
You can use ! -path to exclude any unwanted folders, like node_modules and others. You will have to maintain the script and add some unsupported file types, like Solidity sol, through the style argument as follows:
find . -name "*.sol" ! -path "*/.git/*" -exec reuse addheader {} --license "LicenseRef-SomeCorp" --copyright "SomeCorp Ltd" --style="c" \;
After running the script, rerun the linter to validate the compliance.
# SUMMARY * Bad licenses: * Deprecated licenses: * Licenses without file extension: * Missing licenses: * Unused licenses: * Used licenses: LicenseRef-SomeCorp * Read errors: 0 * Files with copyright information: 13 / 13 * Files with license information: 13 / 13 Congratulations! Your project is compliant with version 3.0 of the REUSE Specification :-)
Conclusion
Despite the fact that blockchain community severely lacks the tools for proper development, there are still ways to ensure the code you produce is maintainable, secured and comliant with your business needs.
Comments
Post a Comment