-
Notifications
You must be signed in to change notification settings - Fork 89
Add migration guide from ink! 4.x to 5.0 #301
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
Merged
Merged
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
af6e388
Add migration guide from ink! 4.x to 5.0
cmichi abed487
Add Krest to compatible production chains
cmichi 062b65d
Merge remote-tracking branch 'origin/master' into cmichi-add-migratio…
cmichi c90d2ba
Add screenshot of `cargo contract storage`
cmichi 29980d7
Add steps to upgrade
cmichi 95e84b1
Add breaking decode behavior change
cmichi 1d6e623
Add note for `StorageVec`
cmichi 1beaff2
Add note on support for multiple chain extensions
cmichi c39589e
Add note on stabilized `call_runtime`
cmichi 0d4876a
Add note on chain extension syntax change
cmichi 3a969d7
Move `StorageVec` section up
cmichi 04125e5
Add note on new fallible methods
cmichi d314a0a
Move `StorageVec` and fallible methods to important section
cmichi d46d35b
Improve docs on fallible methods
cmichi 7b37142
Improve `StorageVec` text
cmichi fecf707
Mention `non_fallible_api` lint
cmichi c55baa0
Update list of fallible `StorageVec` methods
cmichi 95d2498
Update text on recommendations
cmichi b0c4455
Update section on chain extensions
cmichi 9ff89d4
Mention contract verification
cmichi 31309ed
Add note on fallible methods
cmichi 48c822d
Apply suggestions from code review
47d2005
Explain reason for data migration better
cmichi 4710bae
Move custom signature topics to Events 2.0
cmichi bd3f1a9
Added E2E builder API changes
cmichi b4e161f
Link to more infos about safe math in Rust
cmichi d69be1d
Improve text on safe math
cmichi 2a7b82d
Clarify text
cmichi d550fba
Improve text
cmichi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next
Next commit
Add migration guide from ink! 4.x to 5.0
- Loading branch information
commit af6e388452bdd6c77196383054426ccbb8cd586e
There are no files selected for viewing
342 changes: 342 additions & 0 deletions
342
versioned_docs/version-5.x/faq/migrating-from-ink-4-to-5.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,342 @@ | ||
| --- | ||
| title: Migrating from ink! 4.x to 5.0 | ||
| slug: /faq/migrating-from-ink-4-to-5 | ||
| --- | ||
|
|
||
| <img src="/img/title/migration-4.x-to-5.0.svg" className="titlePic" /> | ||
|
|
||
| We've made a couple of breaking changes from ink! 4.x to ink! 5.0. | ||
| On this page we outline how you can migrate existing clients and | ||
| contracts from 4.x to 5.0. | ||
|
|
||
| This release addresses the majority of issues raised in [the OpenZeppelin | ||
| security review](https://blog.openzeppelin.com/security-review-ink-cargo-contract). | ||
| In particular, we addressed the proxy selector clashing attack. | ||
|
|
||
| You can find the full changelog of the 5.0 release [here](https://github.com/paritytech/ink/blob/master/CHANGELOG.md). | ||
|
|
||
| :::caution | ||
| This migration guide only considers your code base! Not your data! | ||
|
|
||
| If you have an existing contract on-chain you cannot just | ||
| upgrade the code on-chain, you also have to migrate your data. | ||
cmichi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| The way how ink! 4.0 stores data and reads from it (i.e. the storage | ||
| layout) changes from ink! 3.x to 4.0. | ||
cmichi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ::: | ||
|
|
||
| ## Compatibility | ||
|
|
||
| The following chains are in production and support ink! 5.0: | ||
|
|
||
| <div className="row"> | ||
| <div className="col text--center"> | ||
| <a href="https://alephzero.org"> | ||
| <img src= "/img/chains/aleph-zero.svg" className="chain" /> | ||
| </a> | ||
| </div> | ||
| <div className="col text--center"> | ||
| <a href="https://astar.network"> | ||
| <img src= "/img/chains/astar.svg" className="chain" /> | ||
| </a> | ||
| </div> | ||
| <div className="col text--center"> | ||
| <a href="https://shiden.astar.network"> | ||
| <img src= "/img/chains/shiden.svg" className="chain" /> | ||
| </a> | ||
| </div> | ||
| </div> | ||
|
|
||
| <div className="row"> | ||
| <div className="col text--center"> | ||
| <a href="http://phala.network"> | ||
| <img src= "/img/chains/phala.svg" className="chain" /> | ||
| </a> | ||
| </div> | ||
| <div className="col text--center"> | ||
| <a href="https://pendulumchain.org"> | ||
| <img src= "/img/chains/pendulum.svg" className="chain" /> | ||
| </a> | ||
| </div> | ||
| <div className="col text--center"> | ||
| <a href="https://pendulumchain.org/amplitude"> | ||
| <img src= "/img/chains/amplitude.svg" className="chain" /> | ||
| </a> | ||
| </div> | ||
| </div> | ||
|
|
||
| ### `cargo-contract` 4.0 | ||
|
|
||
| Together with ink! 5.0 we've released `cargo-contract` 4.0. | ||
|
|
||
| :::info | ||
| You have to use `cargo-contract` >= 4.0 for ink! 5.0 contracts! | ||
|
|
||
| You can upgrade via: | ||
|
|
||
| ```rust | ||
| cargo install cargo-contract --version ^4 | ||
| ``` | ||
| ::: | ||
|
|
||
| Make sure that e.g. your CI also uses at least `cargo-contract` 4.0 with ink! v5.0. | ||
| If you have wrapper scripts around `cargo-contract`, you should | ||
| ensure that this version is enforced, otherwise users will get an error. | ||
|
|
||
| ### Substrate | ||
|
|
||
| The same requirements as for ink! 4.0 hold. | ||
|
|
||
| * `pallet-contracts` >= `polkadot-v0.9.37`. | ||
| * `substrate-contracts-node` >= `v0.24.0` | ||
|
|
||
| #### How do I find out which Polkadot version a chain is running on? | ||
|
|
||
| You can query the `contracts::palletVersion()` via the chain state RPCs. It has to | ||
| be `>= 9` for ink! 5.0 to be compatible. | ||
|
|
||
| You can use e.g. the [polakdot.js app](https://polkadot.js.org/apps/) to do this: | ||
| Developer » Chain State » `contracts` » `palletVersion()` » Click on the `+` on the right. | ||
|
|
||
| <center> | ||
| <img src="/img/pallet-version.png" /> | ||
| </center> | ||
|
|
||
| ### Tooling | ||
|
|
||
| * `cargo-contract` >= v4.0 | ||
| * Stable Rust >= 1.75 | ||
|
|
||
| ### Dependencies | ||
|
|
||
| Same as for ink! 4.0. | ||
|
|
||
| * `scale` >= 3 | ||
| * `scale-info` >= 2.6 | ||
|
|
||
| ### Frontend Libraries | ||
|
|
||
| Same as for ink! 4.0: `polkadot-js/api` and `polkadot-js/api-contract` >= 9.10.2. | ||
|
|
||
| ## Important Changes | ||
|
|
||
| ### `scale` dependencies were moved to `ink` entrance crate | ||
|
|
||
| This change was done to ensure that you always use the correct scale dependency versions | ||
| with an ink! version. The relevant PR is [#1890](https://github.com/paritytech/ink/pull/1890). | ||
|
|
||
| We removed the requirement for contracts to have direct dependencies on `parity-scale-codec` | ||
| and `scale-info` in their `Cargo.toml`. | ||
| You can now remove those dependencies from your contracts `Cargo.toml`: | ||
|
|
||
| ```diff | ||
| ink = { version = "4.3", default-features = false } | ||
| -scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } | ||
| -scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true } | ||
| ``` | ||
|
|
||
| Both crates have been re-exported from the `ink` umbrella crate: `ink::scale_info` and `ink::scale`. | ||
|
|
||
| We created a convenience macro to derive the re-exported traits `ink::scale::Encode`, | ||
| `ink::scale::Decode` and `ink::scale_info::TypeInfo`. | ||
|
|
||
| ```rust | ||
| // Previously | ||
| #[scale::Encode, scale::Decode)] | ||
| #[cfg_attr(feature = "std", derive(::scale_info::TypeInfo))] | ||
| pub enum Error {} | ||
|
|
||
|
|
||
| // Now | ||
| #[ink::scale_derive(Encode, Decode, TypeInfo)] | ||
| pub enum Error {} | ||
| ``` | ||
|
|
||
| The documentation of the macro can be found [here](https://docs.rs/ink/5.0.0-rc/ink/attr.scale_derive.html). | ||
|
|
||
| ### Wildcard selectors: only one other message is allowed in the contract besides the wildcard selector | ||
|
|
||
| Following [our security review by OpenZeppelin](https://blog.openzeppelin.com/security-review-ink-cargo-contract), | ||
| we've tightened the usage of wildcard selectors. | ||
| With ink! 5.0 we allow only exactly one other contract message with a well-known reserved | ||
| selector to be defined. In ink! 4.x, more than one other message was allowed. | ||
|
|
||
| Read more in [the PR](https://github.com/paritytech/ink/pull/1708) and [IIP-2: Limit contracts with a wildcard selector to one other message](https://github.com/paritytech/ink/issues/1676). | ||
|
|
||
| The proposal is to restrict contracts with a wildcard selector to only have one other message | ||
| with a reserved/well known selector. This guarantees that there are no selector clashes, | ||
cmichi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| either by chance or malicious intent, and that the Proxy will only handle messages intended for it. | ||
|
|
||
| If a contract uses a wildcard selector `#[ink(message, payable, selector = _)]` it _MAY_ define one | ||
| other message. This message _MUST_ use the reserved selector `@`. | ||
| This selector _MUST_ only be used in conjunction with a wildcard selector. | ||
|
|
||
| ```rust | ||
| /// Handles any message with no matching selector in this proxy contract | ||
| #[ink(message, selector = _)] | ||
| pub fn fallback(&self) { | ||
| // forward call to the "logic" contract which actually executes the call | ||
| } | ||
|
|
||
| #[ink::scale_derive(Decode)] | ||
| pub enum ProxyMessage { | ||
| UpgradeContract(Hash), | ||
| } | ||
|
|
||
| /// One other message allowed to handle messages. | ||
| /// Fails to compile unless `@` is used as the selector. | ||
| #[ink(message, selector = @)] | ||
| pub fn handler(&self, msg: ProxyMessage) { | ||
| match msg { | ||
| ProxyMessage(hash) => { } | ||
| } | ||
| } | ||
|
|
||
| /// An additional message. Fails to compile when uncommented. | ||
| // #[ink(message)] | ||
| // pub fn additional_message(&self, msg: ProxyMessage) { | ||
| // match msg { | ||
| // ProxyMessage(hash) => ... | ||
| // } | ||
| // } | ||
| ``` | ||
|
|
||
| ### Events 2.0 | ||
|
|
||
| In prior ink! versions, events were defined inside the `#[ink::contract]` macro. | ||
| With ink! 5.0 we decouple events from the `#[ink::contract]` macro, | ||
| allowing events to be shared between contracts. | ||
| We've updated [the Events documentation page](/5.x/basics/events) accordingly. | ||
|
|
||
| The syntax of defining events within the main `#[ink::contract]` macro will continue to work, | ||
| no code changes in existing contracts are required to update to the new syntax. | ||
|
|
||
| :::caution | ||
| The topic calculation changed in general, so also for events that are declared inside the | ||
| `#[ink::contract]` macro! | ||
|
|
||
| This is a breaking change for any client code which uses topics to filter events. | ||
|
|
||
| Please see [#1827](https://github.com/paritytech/ink/pull/1827) for details. | ||
| ::: | ||
|
|
||
| ### No more unchecked arithmetic | ||
|
|
||
| Unchecked arithmetic operations in a contract no longer work. | ||
cmichi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Compiling a contract that contains those will fail gracefully. | ||
| You need to handle overflows using e.g. saturating or wraparound math. | ||
|
|
||
| This was done in [#1831](https://github.com/paritytech/ink/pull/1831). | ||
cmichi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ### [ink_e2e] Improved `call()` API | ||
cmichi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| We removed the `build_message()` function with its unhandy callback. | ||
|
|
||
| ```rust | ||
| // Previously | ||
| let first_insert = ink_e2e::build_message::<MappingsRef>(contract_id) | ||
| .call(|contract| contract.insert_balance(1_000)); | ||
|
|
||
| // Now | ||
| let first_insert = ink_e2e::build_message::<MappingsRef>(contract_id) | ||
| .call().insert_balance(1_000)); | ||
| ``` | ||
|
|
||
| See [#1782](https://github.com/paritytech/ink/pull/1782) for more details. | ||
|
|
||
|
|
||
| ## Interesting New Features | ||
|
|
||
| ### End-To-End testing with a chain snapshot | ||
|
|
||
| With ink! 5.0 we introduce the possibility of running your tests against the | ||
| fork (i.e. snapshot) of a live chain. | ||
|
|
||
| See [this page](/5.x/basics/contract-testing/chain-snapshot) in our documentation for details. | ||
|
|
||
| ### New lints | ||
|
|
||
| The new lints are: | ||
| * [`no_main`](/5.x/linter/rules/no_main): enforces `no_main` for contracts. | ||
| * [`primitive_topic`](/5.x/linter/rules/primitive_topic): no number types are allowed as event topics. | ||
| * [`storage_never_freed`](/5.x/linter/rules/storage_never_freed): what is written into storage can be removed again. | ||
| * [`strict_balance_equality`](/5.x/linter/rules/strict_balance_equality): detects usage of strict balance equality checks, a common smart contract vulnerability. | ||
| * [`non_fallible_api`](/5.x/linter/rules/non_fallible_api): detects the usage of potentially unsafe methods for which there are safer alternatives. | ||
|
|
||
| With `cargo-contract` 4.0 we added a couple new lints for common smart contract issues | ||
| and best practices. | ||
| You can run the linter via `cargo contract build --lint`. | ||
|
|
||
| Details on each lint can be found [here](/5.x/linter/overview). | ||
|
|
||
| ### New `cargo-contract` commands | ||
|
|
||
| We added a bunch of helpful new commands to `cargo-contract` 4.0: | ||
|
|
||
| * `cargo contract verify`: contract verification ([#1404](https://github.com/paritytech/cargo-contract/pull/1404), [#1306](https://github.com/paritytech/cargo-contract/pull/1306)) | ||
| * `cargo contract info` now outputs the language of the deployed contract, using a heuristic ([#1329](https://github.com/paritytech/cargo-contract/pull/1329)) | ||
| * `cargo contract info --binary`: outputs the on-chain Wasm of the contract ([#1311](https://github.com/paritytech/cargo-contract/pull/1311/)) | ||
| * `cargo contract info --all`: displays all addresses of deployed contracts on a particular chain ([#1319](https://github.com/paritytech/cargo-contract/pull/1319)) | ||
| * `cargo contract storage`: displays the storage of an on-chain contract ([#1395](https://github.com/paritytech/cargo-contract/pull/1395), [#1414](https://github.com/paritytech/cargo-contract/pull/1414)) | ||
|
|
||
| For all these commands you can also supply the `--help` cli flag to get more info (e.g. `cargo contract storage --help`). | ||
|
|
||
| ### Alternative off-chain E2E testing backend support: DRink! | ||
|
|
||
| DRink! is a toolbox for ink! developers that allows for testing your contracts | ||
| without any running node. | ||
|
|
||
| It has a number of features that are pretty great: | ||
|
|
||
| - deploy and call your contracts synchronously, _without any delays_ related to block production or networking. | ||
| - enhanced debugging and call tracing. | ||
| - supports _arbitrary runtime_ configurations, including custom chain extensions and runtime calls. | ||
| - full control over runtime state, including block number, timestamp, etc. | ||
|
|
||
| See the [DRink!](https://github.com/inkdevhub/drink) page for more details. | ||
|
|
||
| ### We improved the contract example illustrating upgradeable contracts via `delegate_call` | ||
|
|
||
| See [here](https://github.com/paritytech/ink/tree/master/integration-tests/upgradeable-contracts) | ||
| for the contract example. | ||
|
|
||
| ### We made `set_code_hash` generic | ||
|
|
||
| The `self.env().set_code_hash()` method now accepts the `Hash` environment type instead | ||
| of a concrete `[u8; 32]`. | ||
|
|
||
| ```rust | ||
| // Previously | ||
| pub fn set_code(&mut self, code_hash: [u8; 32]) { | ||
| ink::env::set_code_hash(&code_hash).unwrap_or_else(|err| {}); | ||
| } | ||
|
|
||
| // Now | ||
| pub fn set_code(&mut self, code_hash: Hash) { | ||
| self.env().set_code_hash(&code_hash).unwrap_or_else(|err| {}); | ||
| } | ||
| ``` | ||
|
|
||
| More details in [#1906](https://github.com/paritytech/ink/pull/1906). | ||
|
|
||
| ### Buffer size can be customized | ||
|
|
||
| With [#1869](https://github.com/paritytech/ink/pull/1869) we added a possibility | ||
| of setting a custom static buffer size for ink! to use. | ||
|
|
||
| ink! uses a static buffer for interacting with pallet-contracts, i.e. to move data | ||
| between `pallet-contracts` and a smart contract. The advantage of a static buffer | ||
| is that no gas-expensive heap allocations are necessary, all allocations are done | ||
| using simple pointer arithmetic. | ||
|
|
||
| The default static buffer size is 16 kB, which is enough for on-chain smart | ||
| contracts. However, the [Phala Network](https://phala.network/) parachain on Polkadot | ||
| allows the deployment of ink! contracts off-chain. Hence, for their chain certain high | ||
| computation contracts might require a larger buffer size. | ||
|
|
||
| ### Custom signature topics | ||
cmichi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| In [#2031](https://github.com/paritytech/ink/pull/2031) we introduced an | ||
| optional attribute `signature_topic` to the `#[ink::event]` and `#[ink(event)]` macros. | ||
| It can be used to specify the signature topic for a specific event manually, instead of the | ||
| automatic topic calculation. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.