2.26 Solidity Version Changes
Every new Solidity
version introduces bug fixes and sometimes breaking changes. Remember that breaking versions are versions that are not backwards compatible, or in other words they've introduced significant changes to the syntax, to the underlying semantics, that are not compatible with the previous changes.
These breaking versions increment the number that you see in the middle of the version, so for a Solidity
version x.y.z
, the next breaking version would be x.(y + 1).z
.
In this section we are going to revise recent Solidity
versions and their most impactful changes.
solc 0.6.0
solc 0.6.0
Breaking Changes
In Solidity 0.6.0
a breaking semantic feature that was introduced changed the behavior of the existing code without changing the syntax itself. It was specifically related to the exponentiation. The type of the result until this version was the smallest type that could hold both the type of the base and the type of the exponent. With this change the resulting type was always the type of the base.
Explicitness
Solidity 0.6.0
also introduced a set of explicitness requirements. Explicitness, as you can imagine, is good for security because it reduces ambiguity and any vulnerabilities that result because of that ambiguity.
In this case, keywords
virtual
andoverride
were introduced for functions in base and derived classes. Functions and base classes can now only be overridden when they are marked with thevirtual
keyword, and their corresponding overriding functions need to use theoverride
keyword.Array length is read-only: it's no longer possible with version
0.6.0
to resize storage arrays by assigning a new value to their length.An
abstract
keyword was introduced for what became abstract contracts or contracts where at least one function is not defined.Libraries have to implement all their functions, not only the internal ones, as of this version and there are various restrictions (explicitness restrictions) brought forward for the assembly variables.
State variable shadowing being removed as this led to confusing results in ambiguity and has impacted the security of smart contracts.
Changes
There were many other syntactic and semantic changes brought forward by Solidity 0.6.0
.
external
function type conversions toaddress
types are not allowed. Instead they have an address member that allows similar functionality.Dynamic storage arrays have now their
push(x)
return nothing, while until then it returned the length of the array.Until
0.6.0
there was a concept ofunnamed
functions. This version split the functionality implemented by such a functions into afallback
function and a separatereceive
function. As you know, there are differences between these two functions and specific use cases where one of them is applicable versus the other.
New Features
0.6.0
also introduced several new features:
try
/catch
blocks for exception handling.struct
andenum
types can be declared at a file level with this version. Until then, it was only possible at contract level.Array slices can be used for all data arrays.
NatSpec
, as of this version supports multiple return parameters for developer documentation; it enforces the same naming checks as the param tag.The inline assembly language
YUL
introduced a new statement calledleave
to help exit the current function.Conversions from
address
type toaddress payable
type are now possible via thepayable(x)
primitive, wherex
is of typeaddress
.
solc 0.7.0
solc 0.7.0
Breaking Changes
The next breaking release was Solidity 0.7.0
. With this version, exponentiation and shift of literals by non-literals will always use uint256
or int256
to perform the operation. Until this version the operation was performed using the type of the shift amount or the type of the exponent, which can be misleading, so this became very explicit.
This again is a breaking semantic change because the behavior of exponentiation and shifts changed underneath without any changes to the syntactic aspect.
Changes
This version also introduced several syntactic changes that could cause existing contracts to not compile anymore and therefore considered a breaking change. Examples of such changes are:
The syntax for specifying the Gas and Ether values applied during external calls.
The
now
keyword for time management within contracts was deprecated in favor ofblock.timestamp
becausenow
gave the perception that time could change within the context of a transaction whereas it is a property of the block, correctly indicated byblock.timestamp
.The
NatSpec
aspect for variables was also changed to allow that for onlypublic
state variables and not forlocal
orinternal
variables.gwei
was declared as a keyword and therefore can't be used for identifiers.string literals can contain only printable
ASCII
characters. As of this versionunicode
string literals were also supported with the use of theunicode
prefix.The state mutability of functions during inheritance was also allowed to be restricted with this version, so functions with the default state mutability can be overridden by
pure
andview
functions while theview
functions can be overridden bypure
functions.
There are also multiple changes introduced to the assembly support within Solidity
.
Removed
This version also removed some features that were considered as unused or unsafe and therefore beneficial for security.
Struct or arrays that contained mappings were allowed to be used only in storage and not in memory, the reason for this was that mapping members within such structural arrays in memory were silently skipped. This as you can imagine would be error prone.
The visibility of constructors, either
public
orexternal
is not needed anymore.The
virtual
keyword is disallowed for library functions, because libraries can never be inherited from and therefore the library functions should not need to bevirtual
.Multiple events with the same name and parameter types in an inheritance hierarchy are disallowed, again to reduce confusion.
The directive
using A for B
with respect to library functions and types affects only the contract it is specified in as of this version. Previously this was inherited, now it has to be repeated in all the derived contracts that require this feature.Shifts by sign types are disallowed as of this version. Until now shift by negative amounts were allowed, but they caused a
revert
runtime.The Ether denominations of
fini
andszabo
were considered as rarely used and therefore were removed as of this version.The keyword
var
was also removed because this would until now pass, but result in a type error as of this version.
solc 0.8.0
solc 0.8.0
Breaking Changes
Solidity 0.8.0
is the latest of the breaking versions of Solidity
. This version introduced several breaking changes:
The biggest perhaps is the introduction of default checked arithmetic. This is the overflow and underflow arithmetic checks that are so commonly used in
Solidity
contracts to prevent the wrapping behavior that results in overflows and has resulted in several security vulnerabilities.\Until this version, the best practice was to rely on the
OpenZeppelin
SafeMath
libraries or their equivalents to make sure that there are runtime checks for overflows and underflows. These never result in vulnerabilities. This is so commonly used thatSolidity 0.8.0
introduced the concept of checked arithmetic by default, so all the arithmetic that happens with increment, decrements, multiplication and division is all checked by default.\This might come at a slight increase of Gas Cost, but it also increases the default security level significantly and it also improves the readability of code because now one doesn't have to use or see the use of calls to the
SafeMath
libraries in the form of.add()
,.sub()
and, so on...\And as an escape hatch where the developer knows for sure that certain arithmetic is safe from such underflows and overflows,
Solidity
provides theunchecked
primitive that is allowed to be used on blocks of arithmetic expressions where this default underflow and overflow checks are not done by theSolidity
compiler.\ABI coder version
v2
is activated by default. As of this version, it doesn't have to be explicitly specified but if the developer wants to fall back on the olderv1
version that has to be specified.Exponentiation is right associative as opposed to being left associative that was the case. This is the common way to parse exponentiation operator in other languages, so this was fixed.
As of this version the use of the
REVERT
opcode versus the use of theINVALID
opcode for failing asserts and internal checks was removed. Now both use theREVERT
opcode and static analysis tools are allowed to distinguish these two differing situations by noticing the use of the panic error in the case of failing asserts and internal checks.\When storage byte arrays are accessed where the length is encoded incorrectly a panic is raised that's another change introduced.
The
byte
type which used to be an alias ofbytes1
has been removed as of this version.
Restrictions
Solidity 0.8.0
also introduced several restrictions:
Explicit conversions of multiple types are disallowed. Remember that explicit conversions are where the user forces conversions between certain types without the compiler necessarily thinking those are safe from a type safety perspective, so these explicit conversions being disallowed may be considered as a good thing from a security perspective.
Address literals now have the type
address
instead ofaddress
payable
, these have to be explicitly converted toaddress payable
.If required, the function call options for specifying the Gas and Ether value passed can only be provided once and not multiple times.
The global functions
log0
,log1
all the way tolog4
that may be used for specifying events or logs have been removed because they were low level functions that were considered as largely unused bySolidity
contracts and, if a developer wants to use them, they need to resort to inline assembly.enum
definitions now can't contain more than 256 members. This makes it safer because the underlying type is alwaysuint8
, so 8 bits that allows only 256 members to be represented by that type.Declarations with name
this
,super
and_
are disallowed.Transaction origin (
tx.origin
) and message sender (msg.sender
) global variables now have the typeaddress
instead ofaddress payable
, and again require an explicit conversion whereaddress
payable
is needed.The mutability of
chainId
is now consideredview
instead ofpure
.
All these different types of restrictions were introduced in this version that have an impact on security.
Last updated