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 throwthe benefit revert()/ 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: In
      for(var i = 0; i < 100500; i++) { ... // бесконечный цикл
      addition, they discuss what to replace structures with
      var (z, y, z) = foo();
      and how to more elegantly skip unnecessary values .
    • Forbidden to use constantfor functions - everywhere should be view or pure.
    • Built in функция gasleft()instead msg.gas. It is more clear that this is not some kind of constant, but the remaining amount of gas. Yes, gasleft()you can override.
    • Movedblock.blockhash to blockhash. It is logical, because the blockhashcurrent 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/ sha3to inline assembly.
    • Rejection of the unary plus, because it does not have any special role and can participate in stupid mistakes (like x=+1;instead x+=1;).
    • It is planned to abandon the multiplier years, because now it is defined as 365 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 emitwhen 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 { ...

    • 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 compiled
       x = 1; 
       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 like foror switch.
    • 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 0x0use it instead of the usual one address(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 of external viewfunctions using publicvariables.
    • 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 abiand its methods
      encode, encodePacked, encodeWithSelectorand encodeWithSignatureto monitor data assembly to call or hashing.
      It is proposed to use them to collect arguments for keccak256/ sha256/ ripemd160and call/ 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, but uint256. 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 rejection varand 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.dataat 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 it deleteto 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, assertand require, 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.

    Also popular now: