Exploring the new Solidity 0.8 Release
And how to upgrade your contracts to Solidity 0.8
We are getting closer to that Solidity 1.0 release (unless of course after 0.9 comes 0.10). Now Solidity 0.8 has been released only 5 months after the 0.7 release!
Let's explore how you can migrate your contracts today...

New features & how to use them
Let's look at the two big new features which are the integrated SafeMath and the new error handling.
1. Integrated SafeMath

That's right, you don't need to import the Openzeppelin SafeMath anymore. Best of all, you don't need to do anything to activate the Solidity integrated SafeMath. Just write a + b
and it will automatically revert on overflows.
You might see errors in tools like Remix as 0.8 is not fully supported yet. For example overflows don't give you the exact reason yet:
transact to Solidity08.test errored: VM error: revert. revert
But this should change in the future.
What if you actually want the code to be able to overflow? Or you are just way too concerned about gas costs?
You can deactivate it by wrapping it with an unchecked
form like this:
contract Solidity08 {
function test() external pure returns(uint256) {
// with SafeMath
// will revert
uint256 x = 0;
x--;
return x;
}
}
contract Solidity08 {
function test() external pure returns(uint256) {
// not using SafeMath
// will return type(uint256).max
uint256 x = 0;
unchecked { x--; }
return x;
}
}
2. Invalid Opcode replaced by Reverting
Up until now certain operations caused the execution of the INVALID
opcode. The issue with this opcode is that it's consuming all remaining gas. This is obviously bad and just not necessary. Why would you waste the gas and donate it to the miners?
For more details, check out the difference between revert
and assert
here.
Now Solidity is using the revert
opcode. To distinguish between regular reverts and these system reverts, Solidity prefixes the return data with an identifier:
- Regular Revert Errors start with the first four bytes of
keccak256(Error(string))
which equals0x08c379a0
- System Internal Errors start with the first four bytes of
keccak256(Panic(uint256))
which equals0x4e487b71
Panics come with an additional error identifier. Currently available panics are
- 0x01: Using
assert
. - 0x11: SafeMath over-/under-flows.
- 0x12: Divide by 0.
- 0x21: Conversion into non-existent enum type.
- 0x22: Incorrectly encoded storage byte array.
- 0x31:
pop()
on an empty array. - 0x32: Index out of bounds exception.
- 0x41: Allocating too much memory or creating a too large array.
- 0x51: Calling a zero-initialized variable of internal function type.
For further details see the new Error handling section in the documentation here.

Should you migrate already?
Before we see how to migrate, let's first discuss should you migrate?
Depending on the time you read this, the answer may differ. Right now it was only just released and proper support from tools doesn't really exist yet. On top it's not heavily tested and used yet. Expect potential bugs!
What does this mean for you?
Let's go through our checklist.
- Has Solidity 0.8 been out for several months now, all tools support it and even Openzeppelin Contracts are migrated to 0.8?
- Yes!
- Then why are you even asking?
- No!
- Are you planning to release to mainnet in the short-term?
- Yes!
- Don't migrate yet.
- No!
- Are all the tools you want to use already imported and working for 0.8?
- No!
- Better wait for that support.
- Yes!
- Can you live without the Openzeppelin Contracts?
- Yes!
- Go and use 0.8 already you early-adopter.
- No!
- Consider migrating what you need yourself, or wait.
How to migrate to Solidity 0.8
Alright you said yes to the migration after going through the checklist? Let's see how this can be done...
The migration should in most case be pretty straight-forward. Only some cases where you do strange type conversions could become more difficult.
The changes you have to make for the migration include:
ABIEncoderV2
is now the default and automatically activated. The encoder wasn't experimental anymore since 0.6 but the 'pragma experimental' name was just kept for legacy reasons. Now you won't need to add the line anymore.- Remove any Openzeppelin SafeMath, you won't need it anymore.
- Some type conversions might be required.
msg.sender
andtx.origin
are not of type payable by default: Changemsg.sender.transfer
topayable(msg.sender).transfer
- Conversion from literals is only allowed if it fits within the given type, so
uint256(-1)
won't work anymore. Usetype(uint256).max
instead. - Casting types is restricted in some cases when changing the sign multiple times, because the order of casting might play a role for the result. You would now see an error like TypeError: Explicit type conversion not allowed from "int256" to "bytes32". Then manually cast it to a uint256 first.
- Combine
myContract.functionCall{gas: 10000}{value: 1 ether }()
intomyContract.functionCall{gas: 10000, value: 1 ether }()
- Change
x**y**z
to(x**y)**z
as the default order of execution changed. - Change type
byte
to bytes1
I've left a few details out, for the full changelog and break down of all changes in detail, check out the documentation here.
Solidity Developer