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: How to flatten and verify a smart contract using 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.

License text not enforced

I assumed (incorrectly) that the compiler would enforce the license text but any random text will compile as long as it has the prefix SPDX-License-Identifier (Thanks to @PreciousChicken for the find).

// SPDX-License-Identifier: RANDOM_TEXT

pragma solidity ^0.6.0;

contract MyContract {

}
$ npx oz compile
✓ Compiled contracts with solc 0.6.11 (commit.5ef660b1)

Multiple identifiers

The following generates an error

// SPDX-License-Identifier: MIT

pragma solidity ^0.6.8;

contract MyContract {
}

// SPDX-License-Identifier: Something Else

Whilst the following doesn't generate an error

// SPDX-License-Identifier: MIT


// SPDX-License-Identifier: Something Else

pragma solidity ^0.6.8;

contract MyContract {
}

Reported: https://github.com/ethereum/solidity/issues/10145

8 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

2 Likes

Hi @sambacha,

Welcome to the community :wave:.

Thanks for sharing the tool, that sounds quite handy.

One thing to watch out for is to ensure that a license identifier from a third party isn’t replaced with a different license.

You can do,

grep --line-buffered -L SPDX-License-Identifier *.sol | tee spdx-audit.txt

which will save results in a file named spdx-audit.txt for inventory purposes

1 Like

The multiple SPDX seems to break “oz verify”
what can be done about it?

1 Like

Hi @sirpy,

I recommend using Buidler Etherscan plugin as this does multifile verification so that SPDX License identifies are not removed:

The URL Link is not Working

For questions related to verifying on Etherscan refer to our guide: