Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework the Environment trait #1303

Open
xgreenx opened this issue Jun 23, 2022 · 5 comments
Open

Rework the Environment trait #1303

xgreenx opened this issue Jun 23, 2022 · 5 comments

Comments

@xgreenx
Copy link
Collaborator

xgreenx commented Jun 23, 2022

It is possible to customize AccountId, Timestamp, Balance, Hash, Gas, BlockNumber types on the contract-pallet side. So different parachain can use different types inside.

To support it and be agnostic to the parachain/blockchain ink! provides Environment trait that is automatically implemented by the contract with DefaultEnvironment or can be customized with its own environment via #[ink::contract(env = CustomEnvironment)].

The problem with that approach is:

  • ink! requires propagation of the Env generic via the whole stack.
  • It makes the development of ink!, libraries for smart contracts harder.
  • It makes code harder for newcomers. They should be aware of the generics and inner struct of the pallet.
  • It is impossible to import a contract written for another parachain if the types are not the same. Because one contract will use ParachainAEnvironment and another - ParachainBEnvironment.

We are proposing another approach:
Create a separate crate like ink_types that will contain definitions of all customizable items(better put it in a separate repository). It can be, for example, that file.

ink_env crate uses ink_types to get all requires types:

/// The default balance type.
pub type Balance = ink_types::Balance;

/// The default timestamp type.
pub type Timestamp = ink_types::Timestamp;

/// The default gas type.
pub type Gas = ink_types::Gas;

/// The default block number type.
pub type BlockNumber = ink_types::BlockNumber;

And use a default configuration.

If some parachain/blockchain want to use custom types, they fork the repository and use [patch.crates-io] to override default types.

[patch.crates-io]
ink_types = { path = "/path/to/local/ink_types"}

or

[patch.crates-io]
ink_types = { git = "https://github.com/fork/ink_types"}

So the destination contract decides that types use across all dependencies. It solves all problems described above. If someone wants to deploy the contract to parachain/blockchain with the custom environment he only needs to add 2 lines in his Cargo.toml.

@HCastano
Copy link
Contributor

If some parachain/blockchain want to use custom types, they fork the repository and use [patch.crates-io] to override default types.

I really don't like this approach. Part of the point of using Substrate is that things are generic and they can be swapped out easily. Having people fork a crate only to swap some types around seems like unnecessary overhead

@xgreenx
Copy link
Collaborator Author

xgreenx commented Jun 23, 2022

Part of the point of using Substrate is that things are generic and they can be swapped out easily

It is that I'm suggesting!=)

Only maintainers of the network should fork crate and specify new types. The developers only should add two lines in Cargo.toml. In real life, we will have more developers than parachains=) If you have ten parachain with unique types and 10k developers, you will have only ten crates that can be easily swapped. All contracts will be compatible between that networks because any contract didn't specify ParachainXEnvironment.

Right now, if you have contracts that use ParachainXEnvironment, you can't deploy it on parachain Y. You can't import that crate(with contract) and reuse the logic of that contract because it works only with ParachainXEnvironment. You need to fork that contract(or a bunch of contracts) and swap ParachainXEnvironment -> ParachainYEnvironment. Of course, that problem can be solved if each struct in the contract uses the E: Environment generic(I want to highlight that generics are not allowed in contracts and traits right now).

But what approach adds more overhead? The approach where 10k developers should propagate E: Environment everywhere, slow down development, and fix compilation errors. Or fork crate ten times, and during the deployment specify two lines(only in your final contract or in the workspace) and don't worry about any dependency and environments?=)

I like the idea of using generics in the Substrate. And I like generics in Rust=) But smart contracts are about easy development and faster deployment. You don't need to be a guru of Rust to write a smart contract otherwise, I can use Substrate=D

@xgreenx
Copy link
Collaborator Author

xgreenx commented Jun 23, 2022

In other words, they are global types for the whole parachain's smart contract ecosystem. But in that way, they still are generic because you can replace them to work with specific parachain.

With substrate, one relay chain contains many parachain, and each parachain has its Config. But in terms of one parachain, the config is the same across all contracts on that parachain otherwise it can't work.

@h4x3rotab
Copy link

Personally I'd prefer to just fix AccountId to AccountId32 and Balance to u128. Substrate is already built to allow customization. What we need more is an unified ecosystem that can interoperate.

@xgreenx
Copy link
Collaborator Author

xgreenx commented Apr 13, 2023

Added an example to show how it could work and how it is easy to do on the developer side=)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants