Solidity 0.6.8 introduces SPDX license identifiers

SPDX license identifiers

Solidity 0.6.8 introduces SPDX license identifiers so developers can specify the license the contract uses. (e.g. OpenZeppelin Contracts use MIT license).

SPDX license identifiers should be added to the top of contract files. (see example in OpenZeppelin Contracts ERC20.sol)

The following identifier should be added to the top of your contract (example uses MIT license):

// SPDX-License-Identifier: MIT

The license should be from one of the following: https://spdx.org/licenses/

:warning: If the license identifier isn’t included in the contract file the compiler will now show a warning.

:exclamation: If there are multiple license identifiers in the contract file the compiler will now show an error.


An impact of this is how we verify contracts importing other contracts. Contracts are often flattened and a single file is verified (such as on Etherscan), but one file would then contain multiple license identifiers, either the same license or a mix of licenses. So the community may need to move to verifying multiple files rather than using flattening.

Solidity Compiler

SPDX license identifiers were introducted in Solc release v0.6.8:
https://github.com/ethereum/solidity/releases/tag/v0.6.8

we introduced a recommendation to use SPDX license identifiers for all source files which are also stored in the contract metadata

Solidity documentation on SPDX license identifiers:
https://solidity.readthedocs.io/en/v0.6.8/layout-of-source-files.html?highlight=spdx#spdx-license-identifier

Compiler Warning

When compiling a contract with solc 0.6.8+ without a SPDX licence identifier gives the following warning:

$ npx oz compile
✓ Compiled contracts with solc 0.6.8 (commit.0bbfe453)
Compilation warnings:
contracts/Box.sol: Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: <SPDX-License>" to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see https://spdx.org for more information.

Verification

When verifying contracts with imports on Etherscan, often contracts are flattened into a single file. (see: Verifying a contract inheriting from OpenZeppelin Contracts)

Flattening contracts with SPDX license identifiers results in a file with multiple SPDX license identifiers and attempting to compile generates an error:

$ npx oz compile
✖ Compiling contracts with solc 0.6.8 (commit.0bbfe453)
Compilation errors:
contracts/FlatB.sol: ParserError: Multiple SPDX license identifiers found in source file. Use "AND" or "OR" to combine multiple licenses. Please see https://spdx.org for more information.

Verification - Single License

Where all contracts share the same license, we could manually (or potentially, if the flattener supported, the flattener could do this) strip out the duplicate SPDX license identifiers to allow verification. Otherwise we can use Solidity Multiple files format and upload each of the files. (we would need to copy all of the Solidity files to a single temporary directory to upload)

I think the preferred approach will be to verify using Solidity Multiple files format.

Verification - Multiple Licenses

Where contracts have different licenses (e.g. a contract has a non-MIT license and inherits from OpenZeppelin Contracts which has the MIT license), we can’t use the flatten method. Instead we need to use Solidity Multiple files format and upload each of the files. (we would need to copy all of the Solidity files to a single temporary directory to upload)

For an example: see the following verified contract: https://rinkeby.etherscan.io/address/0x6BA8d4FfD88Ccc1c0eF61820839837B598514699#code

Note, Etherscan currently shows the license that we manually selected during verification and doesn’t appear to have a Multiple/Mixed license.

I think the preferred approach will be to verify using Solidity Multiple files format.

Developers (as has always been the case) need to ensure that they don’t remove or change the license of any contracts that they import or use a license in their contracts that is incompatible with contracts that they import.

OpenZeppelin Contracts

Licence identifiers have been added to OpenZeppelin Contracts and will be included in future releases of OpenZeppelin Contracts (and hence OpenZeppelin Contracts Ethereum Package): https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2234

Discussion

@frangio created the following issues to discuss and track use of the identifiers and verification:

The community may need a tool that makes multiple file verification easier, either from block explorers such as Etherscan or a tool to copy all of the contract files into a single temporary directory for easy upload.

Please add to the discussion here with your experience with using SPDX license identifiers and verification.

4 Likes

Does the license identifier work also on the package level, as often maintaining the license information per file is too granular?

1 Like

Hi @miohtama,

It is per file.

e.g. If your code is MIT licensed then you would need to add the following to every file.

// SPDX-License-Identifier: MIT