Solidity 0.5.0 - what's new for us
Update: 11/13/2018 release released , here is a detailed description of the changes. The article talks about the state of this version in May (five months before the release).
I want to talk about the changes in the Solidity language that are expected in version 0.5.0. I note right away that I will limit myself only to the language - its grammar and semantics.
There is no sane text on this subject even in English, but recently a project has appeared in the Solidity repository .
On it you can track the progress of the preparation of version 0.5.0.
Disclaimer: the article describes the current state of the project, a lot can change for release. Accurate information can be obtained from the official changelog .
The final ban on obsolete designs
Solidity has accumulated quite a lot of obsolete constructs that I would like to remove from the language, but it still fails due to backward compatibility. This category of changes includes:
- The refusal of
throw
the benefitrevert()
/assert(...)
/require(...)
. The transaction rollback mechanism is different from the exception mechanism, and I want to emphasize this difference at the language level. - A rejection
var
, which, taking into account the rules of type inference, can easily lead to errors, for example: Infor(var i = 0; i < 100500; i++) { ... // бесконечный цикл
addition, they discuss what to replace structures withvar (z, y, z) = foo();
and how to more elegantly skip unnecessary values . - Forbidden to use
constant
for functions - everywhere should be view or pure. - Built in
функция gasleft()
insteadmsg.gas
. It is more clear that this is not some kind of constant, but the remaining amount of gas. Yes,gasleft()
you can override. - Moved
block.blockhash
toblockhash
. It is logical, because theblockhash
current block is not available (block.blockhash(block.number) == 0
). - Forbidden to mix hexadecimal constants and time / ether factors. In fact, it is not entirely clear what it is
0xaf days
. - Declined from
suicide
/sha3
to inline assembly. - Rejection of the unary plus, because it does not have any special role and can participate in stupid mistakes (like
x=+1;
insteadx+=1;
). - It is planned to abandon the multiplier
years
, because now it is defined as365 days
, and this does not correlate very well with the usual calendar. This seems to me a controversial decision - it would seem, so far, you can limit yourself to a warning.
Stronger syntax
In Solidity, very different constructions have a similar syntax. This makes it difficult to read the code, but even more it spoils the life of developers of tools for working with source codes (this applies to the compiler as well). It is nice to see that work is being done in this direction too.
- Required keyword
emit
when generating events .
Creating an event was not syntactically different from calling a function (and creating a structure). This problem was especially pronounced in the ERC20 standard, in which there is a function and an event with the same “signature”. - The new syntax for constructors : .
With the release of 0.5.0, this will be the only option - functions whose names coincide with the contract are prohibited.
This change solves the problem of renaming files when the constructor suddenly turns into a regular function and can be called repeatedly or not called at all.
This decision looks more reasonable if we recall that the constructor can only or cannot, or cannot, have return values, i.e. is a special entity.
It is curious that at the same time an issue was opened with a proposal to allow functions of the same name to the contract in 0.6.0.
constructor(
) public { ... public
internal
view
pure
- Changing the visibility rules of local variables - from those adopted in Javascript to C99 / C ++.
My favorite I can’t do anything with myself, every time I am happy when I show how the code is compiledx = 1; revert(); uint x; }```
- Force strict mode for assembler. It is now available with the compiler option
--strict-assembly
. It has limited manipulation of the stack and labels and transitions are not available - instead, it is proposed to use more familiar control structures likefor
orswitch
. - Forbidden to use addresses without a check sum or an incorrect length (other than 20 bytes). It’s a good idea, although it’s difficult to get used to it - you’ll have to urgently learn how to write addresses with a check sum, and
0x0
use it instead of the usual oneaddress(0)
. - Forbidden to declare empty structures (
struct A {}
). I didn’t really want to, but earlier grammar allowed this.
Visibility Modifiers and ABI
There was an easy mess with visibility modifiers, largely due to the presence of default values. A lot of small edits have accumulated that should make the language more strict, removing this confusion.
And since these modifiers fall into the ABI contract, the changes affected him.
- All functions in the interfaces must be explicitly marked as external .
Unfortunately, it is impossible to redefine such a function as public in some versions of the compiler - an error will occur (for example, in 0.4.21). This has been made possible since version 0.4.22.
They also promise to allow the implementation ofexternal view
functions usingpublic
variables. - Visibility modifiers have become mandatory for functions .
This change has long been waiting in the wings. Issue on the github was created immediately after the first hack by Parity.
An additional limitation is that fallback can only be external .
Functions with an arbitrary number of arguments and data packaging
In Solidity, there are several functions that take any number of arguments, glue them to one binary sausage and then work with it. There are many subtleties and non-obvious moments in this process, and now we decided to deal with them.
- New global object
abi
and its methodsencode
,encodePacked
,encodeWithSelector
andencodeWithSignature
to monitor data assembly to call or hashing.
It is proposed to use them to collect arguments forkeccak256
/sha256
/ripemd160
andcall
/delegatecall
. It is planned to change the syntax of these commands so that they cannot accept a list of arguments of arbitrary length. - A change in the automatic type inference for constants in constructions with a tight packing of arguments: in constructions, it seems,
keccak256(1)
now not the smallest sufficient type (uint8
) is used, butuint256
. If this behavior does not suit you, you will have to use explicit type conversion (keccak256(uint8(1))
).
This change looks logical next to the rejectionvar
and high (albeit finite ) accuracy of the calculation of constant expressions. - Changing the rules for packing arrays. It all started with the problem of multisig wallets that could not perform transaction transactions of contracts that tried to defend themselves against a short address attack. Apparently, the current behavior was considered quite unobvious, or maybe it's preparation for the introduction of length checks
msg.data
at the EVM level.
Improving the "work with memory"
In quotation marks, because this is mainly about "unexpected" access to storage without using assembly.
- Prohibition of uninitialized references to storage, which actually indicated the beginning of storage, and therefore intersected with other state variables.
- May be prohibited direct work with
..length
Manually changing the length of the array is a fairly low-level operation. Its main advantage is gas saving with small changes in the length of the array. But this syntax allows you to accidentally (or intentionally) create an array of inadequate size, which can lead to an overlap attack. There is a long time ago for cleaning the array, it is proposed to use itdelete
to reduce the size , in addition, operations like and are discussed . Well, there is still assembly if you really need to.pop()
truncate()
extend()
From the dubious
Any barrel of honey will have its own fly in the ointment.
- Add a whole bunch of keywords for all occasions. Some of them look menacing, but so far nothing is clear. Honestly, I was hoping to see on this list
revert
,assert
andrequire
, but from the point of view of grammar, they remain just functions (and they can be redefined).
Not about the language
There are some very important changes that do not directly affect the language, but at the same time greatly affect the code of new contracts.
- Finally, numbers with a fractional part will appear . It seems that everyone is used to doing without them, and now we will learn to use them correctly .
- At the EVM level, protection against short address attack will be added . It would seem a trifle, but it’s nice that you don’t need to think about it anymore (and generally know about this problem). Maybe it will be even more strict , but there are difficulties.
Some conclusions
Although the release date of the release is still unknown, many innovations can already be touched.
They are turned on with pragma experimental "v0.5.0";
and the pragma experimental "ABIEncoderV2";
Compiler, of course, gives a warning.
In general, 0.5.0 is perceived positively. They will remove something that cannot be eliminated in any way due to backward compatibility, tightly refactor a couple of slippery topics, and make some useful changes. Then we will wait for the inheritance refactoring , and there, maybe Vyper will arrive in time.