Skip to content

Commit

Permalink
Merge pull request #74 from onflow/bastian/improve-c1-migration-guide
Browse files Browse the repository at this point in the history
  • Loading branch information
turbolent authored Mar 28, 2024
2 parents dbb010d + 7b048ed commit 928b51d
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 55 deletions.
58 changes: 32 additions & 26 deletions docs/cadence_migration_guide/type-annotations-guide.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,44 @@ sidebar_label: Cadence Type Annotations 1.0 Guide

# Type Annotations in Cadence 1.0

In addition to updating your contracts in reaction to the Core Contract changes in Cadence 1.0,
certain language changes in Cadence 1.0 will also require changes to type annotations in your contracts,
in particular type annotations on resource and struct fields.
In addition to updating your contracts in reaction to the Core Contract changes in Cadence 1.0,
certain language changes in Cadence 1.0 will also require changes to type annotations in your contracts,
in particular type annotations on resource and struct fields.
These type updates are required to accurately reflect the way that the Cadence 1.0 data migrations will change
the types of these fields' values, and the Cadence 1.0 upgrade validator will enforce that these upgrades are accurate.
the types of these fields' values, and the Cadence 1.0 upgrade validator will enforce that these upgrades are accurate.

## Restricted Types

In Cadence 1.0, support for restricted types was dropped, and replaced with [intersection types](https://cadence-lang.org/docs/1.0/language/intersection-types).
As such, any existing restricted types must be replaced with a different type.
During the automated state migration for the Cadence 1.0 upgrade, restricted typed-values will be migrated according to a specific set of rules, and all developers must update the types in their contracts to mirror this.
In Cadence 1.0, support for restricted types was dropped, and replaced with [intersection types](https://cadence-lang.org/docs/1.0/language/intersection-types).
As such, any existing restricted types must be replaced with a different type.
During the automated state migration for the Cadence 1.0 upgrade, restricted typed-values will be migrated according to a specific set of rules, and all developers must update the types in their contracts to mirror this.

* `AnyStruct{I}` and `AnyResource{I}` should be migrated to just `{I}`, as these types have identical behavior
* For any other type `T`, `T{I}` should be migrated to `T`, as this is the most specific possible type that can go here
* For any type `T`, `T{}` should be migrated to just `T`, as there is no support for empty intersection types

So, for example, a value of type `FlowToken.Vault{FungibleToken.Receiver}` should be migrated to just a `FlowToken.Vault` type,
while a value of type `AnyResource{Provider, Receiver}` should be migrated to a `{Provider, Receiver}` intersection.
So, for example, a value of type `FlowToken.Vault{FungibleToken.Receiver}` should be migrated to just a `FlowToken.Vault` type,
while a value of type `AnyResource{Provider, Receiver}` should be migrated to a `{Provider, Receiver}` intersection.

## Reference Types

Reference types (whether on their own like `&FlowToken.Vault` or within a capability type like `Capability<&FlowToken.Vault{FungibleToken.Provider}>`)
from contracts written in Cadence v0.42 will need to be given
[entitlements](https://cadence-lang.org/docs/1.0/language/access-control#entitlements) in order to retain the same functionality
in Cadence 1.0.
The Cadence 1.0 automated data migration will automatically grant the appropriate entitlements to stored values,
but any reference types that appear in your contracts will need to be manually updated.

The update you will need to perform involves changing each reference type to have the appropriate entitlements necessary to perform
the same operations in Cadence 1.0 that it previously could in Cadence v0.42.
from contracts written in Cadence v0.42 will need to be given
[entitlements](https://cadence-lang.org/docs/1.0/language/access-control#entitlements) in order to retain the same functionality
in Cadence 1.0.
The Cadence 1.0 automated data migration will automatically grant the appropriate entitlements to stored values,
but any reference types that appear in your contracts will need to be manually updated.

The update you will need to perform involves changing each reference type to have the appropriate entitlements necessary to perform
the same operations in Cadence 1.0 that it previously could in Cadence v0.42.
The Cadence 1.0 upgrade validator will enforce that these upgrades are accurate, and will suggest the correct type in case of an error.
However, if you'd like to understand how the validator computes this type, the next section has a technical explanation of what the validator is computing.

### How the Validator Computes Entitlements

The first basic concept necessary to understand the upgrade is the "entitlements function";
i.e. a hypothetical function that computes the set of entitlements that are valid for some composite or interface type `T`.
This is just the complete set of entitlements that appear in that type's definition.
The first basic concept necessary to understand the upgrade is the "entitlements function";
i.e. a hypothetical function that computes the set of entitlements that are valid for some composite or interface type `T`.
This is just the complete set of entitlements that appear in that type's definition.

E.g., for a resource type `R` defined as:

Expand All @@ -54,15 +54,15 @@ access(all) resource R {
}
```

`Entitlements(I)` would be equal to `{E, G, H}`, i.e. all the entitlements that appear in `I`'s definition.
The idea here is that any reference that was previously typed as `&R` was originally able to call all
the `pub` functions in `R` (here both `foo` and `bar`), and after the Cadence 1.0 migration we want that to still be the case.
`Entitlements(I)` would be equal to `{E, G, H}`, i.e. all the entitlements that appear in `I`'s definition.
The idea here is that any reference that was previously typed as `&R` was originally able to call all
the `pub` functions in `R` (here both `foo` and `bar`), and after the Cadence 1.0 migration we want that to still be the case.
In order to make that true, we need to give the `&R` all the entitlements it might need to do that, which is exactly `Entitlements(R)`.

All of which is to say, any `&R` reference types that appear in your contract must be updated to `auth(E1, E2, ...) &R`, where `E1, E2, ...` are all
All of which is to say, any `&R` reference types that appear in your contract must be updated to `auth(E1, E2, ...) &R`, where `E1, E2, ...` are all
the entitlements in `Entitlements(R)`.

One important note is that reference to restricted types (`&T{I}`) behave slightly differently; instead of being given entitlements to `T`, they
One important note is that reference to restricted types (`&T{I}`) behave slightly differently; instead of being given entitlements to `T`, they
are instead granted only entitlements based on the interfaces in the restriction set (here `{I}`). So for some interface and composite defined like so:

```cadence
Expand All @@ -76,4 +76,10 @@ access(all) resource R: I {
```

A type `&R{I}` should be updated to `auth(E) &R`, since the entitlements it is given is only those in `I`. It does not receive an entitlement to `F`, since
the old `&R{I}` was not able to call `bar`.
the old `&R{I}` was not able to call `bar`.

## Account Types

The replacement for `AuthAccount` is the fully-entitled type `auth(Storage, Contracts, Keys, Inbox, Capabilities) &Account`.

The replacement for `PublicAccount` is the unentitled type `&Account`.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ To ensure your contracts are fully operational with Cadence 1.0, follow these es
flow-c1 version
```

5. **Stage**: A new **_Staging process_** will be released in the coming weeks that checks if your updated code is compatible with Cadence 1.0. Complete this [form](https://docs.google.com/forms/d/e/1FAIpQLSfprZJLPSEAS6H7_oL0j6bzetDzkHPmDZHYAGgqAAOAdLDKqw/viewform) to stay informed about updates and receive recommendations tailored to your code.
5. **Stage**: The last step is to get your updated code ready to replace your live pre-cadence 1.0 code when the upgrade occurs, to do this you need to [stage](https://cadence-lang.org/docs/cadence_migration_guide/staging-guide) your contracts. Stage them on testnet and ensure that they are working as expected along with their staged dependencies. Staging for mainnet contracts is coming soon.

### Resources

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,20 @@ This guide aims to simplify the migration process to Cadence 1.0, making it acce

## Staging a contract

<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/vhdP1kv_Ooc"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>

In order to migrate your updated smart contract to Cadence 1.0, it's crucial to stage it on the Testnet network. This preliminary step not only verifies the contract's compatibility and syntactical correctness but also ensures a seamless transition to the new environment.

```bash
flow migrate stage-contract HelloWorld --network=testnet
flow-c1 migrate stage-contract HelloWorld --network=testnet
```

Ensure that HelloWorld accurately reflects the name of your contract as specified in your flow.json configuration file.
Expand All @@ -30,7 +40,7 @@ Ensure that HelloWorld accurately reflects the name of your contract as specifie
To confirm that your contract is ready for migration and has been successfully staged, execute the following command:

```bash
flow migrate is-staged HelloWorld --network=testnet
flow-c1 migrate is-staged HelloWorld --network=testnet
```

A response of true indicates that your contract has been approved by the Flow Blockchain Testnet network and is ready for the migration process.
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,44 @@ sidebar_label: Cadence Type Annotations 1.0 Guide

# Type Annotations in Cadence 1.0

In addition to updating your contracts in reaction to the Core Contract changes in Cadence 1.0,
certain language changes in Cadence 1.0 will also require changes to type annotations in your contracts,
in particular type annotations on resource and struct fields.
In addition to updating your contracts in reaction to the Core Contract changes in Cadence 1.0,
certain language changes in Cadence 1.0 will also require changes to type annotations in your contracts,
in particular type annotations on resource and struct fields.
These type updates are required to accurately reflect the way that the Cadence 1.0 data migrations will change
the types of these fields' values, and the Cadence 1.0 upgrade validator will enforce that these upgrades are accurate.
the types of these fields' values, and the Cadence 1.0 upgrade validator will enforce that these upgrades are accurate.

## Restricted Types

In Cadence 1.0, support for restricted types was dropped, and replaced with [intersection types](https://cadence-lang.org/docs/1.0/language/intersection-types).
As such, any existing restricted types must be replaced with a different type.
During the automated state migration for the Cadence 1.0 upgrade, restricted typed-values will be migrated according to a specific set of rules, and all developers must update the types in their contracts to mirror this.
In Cadence 1.0, support for restricted types was dropped, and replaced with [intersection types](https://cadence-lang.org/docs/1.0/language/intersection-types).
As such, any existing restricted types must be replaced with a different type.
During the automated state migration for the Cadence 1.0 upgrade, restricted typed-values will be migrated according to a specific set of rules, and all developers must update the types in their contracts to mirror this.

* `AnyStruct{I}` and `AnyResource{I}` should be migrated to just `{I}`, as these types have identical behavior
* For any other type `T`, `T{I}` should be migrated to `T`, as this is the most specific possible type that can go here
* For any type `T`, `T{}` should be migrated to just `T`, as there is no support for empty intersection types

So, for example, a value of type `FlowToken.Vault{FungibleToken.Receiver}` should be migrated to just a `FlowToken.Vault` type,
while a value of type `AnyResource{Provider, Receiver}` should be migrated to a `{Provider, Receiver}` intersection.
So, for example, a value of type `FlowToken.Vault{FungibleToken.Receiver}` should be migrated to just a `FlowToken.Vault` type,
while a value of type `AnyResource{Provider, Receiver}` should be migrated to a `{Provider, Receiver}` intersection.

## Reference Types

Reference types (whether on their own like `&FlowToken.Vault` or within a capability type like `Capability<&FlowToken.Vault{FungibleToken.Provider}>`)
from contracts written in Cadence v0.42 will need to be given
[entitlements](https://cadence-lang.org/docs/1.0/language/access-control#entitlements) in order to retain the same functionality
in Cadence 1.0.
The Cadence 1.0 automated data migration will automatically grant the appropriate entitlements to stored values,
but any reference types that appear in your contracts will need to be manually updated.

The update you will need to perform involves changing each reference type to have the appropriate entitlements necessary to perform
the same operations in Cadence 1.0 that it previously could in Cadence v0.42.
from contracts written in Cadence v0.42 will need to be given
[entitlements](https://cadence-lang.org/docs/1.0/language/access-control#entitlements) in order to retain the same functionality
in Cadence 1.0.
The Cadence 1.0 automated data migration will automatically grant the appropriate entitlements to stored values,
but any reference types that appear in your contracts will need to be manually updated.

The update you will need to perform involves changing each reference type to have the appropriate entitlements necessary to perform
the same operations in Cadence 1.0 that it previously could in Cadence v0.42.
The Cadence 1.0 upgrade validator will enforce that these upgrades are accurate, and will suggest the correct type in case of an error.
However, if you'd like to understand how the validator computes this type, the next section has a technical explanation of what the validator is computing.

### How the Validator Computes Entitlements

The first basic concept necessary to understand the upgrade is the "entitlements function";
i.e. a hypothetical function that computes the set of entitlements that are valid for some composite or interface type `T`.
This is just the complete set of entitlements that appear in that type's definition.
The first basic concept necessary to understand the upgrade is the "entitlements function";
i.e. a hypothetical function that computes the set of entitlements that are valid for some composite or interface type `T`.
This is just the complete set of entitlements that appear in that type's definition.

E.g., for a resource type `R` defined as:

Expand All @@ -54,15 +54,15 @@ access(all) resource R {
}
```

`Entitlements(I)` would be equal to `{E, G, H}`, i.e. all the entitlements that appear in `I`'s definition.
The idea here is that any reference that was previously typed as `&R` was originally able to call all
the `pub` functions in `R` (here both `foo` and `bar`), and after the Cadence 1.0 migration we want that to still be the case.
`Entitlements(I)` would be equal to `{E, G, H}`, i.e. all the entitlements that appear in `I`'s definition.
The idea here is that any reference that was previously typed as `&R` was originally able to call all
the `pub` functions in `R` (here both `foo` and `bar`), and after the Cadence 1.0 migration we want that to still be the case.
In order to make that true, we need to give the `&R` all the entitlements it might need to do that, which is exactly `Entitlements(R)`.

All of which is to say, any `&R` reference types that appear in your contract must be updated to `auth(E1, E2, ...) &R`, where `E1, E2, ...` are all
All of which is to say, any `&R` reference types that appear in your contract must be updated to `auth(E1, E2, ...) &R`, where `E1, E2, ...` are all
the entitlements in `Entitlements(R)`.

One important note is that reference to restricted types (`&T{I}`) behave slightly differently; instead of being given entitlements to `T`, they
One important note is that reference to restricted types (`&T{I}`) behave slightly differently; instead of being given entitlements to `T`, they
are instead granted only entitlements based on the interfaces in the restriction set (here `{I}`). So for some interface and composite defined like so:

```cadence
Expand All @@ -76,4 +76,10 @@ access(all) resource R: I {
```

A type `&R{I}` should be updated to `auth(E) &R`, since the entitlements it is given is only those in `I`. It does not receive an entitlement to `F`, since
the old `&R{I}` was not able to call `bar`.
the old `&R{I}` was not able to call `bar`.

## Account Types

The replacement for `AuthAccount` is the fully-entitled type `auth(Storage, Contracts, Keys, Inbox, Capabilities) &Account`.

The replacement for `PublicAccount` is the unentitled type `&Account`.

0 comments on commit 928b51d

Please sign in to comment.