Skip to content

Commit e5e8af9

Browse files
authored
Merge pull request #1606 from onflow/build_smart_contracts_docs_cws
Smart contract doc updates.
2 parents 819f360 + 979e92d commit e5e8af9

File tree

7 files changed

+335
-393
lines changed

7 files changed

+335
-393
lines changed

docs/build/cadence/smart-contracts/best-practices/contract-upgrades.md

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,28 +20,30 @@ keywords:
2020
- contract security
2121
---
2222

23-
### Problem
23+
# Contract Upgrades with Incompatible Changes
24+
25+
## Problem
2426

2527
I have an incompatible upgrade for a contract. How can I deploy this?
2628

27-
### Solution
29+
## Solution
2830

29-
Please don't perform incompatible upgrades between contract versions in the same account.
30-
There is too much that can go wrong.
31+
Please don't perform incompatible upgrades between contract versions in the same account. There is too much that can go wrong.
3132

32-
You can make [compatible upgrades](https://cadence-lang.org/docs/language/contract-updatability) and then run a post-upgrade function on the new contract code if needed.
33+
You can make [compatible upgrades] and then run a post-upgrade function on the new contract code if needed.
3334

34-
If you must replace your contract rather than update it,
35-
the simplest solution is to add or increase a suffix on any named paths in the contract code
36-
(e.g. `/public/MyProjectVault` becomes `/public/MyProjectVault002`) in addition to making the incompatible changes,
37-
then create a new account and deploy the updated contract there.
35+
If you must replace your contract rather than update it, the simplest solution is to add or increase a suffix on any named paths in the contract code (for example, `/public/MyProjectVault` becomes `/public/MyProjectVault002`) in addition to making the incompatible changes, then create a new account and deploy the updated contract there.
3836

3937
⚠️ Flow identifies types relative to addresses, so you will also need to provide _upgrade transactions_ to exchange the old contract's resources for the new contract's ones. Make sure to inform users as soon as possible when and how they will need to perform this task.
4038

41-
If you absolutely must keep the old address when making an incompatible upgrade, then you do so at your own risk. Make sure you perform the following actions in this exact order:
39+
If you absolutely must keep the old address when you make an incompatible upgrade, then you do so at your own risk. Make sure you perform the following actions in this exact order:
4240

43-
1. Delete any resources used in the contract account, e.g. an Admin resource.
41+
1. Delete any resources used in the contract account, such as an Admin resource.
4442
2. Delete the contract from the account.
4543
3. Deploy the new contract to the account.
4644

47-
⚠️ Note that if any user accounts contain `structs` or `resources` from the _old_ version of the contract that have been replaced with incompatible versions in the new one, **they will not load and will cause transactions that attempt to access them to crash**. For this reason, once any users have received `structs` or `resources` from the contract, this method of making an incompatible upgrade should not be attempted!
45+
⚠️ If any user accounts contain `structs` or `resources` from the _old_ version of the contract that have been replaced with incompatible versions in the new one, **they will not load and will cause transactions that attempt to access them to crash**. For this reason, after any users have received `structs` or `resources` from the contract, do not attempt an incompatible upgrade with this method!
46+
47+
<!-- Relative links, will not render on page -->
48+
49+
[compatible upgrades]: https://cadence-lang.org/docs/language/contract-updatability

docs/build/cadence/smart-contracts/best-practices/project-development-tips.md

Lines changed: 104 additions & 202 deletions
Large diffs are not rendered by default.

docs/build/cadence/smart-contracts/best-practices/security-best-practices.md

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,69 +21,74 @@ keywords:
2121
- security guidelines
2222
---
2323

24+
# Cadence Security Best Practices
25+
2426
This is an opinionated list of best practices Cadence developers should follow to write more secure Cadence code.
2527

26-
Some practices listed below might overlap with advice in the [Cadence Anti-Patterns](https://cadence-lang.org/docs/design-patterns) section, which is a recommended read as well.
28+
Some practices listed below might overlap with advice in the [Cadence Anti-Patterns] section, which is a recommended read as well.
2729

2830
## References
2931

30-
[References](https://cadence-lang.org/docs/language/references) are ephemeral values and cannot be stored. If persistence is required, store a capability and borrow it when needed.
32+
[References] are ephemeral values and cannot be stored. If persistence is required, store a capability and borrow it when needed.
3133

32-
References allow freely upcasting and downcasting, e.g. a restricted type can be cast to its unrestricted type which will expose all `access(all)` functions and fields of the type.
33-
So even if your capability uses an interface to restrict its functionality, it can
34-
still be downcasted to expose all other public functionality.
34+
References allow free upcasting and downcasting. For example, a restricted type can cast to its unrestricted type, which exposes all `access(all)` functions and fields of the type. So, even if your capability uses an interface to restrict its functionality, it can still downcast to expose all other public functionality.
3535

36-
Therefore, any privileged functionality in a resource or struct that will have a public
37-
capability needs to have entitled accecss, for example `access(Owner)`.
38-
Then, the only way to access that functionality would be through an entitled reference,
39-
like `<auth(Owner) &MyResource>`.
36+
Therefore, any privileged functionality in a resource or struct that will have a public capability needs to have entitled accecss, for example `access(Owner)`. Then, the only way to access that functionality would be through an entitled reference, like `<auth(Owner) &MyResource>`.
4037

4138
## Account Storage
4239

43-
Don't trust a users' [account storage](https://cadence-lang.org/docs/language/accounts#account-storage). Users have full control over their data and may reorganize it as they see fit. Users may store values in any path, so paths may store values of "unexpected" types. These values may be instances of types in contracts that the user deployed.
40+
Don't trust a users' [account storage]. Users have full control over their data and may reorganize it as they see fit. Users may store values in any path, so paths may store values of "unexpected" types. These values may be instances of types in contracts that the user deployed.
4441

45-
Always [borrow](https://cadence-lang.org/docs/language/capabilities) with the specific type that is expected. Or, check if the value is an instance of the expected type.
42+
Always [borrow] with the specific type that is expected. Or, check if the value is an instance of the expected type.
4643

4744
## Authorized Accounts
4845

49-
Access to an `&Account` gives access to whatever is specified in the account entitlements
50-
list when that account reference is created.
51-
Therefore, [avoid using Account references](https://cadence-lang.org/docs/anti-patterns#avoid-using-authaccount-as-a-function-parameter) as a function parameter or field unless absolutely necessary and only use the minimal set of entitlements required
52-
for the specified functionality so that other account functionality cannot be accessed.
46+
Access to an `&Account` gives access to whatever is specified in the account entitlements list when that account reference is created. Therefore, [don't use Account references] as a function parameter or field unless absolutely necessary and only use the minimum set of entitlements required for the specified functionality so that other account functionality cannot be accessed.
5347

54-
It is preferable to use capabilities over direct `&Account` references when exposing account data. Using capabilities allows the revocation of access by unlinking and limits the access to a single value with a certain set of functionality.
48+
It is preferable to use capabilities over direct `&Account` references when you expose account data. Capabilities revoke access by unlinking and limits the access to a single value with a certain set of functionality.
5549

5650
## Capabilities
5751

58-
Don't store anything under the [public capability storage](https://cadence-lang.org/docs/language/capabilities) unless strictly required. Anyone can access your public capability using `Account.capabilities.get`. If something needs to be stored under `/public/`, make sure only read functionality is provided by restricting privileged functions with entitlements.
52+
Don't store anything under the [public capability storage] unless strictly required. Anyone can access your public capability with `Account.capabilities.get`. If something needs to be stored under `/public/`, restrict privileged functions with entitlements to make sure only read functionality is provided.
5953

60-
When publishing a capability, the capability might already be present at the given `PublicPath`.
61-
In that case, Cadence will panic with a runtime error to not override the already published capability.
54+
When you publish a capability, the capability might already be present at the given `PublicPath`. In that case, Cadence will panic with a runtime error to not override the already published capability.
6255

63-
It is a good practice to check if the public capability already exists with `account.capabilities.get().check` before creating it. This function will return `nil` if the capability does not exist.
56+
It is a good practice to check if the public capability already exists with `account.capabilities.get().check` before you create it. This function will return `nil` if the capability does not exist.
6457

65-
If it is necessary to handle the case where borrowing a capability might fail, the `account.check` function can be used to verify that the target exists and has a valid type.
58+
If there's a case where borrowing a capability might fail, use the `account.check` function to verify that the target exists and has a valid type.
6659

67-
Ensure capabilities cannot be accessed by unauthorized parties. For example, capabilities should not be accessible through a public field, including public dictionaries or arrays. Exposing a capability in such a way allows anyone to borrow it and perform all actions that the capability allows.
60+
Ensure that unauthorized parties cannot access capabilities. For example, capabilities should not be accessible through a public field, such as public dictionaries or arrays. When you expose a capability in such a way, anyone can borrow it and perform all actions that the capability allows.
6861

6962
## Transactions
7063

71-
Audits of Cadence code should also include [transactions](https://cadence-lang.org/docs/language/transactions), as they may contain arbitrary code, just, like in contracts. In addition, they are given full access to the accounts of the transaction's signers, i.e. the transaction is allowed to manipulate the signers' account storage, contracts, and keys.
64+
Audits of Cadence code should also include [transactions], as they may contain arbitrary code, just, like in contracts. In addition, they are given full access to the accounts of the transaction's signers, i.e. the transaction is allowed to manipulate the signers' account storage, contracts, and keys.
7265

7366
Signing a transaction gives access to the `&Account`, i.e. access to the account's storage, keys, and contracts depending on what entitlements are specified.
7467

7568
Do not blindly sign a transaction. The transaction could for example change deployed contracts by upgrading them with malicious statements, revoking or adding keys, transferring resources from storage, etc.
7669

7770
## Types
7871

79-
Use [restricted types and interfaces](https://cadence-lang.org/docs/language/restricted-types). Always use the most specific type possible, following the principle of least privilege. Types should always be as restrictive as possible, especially for resource types.
72+
Use [restricted types and interfaces]. Always use the most specific type possible, following the principle of least privilege. Types should always be as restrictive as possible, especially for resource types.
8073

8174
If given a less-specific type, cast to the more specific type that is expected. For example, when implementing the fungible token standard, a user may deposit any fungible token, so the implementation should cast to the expected concrete fungible token type.
8275

8376
## Access Control
8477

85-
Declaring a field as [`access(all)`](https://cadence-lang.org/docs/language/access-control) only protects from replacing the field's value, but the value itself can still be mutated if it is mutable. Remember that containers, like dictionaries, and arrays, are mutable.
78+
Declaring a field as [`access(all)`] only protects from replacing the field's value, but the value itself can still be mutated if it is mutable. Remember that containers, like dictionaries, and arrays, are mutable.
8679

8780
Prefer non-public access to a mutable state. That state may also be nested. For example, a child may still be mutated even if its parent exposes it through a field with non-settable access.
8881

8982
Do not use the `access(all)` modifier on fields and functions unless necessary. Prefer `access(self)`, `acccess(Entitlement)`, or `access(contract)` and `access(account)` when other types in the contract or account need to have access.
83+
84+
<!-- Relative links, will not render on page -->
85+
86+
[Cadence Anti-Patterns]: https://cadence-lang.org/docs/design-patterns
87+
[References]: https://cadence-lang.org/docs/language/references
88+
[account storage]: https://cadence-lang.org/docs/language/accounts#account-storage
89+
[borrow]: https://cadence-lang.org/docs/language/capabilities
90+
[don't use Account references]: https://cadence-lang.org/docs/anti-patterns#avoid-using-authaccount-as-a-function-parameter
91+
[public capability storage]: https://cadence-lang.org/docs/language/capabilities
92+
[restricted types and interfaces]: https://cadence-lang.org/docs/language/restricted-types
93+
[`access(all)`]: https://cadence-lang.org/docs/language/access-control
94+
[transactions]: https://cadence-lang.org/docs/language/transactions

0 commit comments

Comments
 (0)