Skip to content

ink! 2.0 Roadmap #153

Closed
Closed
@Robbepop

Description

@Robbepop

ink! 2.0 Roadmap

This is a post describing the current state of ink! and its problems and how we are planning to deal with them in the near future.


During development of ink! we found several issues in its design and implementation.
These issues, some of them more critical than other, hinder us in delivering the best developer experience possible for smart contract development.

Problem #1: Big-Fat-Macro

In its current form the entire code of an ink! smart contract lives within a macro body call to the contract! macro. On the one hand side this beautifully encapsulates and separates ink! code from Rust code and provides the ink! "compiler" with the ability to reason about everything within. On the other hand side the approach to deal with all smart contract code through a single macro invocation has several downsides:

  • RLS and rust-analyzer are having a very hard time reasoning about the internals of macro instantiations and thus we cannot deliver upon our principal of IDE friendliness for ink! at the moment.
  • Having all code specified within a single macro body also means that the entire code of a smart contract needs to live within these boundaries which excludes multi-file projects and general coding structure. This is critical to our principle of having a well scaling developer experience for writing smart contracts.

Solution

We are going to solve this by re-implementing ink! 2.0 as a rustc plugin instead of a procedural macro. The main benefits compared to a procedural macro are that a rustc plugin is able to introspect the entirety of the macro expansion invocations and thus can naturally reason about all of the expanded code which is exactly why we introduced the Big-Fat-Macro in the first place. The downside of this solution is that we cannot expect to work on stable Rust anytime soon but we do not consider this a show stopper since nightly Rust has shown to be stable and robust enough for our purposes.

Note: This change will break compatibility with existing smart contracts. Adjustments are going to be necessary.

Problem #2: Types

Accessing types in procedural macros and also in rustc plugins is simply put not possible. This is for a reason and probably won't change. We normally don't need type information when it comes to simple macro expansion rules, however, for ink! we do more than normal macros and for some tasks, such as the metadata (ABI) file generation, we need access to the underlying types specified within the smart contract code.

For this purpose we already put some work into creating a so-called two-phase compilation approach. This will change the project structure of current ink! smart contracts a bit in order to work. Don't worry, out cargo-contract plugin will deal with this upon creation of a new smart contract. Also we might think about a new routine in order to keep project structures up-to-date through a simple call to the cargo-contract plugin.

On the surface for users generating ABI files will no longer be a separate result of a simple compilation of a smart contract but will be its own phase. In order to create ABI files user will have to invoke the cargo-contract plugin with something in the lines of cargo contract generate-abi and ABI files for the smart contract will be created in the target folder as is done today.

Note: This change will break compatibility with existing smart contracts. Adjustments are going to be necessary.

Problem #3: Calling other Smart Contracts

The fundamental feature to call other ink! smart contracts has not yet been realized due to the current problems stated above. Smart contracts need access to the meta information of the smart contracts they depend on in order to guide instantiations and calls of remote smart contracts.
Also having to specify links to other smart contracts in the Big-Fat-Macro world could potentially lead to several other design complications.

So this builds on the availability on the solutions for problems #1 and #2.

What we do not want is low-level calls to primitives such as ext_call that are available today.* (* After merging #133)
What we do want instead is having our rustc plugin create code on the fly for simple instantiation and calling of other smart contracts that are types safe and eventually just feel like calling yet another Rust function. However, due to complications with the fundamental approach and gas costs a proper UX design has yet to be found.

Problem #4: A world full of fees

When ink! was originally developed it was not clear (at least not to me) that state rent will be a thing in the future. As of the current Substrate implementation it now is. This means that smart contract developers need to have this additional piece of complexity in their heads while developing smart contracts.

In essence rental fees mean that a smart contract now has to pay fees in respect to its used storage size. Also there are going to be techniques to distribute storage fees, such as systems similar to cookie-contracts. In theory we could declare ink! to be independent from all this and won't help users design their smart contract economy friendly with regards to state rent. On the other side we think that if we want to make state rent a success, we need to guide users in these new lands of smart contract development. The funny side about this story is that we need to collect experience with these techniques ourselves before we can actually give great advise.

The hopes are the ink! 2.0, once done, won't have to adjust a lot in order to provide guidelines and help with respect to support smart contract developers in developing rental state friendly smart contracts.

Enhancement: Standard Lib

Currently the ink! standard lib (namely ink_core) is pretty small and doesn't feature a whole lot of collections and utilities. This is for a reason since we currently have no option to dynamically link compiled smart contracts and thus have to rely on static linking which blows our Wasm blobs into gigantic bubbles of ones and zeros.

However, the future looks dynamic, and for the sake and purpose of productivity we want to do two things:

  • Provide many utilities and collections out of the box for developing ink! smart contracts through a standardized set of libraries. Right now we are missing fundamental collections such as storage::BTreeMap/Set and storage::BinaryHeap to name a few. Especially in very performance constrained smart contract ecosystems it is very important to provide many specialized data structures that are heavily optimized for their use cases in order to save up gas and relieve the chain under pressure.
  • Encourage users to provide libraries on their behalf. With the current ink! and its very constrained model it is not very encouraging to develop smart contract libraries. While it is possible, nobody does it and most of the developers develop in isolation. Especially with the solutions of the first two mentioned problems we want to build up ink! 2.0 in a way that encourages for library and interface development in a similar vein as Rust already successfully does.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-eDSLConcerning the Rust eDSL as a total.B-enhancementNew feature or requestC-discussionAn issue for discussion for a given topic.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions