diff --git a/docs/design-patterns.mdx b/docs/design-patterns.mdx index 56a75f70a5..ff35d0fd47 100644 --- a/docs/design-patterns.mdx +++ b/docs/design-patterns.mdx @@ -391,7 +391,7 @@ transaction { ### Problem -An account must be given a [capability](/cadence/language/capability-based-access-control) +An account must be given a [capability](language/capability-based-access-control) to a resource or contract in another account. To create, i.e. link the capability, the transaction must be signed by a key which has access to the target account. @@ -404,7 +404,7 @@ from one account and delivering it to the other. ### Solution -The solution to the bootstrapping problem in Cadence is provided by the [Inbox API](/cadence/language/accounts#account-inbox) +The solution to the bootstrapping problem in Cadence is provided by the [Inbox API](language/accounts#account-inbox) Account A (which we will call the provider) creates the capability they wish to send to B (which we will call the recipient), and stores this capability on their account in a place where the recipient can access it using the `Inbox.publish` function on their account. diff --git a/docs/language/imports.mdx b/docs/language/imports.mdx index d9bd96e802..4beace573b 100644 --- a/docs/language/imports.mdx +++ b/docs/language/imports.mdx @@ -11,7 +11,7 @@ or it can be followed by the names of the declarations that should be imported, followed by the `from` keyword, and then followed by the location. If importing a local file, the location is a string literal, and the path to the file. -Deployment of code with file imports requires the usage for the [Flow CLI](/flow-cli). +Deployment of code with file imports requires the usage for the [Flow CLI](https://developers.flow.com/flow-cli). If importing an external type in a different account, the location is an address literal, and the address diff --git a/docs/measuring-time.mdx b/docs/measuring-time.mdx index dd7af9578d..25207644e3 100644 --- a/docs/measuring-time.mdx +++ b/docs/measuring-time.mdx @@ -25,7 +25,7 @@ and further optimizations are needed to achieve that. As of Feb 2021, the rate of block finalization on Mainnet is more than 0.5 blocks/s; with a standard deviation of ±0.1 blocks/s. Hence, a new block is finalized on average every 2 seconds. Note that block height only has a loose correlation with time, -as [the block rate naturally fluctuates](/faq/operators#does-the-blockheight-go-up-1-every-second). +as [the block rate naturally fluctuates](https://developers.flow.com/flow/faq/operators#does-the-blockheight-go-up-1-every-second). In addition to the natural variation described above, there are several theoretical block production attacks that could skew this relationship even further. diff --git a/docs/security-best-practices.mdx b/docs/security-best-practices.mdx index 0d60625600..95e006b20c 100644 --- a/docs/security-best-practices.mdx +++ b/docs/security-best-practices.mdx @@ -4,11 +4,11 @@ title: Security Best Practices This is an opinionated list of best practices Cadence developers should follow to write more secure Cadence code. -Some practices listed below might overlap with advice in the [Cadence Anti-Patterns](/cadence/design-patterns) section, which is a recommended read as well. +Some practices listed below might overlap with advice in the [Cadence Anti-Patterns](design-patterns) section, which is a recommended read as well. ## References -[References](/cadence/language/references) are ephemeral values and cannot be stored. If persistence is required, store a capability and borrow it when needed. +[References](language/references) are ephemeral values and cannot be stored. If persistence is required, store a capability and borrow it when needed. Authorized references (references with the `auth` keyword) allow downcasting, e.g. a restricted type to its unrestricted type and should only be used in some specific cases. @@ -18,9 +18,9 @@ Be aware that the subtype or unrestricted type could expose functionality that w ## Account Storage -Don't trust a users’ [account storage](/cadence/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. +Don't trust a users’ [account storage](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. -Always [borrow](/cadence/language/capability-based-access-control) with the specific type that is expected. Or, check if the value is an instance of the expected type. +Always [borrow](language/capability-based-access-control) with the specific type that is expected. Or, check if the value is an instance of the expected type. ## Auth Accounts @@ -30,7 +30,7 @@ It is preferable to use capabilities over direct `AuthAccount` storage when expo ## Capabilities -Don’t store anything under the [public capability storage](/cadence/language/capability-based-access-control) unless strictly required. Anyone can access your public capability using `AuthAccount.getCapability`. If something needs to be stored under `/public/`, make sure only read functionality is provided by restricting its type using either a resource interface or struct interface. +Don’t store anything under the [public capability storage](language/capability-based-access-control) unless strictly required. Anyone can access your public capability using `AuthAccount.getCapability`. If something needs to be stored under `/public/`, make sure only read functionality is provided by restricting its type using either a resource interface or struct interface. When linking a capability, the link might already be present. In that case, Cadence will not panic with a runtime error but the link function will return `nil`. @@ -42,7 +42,7 @@ Ensure capabilities cannot be accessed by unauthorized parties. For example, cap ## Transactions -Audits of Cadence code should also include [transactions](/cadence/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. +Audits of Cadence code should also include [transactions](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. Signing a transaction gives access to the `AuthAccount`, i.e. full access to the account’s storage, keys, and contracts. @@ -50,13 +50,13 @@ Do not blindly sign a transaction. The transaction could for example change depl ## Types -Use [restricted types and interfaces](/cadence/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. +Use [restricted types and interfaces](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. 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. ## Access Control -Declaring a field as [`pub/access(all)`](/cadence/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. +Declaring a field as [`pub/access(all)`](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. 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. diff --git a/docs/tutorial/01-first-steps.mdx b/docs/tutorial/01-first-steps.mdx index 14137b304e..1850149f30 100644 --- a/docs/tutorial/01-first-steps.mdx +++ b/docs/tutorial/01-first-steps.mdx @@ -14,11 +14,11 @@ Cadence introduces new features to smart contract programming that help develope - Type safety and a strong static type system - Resource-oriented programming, a new paradigm that pairs linear types with object capabilities to create a secure and declarative model for digital ownership by ensuring that resources (and their associated assets) can only exist in one location at a time, cannot be copied, and cannot be accidentally lost or deleted -- Built-in pre-conditions and post-conditions for functions and [transactions](/cadence/language/transactions) +- Built-in pre-conditions and post-conditions for functions and [transactions](../language/transactions) - The utilization of capability-based security, which enforces access control by requiring that access to objects is restricted to only the owner and those who have a valid reference to the object -Please see the [Cadence introduction](/cadence) for more information about the high level design of the language. +Please see the [Cadence introduction](..) for more information about the high level design of the language. ## What is the Flow Developer Playground? diff --git a/docs/tutorial/02-hello-world.mdx b/docs/tutorial/02-hello-world.mdx index 9eb0b959c1..51d780d113 100644 --- a/docs/tutorial/02-hello-world.mdx +++ b/docs/tutorial/02-hello-world.mdx @@ -51,7 +51,7 @@ without the need for any trusted third party anywhere in the process, because th Programs that run on blockchains are commonly referred to as smart contracts because they mediate important functionality (such as currency) without having to rely on a central authority (like a bank). -[Cadence is the resource-oriented programming language](/cadence) +[Cadence is the resource-oriented programming language](..) for developing smart contracts on the Flow Blockchain. This tutorial will walk you through an example of a smart contract that implements basic Cadence features, @@ -89,11 +89,11 @@ For this tutorial, you'll be working with only the first account `0x01` You will start by writing a smart contract that contains a public function that returns `"Hello World!"`. Like most other blockchains, the programming model in Flow is centered around accounts and transactions. -All state that persists permanently is stored in [accounts](/cadence/language/accounts) +All state that persists permanently is stored in [accounts](../language/accounts) and all accounts have the same core functionality. (users, smart contracts, data storage) The interfaces to this state (the ways to interact with it, otherwise known as methods or functions) are also stored in accounts. -All code execution takes place within [transactions](/cadence/language/transactions), +All code execution takes place within [transactions](../language/transactions), which are blocks of code that are authorized and submitted by external users to interact with the persistent state, which includes directly modifying account storage. @@ -156,10 +156,10 @@ You would have used `var` to declare a variable, which that the value can be cha You can use `access(all)` and the `pub` keyword interchangeably. They are both examples of an access control specification that means an interface can be accessed in all scopes, but not written to in all scopes. -For more information about the different levels of access control permitted in Cadence, refer to the [Access Control section of the language reference](/cadence/language/access-control). +For more information about the different levels of access control permitted in Cadence, refer to the [Access Control section of the language reference](../language/access-control). The `init()` section is called the initializer. It is a special function that only runs when the contract is first created. -Objects similar to contracts, such as other [composite types like structs or resources](/cadence/language/composite-types), +Objects similar to contracts, such as other [composite types like structs or resources](../language/composite-types), require that the `init()` function initialize any fields that are declared in a composite type. In the above example, the initializer sets the `greeting` field to `"Hello, World!"` when the contract is initialized. @@ -181,7 +181,7 @@ is built into the protocol by default. An account is divided into two main areas: -1. The first area is the [contract area](/cadence/language/accounts). +1. The first area is the [contract area](../language/accounts). This is the area that stores smart contracts containing type definitions, fields, and functions that relate to common functionality. There is no limit to the number of smart contracts an account can store. This area cannot be directly accessed in a transaction unless the transaction is just returning (reading) a copy of the code deployed to an account. @@ -223,7 +223,7 @@ In the Flow Playground environment there can only be one contract for each accou ### Creating a Transaction --- -A [Transaction](/cadence/language/transactions) in Flow is defined as an arbitrary-sized block of Cadence code that is authorized by one or more accounts. +A [Transaction](../language/transactions) in Flow is defined as an arbitrary-sized block of Cadence code that is authorized by one or more accounts. When an account authorizes a transaction, the code in that transaction has access to the authorizers' private storage. An account authorizes a transaction by performing a cryptographic signature on the transaction with the account's private key, which should only be accessible to the account owner. Therefore, authorizers are also known as signers. @@ -305,5 +305,5 @@ Now that you have completed the tutorial, you have the basic knowledge to write - Sign the transaction with one or multiple signers Feel free to modify the smart contract to implement different functions, -experiment with the available [Cadence types](/cadence/language/values-and-types), +experiment with the available [Cadence types](../language/values-and-types), and write new transactions that execute multiple functions from your `HelloWorld` smart contract. diff --git a/docs/tutorial/03-resources.mdx b/docs/tutorial/03-resources.mdx index c148684612..095ca0a38a 100644 --- a/docs/tutorial/03-resources.mdx +++ b/docs/tutorial/03-resources.mdx @@ -42,10 +42,10 @@ socialImageDescription: Resource smart contract image. This tutorial builds on the previous `Hello World` tutorial. Before beginning this tutorial, you should understand : -- [Accounts](/cadence/language/accounts) -- [Transactions](/cadence/language/transactions) +- [Accounts](../language/accounts) +- [Transactions](../language/transactions) - Signers -- [Field types](/cadence/language/composite-types) +- [Field types](../language/composite-types) This tutorial will build on your understanding of accounts and how to interact with them by introducing resources. Resources are one of the Cadence's defining features. @@ -71,7 +71,7 @@ To interact with resources, you'll learn a few important concepts: - Using the create keyword - The move operator `<-` -- The [Account Storage API](/cadence/language/accounts#account-storage-api) +- The [Account Storage API](../language/accounts#account-storage-api) Let's start by looking at how to create a resource with the `create` keyword and the move operator `<-`. @@ -169,8 +169,8 @@ so if the object has any fields, this function has to be used to initialize them. Contracts also have read and write access to the storage of the account that they are deployed to by using the built-in -[`self.account`](/cadence/language/contracts) object. -This is an [`AuthAccount` object](/cadence/language/accounts#authaccount) +[`self.account`](../language/contracts) object. +This is an [`AuthAccount` object](../language/accounts#authaccount) that gives them access to many different functions to interact with the private storage of the account. This contract's `init` function is simple, it logs the phrase `"Hello Asset"` to the console. @@ -192,7 +192,7 @@ The `@` symbol specifies that it is a resource, of the type `HelloAsset` which w This function uses the move operator to create a resource of type `HelloAsset` and return it To create a new resource object, we use the `create` keyword -Here we use the `<-` symbol. [This is the move operator](/cadence/language/resources#the-move-operator--). +Here we use the `<-` symbol. [This is the move operator](../language/resources#the-move-operator--). The move operator `<-` replaces the assignment operator `=` in assignments that involve resources. To make the assignment of resources explicit, the move operator `<-` must be used when: @@ -268,12 +268,12 @@ Here's what this transaction does: This is our first transaction using the `prepare` phase! The `prepare` phase is the only place that has access to the signing accounts' -[private `AuthAccount` object](/cadence/language/accounts#authaccount). +[private `AuthAccount` object](../language/accounts#authaccount). `AuthAccount` objects have many different methods that are used to interact with account storage. -You can see the documentation for all of these in the [account section of the language reference](/cadence/language/accounts#authaccount). +You can see the documentation for all of these in the [account section of the language reference](../language/accounts#authaccount). In this tutorial, we'll be using `AuthAccount` methods to save and load from `/storage/`. The `prepare` phase can also create `/private/` and `/public/` links to the objects in `/storage/`, -called [capabilities](/cadence/language/capability-based-access-control) (more on these later). +called [capabilities](../language/capability-based-access-control) (more on these later). By not allowing the execute phase to access account storage, we can statically verify which assets and areas of the signers' storage a given transaction can modify. @@ -290,9 +290,9 @@ let newHello <- HelloWorld.createHelloAsset() ``` Next, we save the resource to the account storage. -We use the [account storage API](/cadence/language/accounts#account-storage-api) to interact with the account storage in Flow. +We use the [account storage API](../language/accounts#account-storage-api) to interact with the account storage in Flow. To save the resource, we'll be using the -[`save()`](/cadence/language/accounts#account-storage-api) +[`save()`](../language/accounts#account-storage-api) method from the account storage API to store the resource in the account at the path `/storage/HelloAssetTutorial`. ```cadence @@ -399,22 +399,22 @@ Here's what this transaction does: 1. Import the `HelloWorld` definitions from account `0x01` 2. Moves the `HelloAsset` object from storage to `helloResource` with the move operator - and the `load` function from the [account storage API](/cadence/language/accounts#account-storage-api) + and the `load` function from the [account storage API](../language/accounts#account-storage-api) 3. Calls the `hello()` function of the `HelloAsset` resource stored in `helloResource` and logs the result 4. Saves the resource in the account that we originally moved it from at the path `/storage/HelloAssetTutorial` We're going to be using the `prepare` phase again to load the resource because it -has access to the signing accounts' [private `AuthAccount` object](/cadence/language/accounts#authaccount). +has access to the signing accounts' [private `AuthAccount` object](../language/accounts#authaccount). Let's go over the transaction in more detail. -To remove an object from storage, we use the `load` method from the [account storage API](/cadence/language/accounts#account-storage-api) +To remove an object from storage, we use the `load` method from the [account storage API](../language/accounts#account-storage-api) ```cadence let helloResource <- acct.load<@HelloWorld.HelloAsset>(from: /storage/HelloAssetTutorial) ``` If no object of the specified type is stored under the given path, the function returns `nil`. -(This is an [Optional](/cadence/language/values-and-types#optionals), +(This is an [Optional](../language/values-and-types#optionals), a special type of data that we will cover later) If the object at the given path is not of the specified type, Cadence will throw an error and the transaction will fail. @@ -434,7 +434,7 @@ Next, we call the `hello()` function and log the output. log(helloResource?.hello()) ``` -We use `?` because the values in the storage are returned as [optionals](/cadence/language/values-and-types#optionals). +We use `?` because the values in the storage are returned as [optionals](../language/values-and-types#optionals). Optionals are values that can represent the absence of a value. Optionals have two cases: either there is a value of the specified type, or there is nothing (`nil`). An optional type is declared using the `?` suffix. @@ -467,7 +467,7 @@ and aborts the entire transaction if the object is `nil`. It is a more risky way of dealing with optionals, but if your program is ever in a state where a value being `nil` would defeat the purpose of the whole transaction, then the force-unwrap operator might be a good choice to deal with that. -Refer to [Optionals In Cadence](/cadence/language/values-and-types#optionals) to learn more about optionals and how they are used. +Refer to [Optionals In Cadence](../language/values-and-types#optionals) to learn more about optionals and how they are used. @@ -505,12 +505,12 @@ Now that you have completed the tutorial, you have the basic knowledge to write - Use the `prepare` phase of a transaction to load resources from account storage Feel free to modify the smart contract to create different resources, -experiment with the available [account storage API](/cadence/language/accounts#account-storage-api), +experiment with the available [account storage API](../language/accounts#account-storage-api), and write new transactions and scripts that execute different functions from your smart contract. -Have a look at the [resource reference page](/cadence/language/resources) +Have a look at the [resource reference page](../language/resources) to find out more about what you can do with resources. You're on the right track to building more complex applications with Cadence, -now is a great time to check out the [Cadence Best Practices document](/cadence/design-patterns) -and [Anti-patterns document](/cadence/anti-patterns) +now is a great time to check out the [Cadence Best Practices document](../design-patterns) +and [Anti-patterns document](../anti-patterns) as your applications become more complex. diff --git a/docs/tutorial/04-capabilities.mdx b/docs/tutorial/04-capabilities.mdx index 775b24a709..a1d0f5c8f3 100644 --- a/docs/tutorial/04-capabilities.mdx +++ b/docs/tutorial/04-capabilities.mdx @@ -40,7 +40,7 @@ socialImageDescription: Capability smart contract image. This tutorial builds on the [previous `Resource` tutorial](03-resources). Before beginning this tutorial, you should have an idea of how accounts,transactions,resources, and signers work with basic field types. This tutorial will build on your understanding of accounts and resources. -You'll learn how to interact with resources using [capabilities](/cadence/language/capability-based-access-control) +You'll learn how to interact with resources using [capabilities](../language/capability-based-access-control) In Cadence, resources are a composite type like a struct or a class, but with some special rules: - Each instance of a resource can only exist in exactly one location and cannot be copied. - Resources must be explicitly moved from one location to another when accessed. @@ -123,7 +123,7 @@ stored in their accounts. (Explained more below) In this transaction, you create a new capability, then use the `link` function to create a public link to your `HelloAsset` resource object. -Next you use that link to borrow a [reference](/cadence/language/references) +Next you use that link to borrow a [reference](../language/references) to the underlying object and call the `hello()` function. A detailed explanation of what is happening in this transaction is below the transaction code so, if you feel lost, keep reading! @@ -197,12 +197,12 @@ You might be confused that we were able to call a method on the `HelloAsset` obj without actually being directly in control of it! It is also stored in the `/storage/` domain of the account, which should be private. -This is because we created a [**capability**](/cadence/language/capability-based-access-control) for the `HelloAsset` object. +This is because we created a [**capability**](../language/capability-based-access-control) for the `HelloAsset` object. Capabilities are kind of like pointers in other languages. ### Capability Based Access Control -[Capabilities](/cadence/language/capability-based-access-control) allow the owners of objects +[Capabilities](../language/capability-based-access-control) allow the owners of objects to specify what functionality of their private objects is available to others. Think of it kind of like an account's public API, if you're familiar with the concept. The account owner has private objects stored in their storage, like their collectibles or their money, @@ -265,7 +265,7 @@ let helloReference = capability.borrow() This method creates the reference as the type we specified in `<>` in the `link` function. While borrowing the reference, we use -[optional chaining](/cadence/language/composite-types#accessing-fields-and-functions-of-composite-types-using-optional-chaining) +[optional chaining](../language/composite-types#accessing-fields-and-functions-of-composite-types-using-optional-chaining) because the borrowing of the reference could fail. The reference could be `nil` if the targeted storage slot is empty, is already borrowed, or if the requested type exceeds what is allowed by the capability. @@ -279,7 +279,7 @@ Only one reference to an object can exist at a time, so this type of vulnerabili Additionally, the owner of an object can effectively revoke capabilities they have created by moving the underlying object or destroying the link with the `unlink` method. If the referenced object is moved or the link is destroyed, capabilities that have been created from that link are invalidated. -You can find more [detailed documentation about capabilities in the language reference.](/cadence/language/capability-based-access-control) +You can find more [detailed documentation about capabilities in the language reference.](../language/capability-based-access-control) Now, anyone can call the `hello()` method on your `HelloAsset` object by borrowing a reference with your public capability in `/public/Hello`! (Covered in the next section) @@ -355,14 +355,14 @@ let helloAccount = getAccount(0x01) The `PublicAccount` object is available to anyone in the network for every account, but only has access to a small subset of functions that can be read from the `/public/` domain in an account. -Most of the [account storage API](/cadence/language/accounts#account-storage-api) +Most of the [account storage API](../language/accounts#account-storage-api) is not available on the `PublicAccount` object, and only signed transactions can make persistent changes to the `AuthAccount` object. `AuthAccount` can now be accessed publicly in scripts with the `getAuthAccount` function, but any changes are discarded after the script execution. With capabilities we can make resources saved to an account explicitly available in the `/public/` domain. -See the [language reference](/cadence/language/accounts) for more information about accounts. +See the [language reference](../language/accounts) for more information about accounts. Then, the script gets the capability that was created in `Create Link`. @@ -423,11 +423,11 @@ Now that you have completed the tutorial, you have the basic knowledge to write - Interact with resources using both signed transactions and scripts Feel free to modify the smart contract to create different resources, -experiment with the available [account storage API](/cadence/language/accounts#account-storage-api), +experiment with the available [account storage API](../language/accounts#account-storage-api), and write new transactions and scripts that execute different functions from your smart contract. -Have a look at the [capability-based access control page](/cadence/language/capability-based-access-control) +Have a look at the [capability-based access control page](../language/capability-based-access-control) to find out more about what you can do with capabilities. You're on the right track to building more complex applications with Cadence, -now is a great time to check out the [Cadence Best Practices document](/cadence/design-patterns) -and [Anti-patterns document](/cadence/anti-patterns) as your applications become more complex. +now is a great time to check out the [Cadence Best Practices document](../design-patterns) +and [Anti-patterns document](../anti-patterns) as your applications become more complex. diff --git a/docs/tutorial/05-non-fungible-tokens-1.mdx b/docs/tutorial/05-non-fungible-tokens-1.mdx index 1ee2fae8d5..0ac1258096 100644 --- a/docs/tutorial/05-non-fungible-tokens-1.mdx +++ b/docs/tutorial/05-non-fungible-tokens-1.mdx @@ -51,10 +51,10 @@ Possible examples of NFTs include: CryptoKitties, Top Shot Moments, and tickets to a really fun concert. Instead of being represented in a central ledger, like in most smart contract languages, -Cadence represents each NFT as a [resource object](/cadence/language/composite-types) +Cadence represents each NFT as a [resource object](../language/composite-types) that users store in their accounts. This allows NFTs to benefit from the resource ownership rules -that are enforced by the [type system](/cadence/language/values-and-types) - +that are enforced by the [type system](../language/values-and-types) - resources can only have a single owner, they cannot be duplicated, and they cannot be lost due to accidental or malicious programming errors. These protections ensure that owners know that their NFT is safe and can represent an asset that has real value. @@ -134,7 +134,7 @@ The contract will: 2. Declare an ID field, a metadata field and an `init()` function in the NFT resource 3. Create an `init()` function for the contract that saves an NFT to an account -This contract relies on the [account storage API](/cadence/language/accounts#authaccount) to save NFTs in the +This contract relies on the [account storage API](../language/accounts#authaccount) to save NFTs in the `AuthAccount` object. --- diff --git a/docs/tutorial/05-non-fungible-tokens-2.mdx b/docs/tutorial/05-non-fungible-tokens-2.mdx index 04f6e9ddcc..a0d258cc41 100644 --- a/docs/tutorial/05-non-fungible-tokens-2.mdx +++ b/docs/tutorial/05-non-fungible-tokens-2.mdx @@ -77,7 +77,7 @@ account.save(<-myNFTs, to: /storage/basicNFTDictionary) ## Dictionaries -This example uses a [**Dictionary**: a mutable, unordered collection of key-value associations](/cadence/language/values-and-types#dictionaries). +This example uses a [**Dictionary**: a mutable, unordered collection of key-value associations](../language/values-and-types#dictionaries). ```cadence pub let myNFTs: @{Int: NFT} @@ -315,7 +315,7 @@ pub fun getIDs(): [UInt64] { ``` This can be used to iterate through the dictionary or just to see a list of what is stored. -As you can see, [a variable length array type](/cadence/language/values-and-types#arrays) +As you can see, [a variable length array type](../language/values-and-types#arrays) is declared by enclosing the member type within square brackets (`[UInt64]`). ## Resources Owning Resources @@ -339,7 +339,7 @@ and the hat can be transferred separately or along with the CryptoKitty that own In the NFT Collection, all the functions and fields are public, but we do not want everyone in the network to be able to call our `withdraw` function. This is where Cadence's second layer of access control comes in. -Cadence utilizes [capability security](/cadence/language/capability-based-access-control), +Cadence utilizes [capability security](../language/capability-based-access-control), which means that for any given object, a user is allowed to access a field or method of that object if they either: - Are the owner of the object diff --git a/docs/tutorial/06-fungible-tokens.mdx b/docs/tutorial/06-fungible-tokens.mdx index c7ccc72bb6..4d585368e6 100644 --- a/docs/tutorial/06-fungible-tokens.mdx +++ b/docs/tutorial/06-fungible-tokens.mdx @@ -292,7 +292,7 @@ If an address doesn’t have the correct resource type imported, the transaction **Important note: This protection is not in place for the Flow network currency,** **because every Flow account is initialized with a default Flow Token Vault** -**in order to pay for [storage fees and transaction fees](/flow-token/concepts#fees).** +**in order to pay for [storage fees and transaction fees](https://developers.flow.com/flow-token/concepts#fees).** ### Function Parameters @@ -442,7 +442,7 @@ Account storage is indexed with paths, which consist of a domain and identifier. Contracts have access to the private `AuthAccount` object of the account it is deployed to, using `self.account`. This object has methods that can modify storage in many ways. -See the [account](/cadence/language/accounts) documentation for a list of all the methods it can call. +See the [account](../language/accounts) documentation for a list of all the methods it can call. In this line, we call the `save` method to store an object in storage. The first argument is the value to store, and the second argument is the path where the value is being stored. @@ -519,7 +519,7 @@ Capabilities allow us to accomplish this safely. --- -Another important feature in Cadence is its utilization of [**Capability Security.**](/cadence/language/capability-based-access-control) +Another important feature in Cadence is its utilization of [**Capability Security.**](../language/capability-based-access-control) This feature ensures that while the withdraw function is declared public on the resource, no one except the intended user and those they approve of can withdraw tokens from their vault. @@ -602,7 +602,7 @@ fields private unless it is explicitly needed to be public. This is one of THE MOST COMMON security mistakes that Cadence developers make, so it is vitally important to be aware of this. - See the [Cadence Best Practices document](/cadence/anti-patterns#array-or-dictionary-fields-should-be-private) for more details. + See the [Cadence Best Practices document](../anti-patterns#array-or-dictionary-fields-should-be-private) for more details. ## Adding Interfaces to Our Fungible Token diff --git a/docs/tutorial/08-marketplace-compose.mdx b/docs/tutorial/08-marketplace-compose.mdx index a45024b637..c2990a3694 100644 --- a/docs/tutorial/08-marketplace-compose.mdx +++ b/docs/tutorial/08-marketplace-compose.mdx @@ -37,10 +37,10 @@ we can build a marketplace that uses both. This is referred to as **composabilit the ability for developers to leverage shared resources, such as code or userbases, and use them as building blocks for new applications. Flow is designed to enable composability because of the way that interfaces, resources and capabilities are designed. -[Interfaces](/cadence/language/interfaces) allow projects to support any generic type as long as it supports a standard set of functionality specified by an interface. -[Resources](/cadence/language/resources) can be passed around and owned by accounts, contracts or even other resources, +[Interfaces](../language/interfaces) allow projects to support any generic type as long as it supports a standard set of functionality specified by an interface. +[Resources](../language/resources) can be passed around and owned by accounts, contracts or even other resources, unlocking different use-cases depending on where the resource is stored. -[Capabilities](/cadence/language/capability-based-access-control) allow exposing user-defined sets of functionality through special objects +[Capabilities](../language/capability-based-access-control) allow exposing user-defined sets of functionality through special objects that enforce strict security with Cadence's type system. The combination of these allows developers to do more with less, re-using known safe code and design patterns to create new, powerful, and unique interactions! @@ -387,7 +387,7 @@ This contract has a few new features and concepts that are important to cover: ### Events -[Events](/cadence/language/events) are special values that can be emitted during the execution of a program. +[Events](../language/events) are special values that can be emitted during the execution of a program. They usually contain information to indicate that some important action has happened in a smart contract, such as an NFT transfer, a permission change, or many other different things. Off-chain applications can monitor events using a Flow SDK to know what is happening on-chain without having to query a smart contract directly. @@ -395,7 +395,7 @@ Off-chain applications can monitor events using a Flow SDK to know what is happe Many applications want to maintain an off-chain record of what is happening on-chain so they can have faster performance when getting information about their users' accounts or generating analytics. -Events are declared by indicating [the access level](/cadence/language/access-control), `event`, +Events are declared by indicating [the access level](../language/access-control), `event`, and the name and parameters of the event, like a function declaration: ```cadence pub event ForSale(id: UInt64, price: UFix64, owner: Address?) @@ -412,13 +412,13 @@ External applications can monitor the blockchain to take action when certain eve ### Resource-Owned Capabilities -We have covered capabilities in previous [tutorials](/cadence/tutorial/04-capabilities), +We have covered capabilities in previous [tutorials](04-capabilities), but only the basics. Capabilities can be used for so much more! -As you hopefully understand, [capabilites](/cadence/language/capability-based-access-control) +As you hopefully understand, [capabilites](../language/capability-based-access-control) are links to private objects in account storage that specify subset of functionality to expose. -To create a capability, a user typically uses [the `AuthAccount.link`](/cadence/language/accounts#authaccount) +To create a capability, a user typically uses [the `AuthAccount.link`](../language/accounts#authaccount) method to create a link to a resource in their private storage, specifying a type to link the capability as: ```cadence // Create a public Receiver + Balance capability to the Vault @@ -429,7 +429,7 @@ acct.link<&ExampleToken.Vault{ExampleToken.Receiver, ExampleToken.Balance}> (/public/CadenceFungibleTokenTutorialReceiver, target: /storage/CadenceFungibleTokenTutorialVault) ``` -Then, users can get that capability if it was created [in a public path](/cadence/language/accounts#paths), +Then, users can get that capability if it was created [in a public path](../language/accounts#paths), borrow it, and access the functionality that the owner specified. ```cadence