diff --git a/docs/tutorials/developer-journey/index.md b/docs/tutorials/developer-journey/index.md index 6a900cbbb1..83a9a99605 100644 --- a/docs/tutorials/developer-journey/index.md +++ b/docs/tutorials/developer-journey/index.md @@ -8,7 +8,7 @@ The developer journey is designed to give both new and existing developers a cle :::info -In this developer journey, we focus on developing canisters and applications using Motoko. In the future, there will be additional variations of the developer journey that focus on different developer paths, such as: +This developer journey will focus on developing canisters and applications using Motoko. In the future, there will be additional variations of the developer journey that focus on different developer paths, such as: - Rust development. - ckBTC-focused development. diff --git a/docs/tutorials/developer-journey/level-0/01-ic-overview.md b/docs/tutorials/developer-journey/level-0/01-ic-overview.md index 00e586d79f..fc25f5218f 100644 --- a/docs/tutorials/developer-journey/level-0/01-ic-overview.md +++ b/docs/tutorials/developer-journey/level-0/01-ic-overview.md @@ -8,7 +8,7 @@ The **Internet Computer (IC)** is a secure and transparent blockchain-based netw Dapps are created by the development and deployment of **smart contracts**, which are known as **canisters** on the IC. Each canister is hosted on an independent blockchain network running on **nodes** called a **subnet**. -We'll dive into these terms a bit further in the next section, [Internet Computer terminology](02-ic-terms.md). +These terms will be explained a bit further in the next section, [Internet Computer terminology](02-ic-terms.md). In order to understand how to develop dapps on the IC, first let's take a look at the architecture of the IC and how it functions. diff --git a/docs/tutorials/developer-journey/level-0/03-dev-env.md b/docs/tutorials/developer-journey/level-0/03-dev-env.md index 61a2209c80..1f7e672ba1 100644 --- a/docs/tutorials/developer-journey/level-0/03-dev-env.md +++ b/docs/tutorials/developer-journey/level-0/03-dev-env.md @@ -2,7 +2,7 @@ ## Overview -Before we can begin our developer journey, we need to set up our developer environment. A developer environment consists of tools and packages that are required to develop code projects. Usually, developer environments are stored and hosted on your local computer, but there are some situations where a virtual, web-based development environment exists. +Before you can begin our developer journey, you need to set up our developer environment. A developer environment consists of tools and packages that are required to develop code projects. Usually, developer environments are stored and hosted on your local computer, but there are some situations where a virtual, web-based development environment exists. An example of this is the [Motoko Playground](https://m7sm4-2iaaa-aaaab-qabra-cai.ic0.app/), which is a web-based, virtual developer environment that can be used by developers without having to set up a local environment. The Motoko Playground has several restrictions, however, and it isn't recommended to be used for workflows other than simple, small-scale testing. @@ -22,7 +22,7 @@ Open a command line interface (CLI) window. This may be referred to as 'Terminal #### Why does this matter? -We will primarily be using CLI-based tools, such as `dfx` and `git`, in this developer journey. +You will primarily be using CLI-based tools, such as `dfx` and `git`, in this developer journey. #### Options for Windows users @@ -62,7 +62,7 @@ The IC SDK is composed of several components that are required for developing on To write and edit code, you will need a code editor. macOS and Linux systems come with some basic editors, such as `vi` or `nano`, but these have very limited functionality and can be hard to use. -We recommend you use [Visual Studio Code](https://code.visualstudio.com/download), as it is a popular choice and there is a [Motoko extension](https://github.com/dfinity/vscode-motoko) that provides additional tools for Motoko development. +It is recommended that you use [Visual Studio Code](https://code.visualstudio.com/download), as it is a popular choice and there is a [Motoko extension](https://github.com/dfinity/vscode-motoko) that provides additional tools for Motoko development. #### Why does this matter? @@ -74,7 +74,7 @@ Download and install [git](https://git-scm.com/downloads). #### Why does this matter? -Many of the DFINITY public repositories are hosted on Github, such as our `examples` repository. We will be using code from this repository later in the developer journey, so it is important to install `git` to assure that you can download the sample code pieces and follow along with the later tutorials. +Many of the DFINITY public repositories are hosted on Github, such as our `examples` repository. You will be using code from this repository later in the developer journey, so it is important to install `git` to assure that you can download the sample code pieces and follow along with the later tutorials. ### Download and install Node.js @@ -82,7 +82,7 @@ Download and install [node.js](https://nodejs.org/en). #### Why does this matter? -Node.js is used by `dfx` to generate frontend code and dependencies. It is not required for dapps that do not contain a frontend interface, though it is required for you to follow along with this developer journey series, since we will explore frontend canisters in a later tutorial. +Node.js is used by `dfx` to generate frontend code and dependencies. It is not required for dapps that do not contain a frontend interface, though it is required for you to follow along with this developer journey series, since you will explore frontend canisters in a later tutorial. ### Assure all packages and tools are updated to the latest release versions @@ -95,17 +95,17 @@ Having the latest release version assures that you have all of the newest featur ### Create a working directory -The last step in setting up our developer environment is to create a new directory for us to build in. You can create a new directory with the command: +The last step in setting up our developer environment is to create a new directory for you to build in. You can create a new directory with the command: ``` mkdir developer_journey ``` -In future modules, we'll refer to this directory as the **working directory**. Each project that we create will be a *sub-directory* of this working directory. +In future modules, you'll refer to this directory as the **working directory**. Each project that you create will be a *sub-directory* of this working directory. #### Why does this matter? -We'll use this working directory to contain the projects that we build throughout our developer journey. This will help keep things organized in our local file structure. +You'll use this working directory to contain the projects that you build throughout your developer journey. This will help keep things organized in our local file structure. ## Need help? diff --git a/docs/tutorials/developer-journey/level-0/04-intro-canisters.md b/docs/tutorials/developer-journey/level-0/04-intro-canisters.md index 67fbc18469..bb23a1f576 100644 --- a/docs/tutorials/developer-journey/level-0/04-intro-canisters.md +++ b/docs/tutorials/developer-journey/level-0/04-intro-canisters.md @@ -16,7 +16,7 @@ A canister differs from a container, however, in the fact that a canister also s Canisters can be developed in a variety of languages, such as Rust, JavaScript, Python, and TypeScript, though the primary language for canister development is **Motoko**, since Motoko has been developed specifically for canister development on the IC. -We'll dive further into Motoko and other languages in the next section, [introduction to languages](05-intro-languages.md). +You'll dive further into Motoko and other languages in the next section, [introduction to languages](05-intro-languages.md). ### Actors diff --git a/docs/tutorials/developer-journey/level-0/06-intro-dfx.md b/docs/tutorials/developer-journey/level-0/06-intro-dfx.md index 99ef31f00d..a5e5289e82 100644 --- a/docs/tutorials/developer-journey/level-0/06-intro-dfx.md +++ b/docs/tutorials/developer-journey/level-0/06-intro-dfx.md @@ -4,7 +4,7 @@ `dfx` is a command line utility that is used to interact with the IC SDK. It is the primary tool that is used for creating, managing, and deploying dapps onto the Internet Computer. -The `dfx` parent command has several flags and subcommands that can be used to perform a wide array of operations. First, we'll take a look at basic usage of the command, then we'll get started creating our first project using dfx. +The `dfx` parent command has several flags and subcommands that can be used to perform a wide array of operations. First, you'll take a look at basic usage of the command, then you'll get started creating your first project using dfx. ## Basic usage @@ -16,7 +16,7 @@ dfx [subcommand] [flag] ### Subcommands -The following is a list of the essential `dfx` subcommands that we'll be using throughout the developer journey series. For the full list of all possible subcommands, check out the [dfx reference documentation](/docs/references/cli-reference/dfx-parent.md). +The following is a list of the essential `dfx` subcommands that you'll be using throughout the developer journey series. For the full list of all possible subcommands, check out the [dfx reference documentation](/docs/references/cli-reference/dfx-parent.md). - `build`: Used to build the canister output from the project's source code. - `canister`: Used to manage deployed canisters. @@ -42,7 +42,7 @@ The following is a list of the essential `dfx` subcommands that we'll be using t ### Options -Below are the essential options that we'll be referencing throughout the developer journey. For the full list of options, see the [reference documentation](/docs/references/cli-reference/dfx-parent.md). +Below are the essential options that you'll be referencing throughout the developer journey. For the full list of options, see the [reference documentation](/docs/references/cli-reference/dfx-parent.md). - `--identity `: Used to specify the user identity to be used with the command. - `--logfile `: Used to write the command's output logs to a specific file. @@ -67,7 +67,7 @@ DFX_VERSION=0.14.1 sh -ci "$(curl -sSL https://internetcomputer.org/install.sh)" All dapps on the IC start off as **projects**. Projects are created using the `dfx` command and subcommands. -To get started, we'll use the default sample app to demonstrate how to create a project and explore the default project structure that is generated when a new project is created. +To get started, you'll use the default sample app to demonstrate how to create a project and explore the default project structure that is generated when a new project is created. ### Step 1: Open a terminal window on your local computer. @@ -81,7 +81,7 @@ dfx new hello_world When no flags are used, the `dfx new` command will create a new project using the default Motoko template. To create a project using the Rust project template, the flag `--type=rust` should be included in the command. -In this developer journey, we will be using Motoko for our development language, so we do not need to pass any additional flags with this command. +In this developer journey, you will be using Motoko for our development language, so you do not need to pass any additional flags with this command. :::info When creating new projects with `dfx`, only alphanumeric characters and underscores should be used. This is to assure that project names are valid within Motoko, JavaScript, and other contexts. @@ -179,7 +179,7 @@ Let's explore these settings a bit further: ## Reviewing the default program code -Now that we've explored the default project structure, let's take a look at the default program code located in the `main.mo` file. This is located in the `src/hello_world_backend` directory. We will cover frontend development and the default files located in the frontend canister directory in a later tutorial. +Now that you've explored the default project structure, let's take a look at the default program code located in the `main.mo` file. This is located in the `src/hello_world_backend` directory. The developer journey will cover frontend development and the default files located in the frontend canister directory in a later tutorial. New Motoko projects will always include a default, template `main.mo` file. To take a look at the file's default contents, open the `src/hello_world_backend/main.mo` file in a code or text editor. The code will resemble the following: @@ -198,7 +198,7 @@ In this simple 'Hello, world' program, there are a few key elements: - Then, the program uses an async keyword to indicate that the program will return an async message that consists of text string that is constructed using "Hello, ", the # operator, the name argument, and "!". -We'll explore actor objects, classes, and asynchronous messages in a future tutorial. For now, this will wrap up our introduction to `dfx`. +You'll explore actor objects, classes, and asynchronous messages in a future tutorial. For now, this will wrap up our introduction to `dfx`. ## Need help? diff --git a/docs/tutorials/developer-journey/level-0/index.md b/docs/tutorials/developer-journey/level-0/index.md index ce9571ed47..ce7d6a05c7 100644 --- a/docs/tutorials/developer-journey/level-0/index.md +++ b/docs/tutorials/developer-journey/level-0/index.md @@ -53,7 +53,7 @@ - Ledger. - Motoko. -- [0.3 Developer environment setup](03-dev-env.md): Before we can begin our developer journey, we need to set up our developer environment. A developer environment is comprised of tools and packages that are required to develop code projects. This module covers: +- [0.3 Developer environment setup](03-dev-env.md): Before you can begin our developer journey, you need to set up our developer environment. A developer environment is comprised of tools and packages that are required to develop code projects. This module covers: - Setting up a developer environment: - Confirming an internet connection. - Confirming access to a CLI. @@ -78,7 +78,7 @@ - Canister controllers. - Cycles and resource charges. -- [0.5 Introduction to languages](05-intro-languages.md): In this page, we discuss the different languages that can be used to develop dapps, and provide a base-level introduction to the two primarily supported languages: Motoko and Rust. This module covers: +- [0.5 Introduction to languages](05-intro-languages.md): This page discusses the different languages that can be used to develop dapps, and provide a base-level introduction to the two primarily supported languages: Motoko and Rust. This module covers: - Motoko. - Motoko's attributes. - Rust. diff --git a/docs/tutorials/developer-journey/level-1/1.1-live-demo.md b/docs/tutorials/developer-journey/level-1/1.1-live-demo.md index 30dc9f30d7..18a2ef02de 100644 --- a/docs/tutorials/developer-journey/level-1/1.1-live-demo.md +++ b/docs/tutorials/developer-journey/level-1/1.1-live-demo.md @@ -2,9 +2,9 @@ ## Overview -In the previous segment of our developer journey, introduction to `dfx`, we created a new `dfx` project using the default 'Hello, world' template and looked into the project's structure and code. However, we didn't build or deploy the canister. +In the previous segment of our developer journey, introduction to `dfx`, you created a new `dfx` project using the default 'Hello, world' template and looked into the project's structure and code. However, you didn't build or deploy the canister. -In this tutorial, we'll deploy the `hello_world_backend` canister from [0.6: Introduction to dfx](../level-0/06-intro-dfx.md) to the Motoko playground. +In this tutorial, you'll deploy the `hello_world_backend` canister from [0.6: Introduction to dfx](../level-0/06-intro-dfx.md) to the Motoko playground. ## What is the Motoko playground? @@ -29,13 +29,13 @@ Since the playground is designed for testing purposes, there are several restric Using the `dfx` command `dfx deploy --playground`, canisters can be deployed directly from the CLI to the Motoko playground. -First, let's take a look at how to use this command to deploy our canister. Then we'll explore how we can interact with that canister once it has been deployed. This will act as a live demo for us to explore and use to gain an understanding of the deployment and interaction process. +First, let's take a look at how to use this command to deploy our canister. Then you'll explore how you can interact with that canister once it has been deployed. This will act as a live demo for you to explore and use to gain an understanding of the deployment and interaction process. ### Prerequisites Before you start, verify that you have set up your developer environment according to the instructions in [0.3: Developer environment setup](../level-0/03-dev-env.md). -This example works with the canister previously created in the [0.6: Introduction to dfx](../level-0/06-intro-dfx.md) module. We recommend completing that module before beginning the steps outlined here. +This example works with the canister previously created in the [0.6: Introduction to dfx](../level-0/06-intro-dfx.md) module. It is recommended to complete that module before beginning the steps outlined here. ### Deploying to the playground using `dfx` @@ -45,7 +45,7 @@ This example works with the canister previously created in the [0.6: Introductio To deploy a canister to the playground network, first open a terminal window if you do not already have one open. -Then, navigate into the project that we created in the [0.6: Introduction to dfx](../level-0/06-intro-dfx.md) module. You can use a command such as: +Then, navigate into the project that you created in the [0.6: Introduction to dfx](../level-0/06-intro-dfx.md) module. You can use a command such as: ```sh cd developer_journey @@ -55,7 +55,7 @@ For more information on file system navigation using the CLI, check out the docu For a review on the project's structure and our `main.mo` source code file, you can review the [0.6: Introduction to dfx](../level-0/06-intro-dfx.md) module. -Before we can deploy the canister, we need to start the local execution environment. To do this, run the command: +Before you can deploy the canister, you need to start the local execution environment. To do this, run the command: ```sh dfx start --clean --background @@ -72,7 +72,7 @@ dfx deploy developer_journey_backend --playground ``` :::info -This command deploys just the backend canister, since that will be the canister we're focused on. To deploy all canisters listed in the `dfx.json` file, which by default includes a frontend canister in addition to the backend canister, you can use the `dfx deploy --playground` command without specifying the canister's name. +This command deploys just the backend canister, since that will be the canister you're focused on. To deploy all canisters listed in the `dfx.json` file, which by default includes a frontend canister in addition to the backend canister, you can use the `dfx deploy --playground` command without specifying the canister's name. ::: The output of this command will resemble the following: @@ -88,7 +88,7 @@ URLs: Once deployed, the canister can be interacted with from the command line, or from the URL shown in the output above that refers to the backend canister's Candid interface. First, let's look at using the command line. -If you recall from the [0.6: Introduction to dfx](../level-0/06-intro-dfx.md) module, our canister has a single method called `greet`, which we can call using a command such as: +If you recall from the [0.6: Introduction to dfx](../level-0/06-intro-dfx.md) module, our canister has a single method called `greet`, which you can call using a command such as: ```sh dfx canister --network playground call developer_journey_backend greet '("everyone")' @@ -102,7 +102,7 @@ As a result, the canister should return the following reply: ("Hello, everyone!") ``` -You can change the text portion to anything you'd like to test the method further. For example, instead of 'everyone', we can pass 'developers' into the method, such as: +You can change the text portion to anything you'd like to test the method further. For example, instead of 'everyone', you can pass 'developers' into the method, such as: ```sh dfx canister --network playground call developer_journey_backend greet '("developers")' @@ -164,6 +164,6 @@ Did you get stuck somewhere in this tutorial, or feel like you need additional h ## Next steps -Now that we've explored a live canister deployed on the Motoko playground, we'll move onto developing our own dapp rather than using the default template files. But first, let's go over the basics of Motoko in Motoko level 1. +Now that you've explored a live canister deployed on the Motoko playground, you'll move onto developing your own dapp rather than using the default template files. But first, let's go over the basics of Motoko in Motoko level 1. - [1.2 Motoko level 1](1.2-motoko-lvl1.md). diff --git a/docs/tutorials/developer-journey/level-1/1.2-motoko-lvl1.md b/docs/tutorials/developer-journey/level-1/1.2-motoko-lvl1.md index d62c077fbf..0b115af5de 100644 --- a/docs/tutorials/developer-journey/level-1/1.2-motoko-lvl1.md +++ b/docs/tutorials/developer-journey/level-1/1.2-motoko-lvl1.md @@ -2,13 +2,13 @@ ## Overview -Motoko is a programming language that has been developed and optimized for creating programs built on the Internet Computer. In this module, we'll cover the fundamental basics of Motoko that we'll use when we build our [first dapp](1.3-first-dapp.md). +Motoko is a programming language that has been developed and optimized for creating programs built on the Internet Computer. In this module, you'll cover the fundamental basics of Motoko that you'll use when you build your [first dapp](1.3-first-dapp.md). ## Basic concepts and terms -In previous modules, we've introduced and briefly discussed actors, and how each canister smart contract is represented by an actor. Within Motoko, the term actor is used to refer to any canister, regardless of the canister's language (Motoko, Rust, etc.). Motoko is designed specifically to make actors easy to write and use once the canister has been deployed. +In previous modules, you've been introduced to and briefly discussed actors, and how each canister smart contract is represented by an actor. Within Motoko, the term actor is used to refer to any canister, regardless of the canister's language (Motoko, Rust, etc.). Motoko is designed specifically to make actors easy to write and use once the canister has been deployed. -With actors in mind, the following terms and concepts are essential to be aware of. Many of these concepts apply to several different programming languages, though we'll be focusing on their application within Motoko. +With actors in mind, the following terms and concepts are essential to be aware of. Many of these concepts apply to several different programming languages, though you'll be focusing on their application within Motoko. - **Declaration:** A declaration in Motoko is used to define immutable variables, mutable state, objects, actors, classes, and other data types. @@ -24,7 +24,7 @@ With actors in mind, the following terms and concepts are essential to be aware ## Motoko syntax -Motoko's program syntax uses declarations and expressions. Programs consist of an actor expression that is introduced using the keyword `actor`. To introduce the Motoko syntax, first we'll use small code snippets that do not define entire programs, but rather some simple printed terminal output. +Motoko's program syntax uses declarations and expressions. Programs consist of an actor expression that is introduced using the keyword `actor`. To introduce the Motoko syntax, first you'll use small code snippets that do not define entire programs, but rather some simple printed terminal output. For example, the following code snippet consists of two **declarations** for the variables `x` and `y`, followed by an **expression**. This forms a single **program**. @@ -34,9 +34,9 @@ let y = x + 1; /// declaration x * y + x; /// expression ``` -In this snippet, the program's type is `Nat` (natural number), since when the program is run, the result value is a `Nat` value of 3. We dive into value types in [values](#values-and-evaluation). +In this snippet, the program's type is `Nat` (natural number), since when the program is run, the result value is a `Nat` value of 3. This tutorial series will dive into value types in [values](#values-and-evaluation). -Now, let's build upon this small snippet. If we introduce a block with enclosing braces `do {` and `}` and another variable `z`, we can amend our original program as follows: +Now, let's build upon this small snippet. If you introduce a block with enclosing braces `do {` and `}` and another variable `z`, you can amend your original program as follows: ```motoko let z = do { @@ -58,7 +58,7 @@ The base library includes a selection of modules that focus on the core features To import the base library, the `import` keyword can be used at the start of your Motoko code file. After the `import` keyword, you need to provide a **local module name** and a **file path** that the import declaration can use to locate the imported module. -For example, to import a local module named 'Debug', we can use the following import statement: +For example, to import a local module named 'Debug', you can use the following import statement: ```motoko import Debug "mo:base/Debug"; @@ -70,7 +70,7 @@ Then, to use this imported library, you can call the module with a line of code Debug.print("hello world"); ``` -In this demonstration, we import Motoko code, indicated by the `mo:` prefix, then specify the `base/` path indicating that we are using the base library, followed by the module's file name, `Debug.mo`. Note that the `.mo` extension is not included in the import statement. +In this demonstration, you import Motoko code, indicated by the `mo:` prefix, then specify the `base/` path indicating that you are using the base library, followed by the module's file name, `Debug.mo`. Note that the `.mo` extension is not included in the import statement. Additionally, you can import Motoko code and other modules using their relative paths. For example, if you have a Motoko program named `types.mo` that you'd like to import into your Motoko file, you can use the following import declaration: @@ -112,11 +112,11 @@ let x = 42 + (1 * 37) / 12: Nat This program results to the value 45, also of type `Nat`. -Expressions can also be formed using a **block**. We can form a block expression from our list of declarations by enclosing it within curly brackets `{}`. A block expression is used to preserve the autonomy of the declaration list and the variable's names. +Expressions can also be formed using a **block**. You can form a block expression from your list of declarations by enclosing it within curly brackets `{}`. A block expression is used to preserve the autonomy of the declaration list and the variable's names. -Blocks are only allowed as sub-expressions of **control flow expressions**. Control flow expressions are programming methods such as `if`, `loop`, `case`, etc. In any other place, we can use `do { ... }` to represent block expressions and distinguish blocks from object literals. +Blocks are only allowed as sub-expressions of **control flow expressions**. Control flow expressions are programming methods such as `if`, `loop`, `case`, etc. In any other place, you can use `do { ... }` to represent block expressions and distinguish blocks from object literals. -So, going back to our example, since there are no control flow expressions in our program, such as `if` or `loop`, we must use the `do { ... }` expression: +So, going back to the example, since there are no control flow expressions in our program, such as `if` or `loop`, you must use the `do { ... }` expression: ```motoko do { @@ -126,9 +126,9 @@ do { } ``` -Using the `do { ... }` expression allows our code to remain a functioning program, but now our declared variables `x` and `y` are privately scoped within the block expression we have defined. +Using the `do { ... }` expression allows our code to remain a functioning program, but now our declared variables `x` and `y` are privately scoped within the block expression you have defined. -Next, we can use a block expression to produce a value within a larger, compound expression, such as: +Next, you can use a block expression to produce a value within a larger, compound expression, such as: ```motoko 100 + @@ -139,7 +139,7 @@ Next, we can use a block expression to produce a value within a larger, compound }) ``` -We can see that nesting blocks preserves the autonomy of each separate declaration list and its variable names. Language theorists refer to this as **lexical scoping**, where variables' scopes may nest, but do not interfere with one another as they nest. +You can see that nesting blocks preserves the autonomy of each separate declaration list and its variable names. Language theorists refer to this as **lexical scoping**, where variables' scopes may nest, but do not interfere with one another as they nest. To further demonstrate this, consider the following example: @@ -159,7 +159,7 @@ Aside from program clarity, the brief benefit of lexical scoping is program secu ## Defining an actor -In our previous examples, we've just demonstrated syntax using simple declaration and expression lines; however, to encapsulate our code within a smart contract, we need to define an actor that will house the code. +In the previous examples, you've just demonstrated syntax using simple declaration and expression lines; however, to encapsulate our code within a smart contract, you need to define an actor that will house the code. Recall from our previous modules that an actor is *a process with encapsulated state that communicates with other running actors*. @@ -191,7 +191,7 @@ actor { ## Values and evaluation -In our previous examples, we explored expressions that produced natural numbers (value type `Nat`). There are several other value forms, which we'll dive deeper into now. +In the previous examples, you explored expressions that produced natural numbers (value type `Nat`). There are several other value forms, which you'll dive deeper into now. ### Primitive values @@ -225,7 +225,7 @@ Additionally, Motoko supports the following user-defined non-primitive value for ## Printing values -Earlier, recall that we printed a value using the imported `Debug` library: +Earlier, recall that you printed a value using the imported `Debug` library: ```motoko import Debug "mo:base/Debug"; @@ -265,7 +265,7 @@ public func location(city : Text) : async Text { }; ``` -In this example, we define a single actor with the function `location`, which accepts a `Text` input for the value of `city`. Then, it returns the output 'Hello, `city`!". +In this example, you define a single actor with the function `location`, which accepts a `Text` input for the value of `city`. Then, it returns the output 'Hello, `city`!". If this example is used in a live canister, the canister can be called and an input text argument can be passed to the function, such as: @@ -313,7 +313,7 @@ Did you get stuck somewhere in this tutorial, or feel like you need additional h ## Next steps -Now that we've covered the basics of Motoko, let's put these concepts all together in practice by developing our first dapp! +Now that you've covered the basics of Motoko, let's put these concepts all together in practice by developing your first dapp! - [1.3 Developing your first dapp](1.3-first-dapp.md). diff --git a/docs/tutorials/developer-journey/level-1/1.3-first-dapp.md b/docs/tutorials/developer-journey/level-1/1.3-first-dapp.md index 7e4a8176f9..915e754857 100644 --- a/docs/tutorials/developer-journey/level-1/1.3-first-dapp.md +++ b/docs/tutorials/developer-journey/level-1/1.3-first-dapp.md @@ -2,9 +2,9 @@ ## Overview -At this point in our developer journey, we've covered the fundamentals of canister development and deployed the default 'Hello, world' project template on the Motoko playground. It's time to get into writing code and developing our own first dapp! +At this point in your developer journey, you've covered the fundamentals of canister development and deployed the default 'Hello, world' project template on the Motoko playground. It's time to get into writing code and developing your own first dapp! -For this tutorial, we'll be creating a poll dapp that includes both a backend canister and a frontend canister. To recap, backend canisters are used to host the dapp's smart contract code, while frontend canisters are used to host user interface assets, such as HTML and CSS. +For this tutorial, you'll be creating a poll dapp that includes both a backend canister and a frontend canister. To recap, backend canisters are used to host the dapp's smart contract code, while frontend canisters are used to host user interface assets, such as HTML and CSS. The poll dapp will ask the end user a question, then have them vote on which answer they'd like to select. @@ -14,7 +14,7 @@ Before you start, verify that you have set up your developer environment accordi ## Creating a new project -First, we need to create a new `dfx` project. Open a terminal window, navigate into your working directory (`developer_journey`), then use the commands: +First, you need to create a new `dfx` project. Open a terminal window, navigate into your working directory (`developer_journey`), then use the commands: ``` dfx start --clean --background @@ -37,7 +37,7 @@ poll # The root of the project ├── package.json # Node.js package configuration ├── src │   ├── poll_backend # Folder containing the source code of your dapp's backend. -│   │   └── main.mo # The default source code file; this is what we'll primarily be working with in this tutorial. +│   │   └── main.mo # The default source code file; this is what you'll primarily be working with in this tutorial. │   └── poll_frontend # Folder containing the frontend configuration and assets of your dapp. │   └── ... └── webpack.config.js # Web dapp bundler configuration. @@ -51,11 +51,11 @@ This file structure is the default template `dfx` creates for a new project. If ## Writing the backend canister code -Let's start writing the code for the backend of our dapp. Open your code editor of choice, then open the file `src/poll_backend/main.mo`. By default, this file will contain the same code we reviewed in the [introduction to dfx](../level-0/06-intro-dfx.md) module. Since we want to write our own code, delete the entire contents of this file. +Let's start writing the code for the backend of our dapp. Open your code editor of choice, then open the file `src/poll_backend/main.mo`. By default, this file will contain the same code you reviewed in the [introduction to dfx](../level-0/06-intro-dfx.md) module. Since you want to write your own code, delete the entire contents of this file. ### Creating an actor -First, we'll create an actor. Recall that an actor is a process with an encapsulated state. Actors contain both code and data, and communicate by sending and receiving messages. A canister can only contain a single actor. +First, you'll create an actor. Recall that an actor is a process with an encapsulated state. Actors contain both code and data, and communicate by sending and receiving messages. A canister can only contain a single actor. In your `src/poll_backend/main.mo` file, paste the following code: @@ -73,7 +73,7 @@ actor { This code defines an actor, but it is currently empty. It does not define any data or send and receive messages. -Next, let's add some code inside the actor that proposes a question for our poll app. For example, we can ask the user, "What is your favorite programming language?". +Next, let's add some code inside the actor that proposes a question for your poll app. For example, you can ask the user, "What is your favorite programming language?". To add this question, insert the following code inside of the actor definition: @@ -93,7 +93,7 @@ First, it creates a new actor variable called `question`. Then, it declares the type of this variable as `Text`, which is the standard type for strings in Motoko. ::: -Since we are using the type `Text`, we need to import the type `Text` from the Motoko base library. To do this, add an import statement at the top of the file: +Since you are using the type `Text`, you need to import the type `Text` from the Motoko base library. To do this, add an import statement at the top of the file: ``` import Text "mo:base/Text"; @@ -116,9 +116,9 @@ actor { Now, our code has an actor with one fixed variable and no methods. -For our next step, we'll add access methods. This is because in order to communicate with other canisters or any other external entity, actors must send and receive messages. +For our next step, you'll add access methods. This is because in order to communicate with other canisters or any other external entity, actors must send and receive messages. -Specifically for our poll, we want to create the following functionality: +Specifically for your poll, you want to create the following functionality: - Obtain the current poll question. - Receive a list of possible options that can be voted on. @@ -127,7 +127,7 @@ Specifically for our poll, we want to create the following functionality: ### Defining the `getQuestion` method -Let's start with the first functionality; obtain the current poll question. To do this, we'll create the `getQuestion` method using the following code: +Let's start with the first functionality; obtain the current poll question. To do this, you'll create the `getQuestion` method using the following code: :::caution The following example is a **code snippet** that is part of a larger code file. This snippet may return an error if run on its own. To view the full code file that should be run, please see [final code](#final-code). @@ -145,8 +145,8 @@ public query func getQuestion() : async Text { This `getQuestion` method takes the current value of the `question` variable and returns it to the caller. There are some important things regarding methods and their behavior to be aware of, such as: - All methods that return values on the IC have to be declared as `async` in order to allow asynchronous execution. -- Since the `getQuestion` method doesn't change any data, it can be declared as a `query` call. We'll dive further into this shortly. -- This method uses the `Text` type that we previously have already imported at the top of the file. +- Since the `getQuestion` method doesn't change any data, it can be declared as a `query` call. you'll dive further into this shortly. +- This method uses the `Text` type that you previously have already imported at the top of the file. ::: ### Query calls vs. update calls @@ -183,7 +183,7 @@ actor { ### Creating a data structure to store the data -In our poll, we will be storing each poll option and a number associated with how many votes each option has. This collection of data will be in the form of a *key-value store*. In other languages, this data structure is known as a "dictionary" or a "map". In Motoko, this data structure is called an [`RBTree`](/motoko/main/base/RBTree.md). +In your poll, you will be storing each poll option and a number associated with how many votes each option has. This collection of data will be in the form of a *key-value store*. In other languages, this data structure is known as a "dictionary" or a "map". In Motoko, this data structure is called an [`RBTree`](/motoko/main/base/RBTree.md). `RBTree` maps a **vote option** of type `Text` to a **vote count** of type `Nat`. `Text` is a data type for string text values, and `Nat` is a data type for natural numbers, which are whole numbers without decimal points. @@ -200,11 +200,11 @@ For example, the data structure for our "What is your favorite programming langu ### Importing additional dependencies -In order to store and query the `RBTree` data structure, we need to import a few different things. These are: +In order to store and query the `RBTree` data structure, you need to import a few different things. These are: -- To use `RBTree`, we need to import `RBTree`. -- To use `Nat` data types, we need to import `Nat`. -- Later in this tutorial we will use `Iter`, which we will import now so that it is ready to use later. +- To use `RBTree`, you need to import `RBTree`. +- To use `Nat` data types, you need to import `Nat`. +- Later in this tutorial you will use `Iter`, which you will import now so that it is ready to use later. To import these packages, add the following import statements to the beginning of the `main.mo` file: @@ -215,7 +215,7 @@ import Iter "mo:base/Iter"; ``` ### Declaring the `votes` variable -Next, we need to add some code inside the actor to declare the variable for the data structure: +Next, you need to add some code inside the actor to declare the variable for the data structure: ```motoko var votes: RBTree.RBTree = RBTree.RBTree(Text.compare); @@ -223,12 +223,12 @@ Next, we need to add some code inside the actor to declare the variable for the :::info **What does this code do?** -In this code, we create a variable called `votes` with the type `RBTree.RBTree`. +In this code, you create a variable called `votes` with the type `RBTree.RBTree`. ::: ### Declaring the `getVotes` method -Now that we have the data collection structure, we need to create a method that queries the amount of vote counts per option. This will be a query call, since it will not alter the data. +Now that you have the data collection structure, you need to create a method that queries the amount of vote counts per option. This will be a query call, since it will not alter the data. Insert the following code into your `main.mo` file; there are inline comments that help explain the code's logic: @@ -294,7 +294,7 @@ The following example is a **code snippet** that is part of a larger code file. case (?Nat) Nat; }; - //once we have the number of votes, update the votes for the entry + //once you have the number of votes, update the votes for the entry votes.put(entry, current_votes_for_entry + 1); //Return the number of votes as an array (so frontend can display it) @@ -305,12 +305,12 @@ The following example is a **code snippet** that is part of a larger code file. :::info **What does this code do?** -The `?Nat` data type is a [Motoko optional](/docs/motoko/main/base/Option.md) data type that may be a `Nat` or a `null` value. If an entry is queried for the `RBTree` data structure titled `votes`, but the entry is not present, it will return `null`. That is why we use a Motoko optional in line 11. +The `?Nat` data type is a [Motoko optional](/docs/motoko/main/base/Option.md) data type that may be a `Nat` or a `null` value. If an entry is queried for the `RBTree` data structure titled `votes`, but the entry is not present, it will return `null`. That is why you use a Motoko optional in line 11. ::: ### Declaring the `resetVotes` method -Lastly, we'll declare the `resetVotes` method that'll be used to reset the state of each vote option back to 0. +Lastly, you'll declare the `resetVotes` method that'll be used to reset the state of each vote option back to 0. Insert the following code into your `main.mo` file; there are inline comments that help explain the code's logic: @@ -393,7 +393,7 @@ actor { case (?Nat) Nat; }; - //once we have the number of votes, update the votes for the entry + //once you have the number of votes, update the votes for the entry votes.put(entry, current_votes_for_entry + 1); //Return the number of votes as an array (so frontend can display it) @@ -425,9 +425,9 @@ Then, you can deploy the dapp with the command: dfx deploy ``` -You may recall that in the previous module, [exploring a live demo](1.1-live-demo.md), we used the `--playground` flag to deploy our canister to the Motoko playground network. In this module, we aren't using any flags, which defaults to deploying the canister to the local environment. You can also specify this with the flag `--network local`. +You may recall that in the previous module, [exploring a live demo](1.1-live-demo.md), you used the `--playground` flag to deploy your canister to the Motoko playground network. In this module, you aren't using any flags, which defaults to deploying the canister to the local environment. You can also specify this with the flag `--network local`. -Additionally, we aren't specifying a canister name in the `dfx deploy` command, which will deploy all canisters listed in the `dfx.json` file, which by default includes both the `poll_backend` and `poll_frontend` canisters. +Additionally, you aren't specifying a canister name in the `dfx deploy` command, which will deploy all canisters listed in the `dfx.json` file, which by default includes both the `poll_backend` and `poll_frontend` canisters. The output of the `dfx deploy` command will resemble the following: @@ -441,7 +441,7 @@ URLs: ## Adding pre-developed frontend code -Now let's create a frontend for users to interact with our dapp. We will use some basic JavaScript to keep it as simple as possible. +Now let's create a frontend for users to interact with your dapp. you will use some basic JavaScript to keep it as simple as possible. Start by opening the file `/src/poll_frontend/src/index.html` in your code editor, then replace the existing content with the following: @@ -581,7 +581,7 @@ The HTML code above is a simple form that provides the end user with options to Then, the `` tag is used to include some basic CSS for the page's styling. To learn more about adding a stylesheet, see: [add a stylesheet](/docs/developer-docs/frontend/add-stylesheet.md). ::: -Lastly, we need to update the `index.js` file in order for our frontend canister to communicate with our backend canister and have the result of that communication reflected within the frontend's HTML. +Lastly, you need to update the `index.js` file in order for your frontend canister to communicate with our backend canister and have the result of that communication reflected within the frontend's HTML. Open the `/src/poll_frontend/src/index.js` file in your code editor and replace the content of `index.js` with the following: @@ -625,14 +625,14 @@ document.addEventListener('DOMContentLoaded', async (e) => { }, false); ``` -To make this code fully functional, we'll need to add a few other pieces of Javascript. Ultimately, your `index.js` file will need to look like this: +To make this code fully functional, you'll need to add a few other pieces of Javascript. Ultimately, your `index.js` file will need to look like this: ```javascript const pollForm = document.getElementById("radioForm"); const resultsDiv = document.getElementById('results'); const resetButton = document.getElementById('reset'); -//Note we will use "poll_backend" in this JavaScript code a few times to call the backend +//Note you will use "poll_backend" in this JavaScript code a few times to call the backend import { poll_backend } from "../../declarations/poll_backend"; //1. LOCAL DATA @@ -727,7 +727,7 @@ function updateLocalVoteCounts(arrayOfVoteArrays){ ::: **What does this code do?** -The remainder of this code is annotated with comments to help explain how it works. It can be helpful to read through and understand what this code does, but we will not be focusing on the fundamentals of Javascript until a later tutorial. +The remainder of this code is annotated with comments to help explain how it works. It can be helpful to read through and understand what this code does, but you will not be focusing on the fundamentals of Javascript until a later tutorial. ::: ## Re-deploying the dapp @@ -777,7 +777,7 @@ Did you get stuck somewhere in this tutorial, or feel like you need additional h ## Next steps -In this tutorial, we only deployed our dapp to our local environment. In the next module, we'll set up a cycles wallet and acquire cycles in order for us to deploy our dapp to the Internet Computer mainnet. +In this tutorial, you only deployed our dapp to your local environment. In the next module, you'll set up a cycles wallet and acquire cycles in order for you to deploy your dapp to the Internet Computer mainnet. - [1.4 Acquiring and using cycles](1.4-using-cycles.md). diff --git a/docs/tutorials/developer-journey/level-1/1.4-using-cycles.md b/docs/tutorials/developer-journey/level-1/1.4-using-cycles.md index 3cbb683607..b4f1b9c990 100644 --- a/docs/tutorials/developer-journey/level-1/1.4-using-cycles.md +++ b/docs/tutorials/developer-journey/level-1/1.4-using-cycles.md @@ -16,7 +16,7 @@ Cycles wallets are necessary since a user's principal can't hold cycles directly For local canister execution, the SDK automatically creates a default cycles wallet in every project, and operations performed using cycles are done in the background. In a production environment with canisters deployed on the mainnet, canisters will need to have cycles explicitly registered and transferred into them. Production canisters will also require principals to be configured to act as **custodians**, which are principals that have permission to send and receive cycles for the canister. -In this tutorial, we'll cover how to set up a cycles wallet and fill it with cycles to use. Then, in the next tutorial we'll deploy a canister to the mainnet using those cycles. +In this tutorial, you'll learn how to set up a cycles wallet and fill it with cycles to use. Then, in the next tutorial you'll deploy a canister to the mainnet using those cycles. ## Prerequisites @@ -36,7 +36,7 @@ Each principal can control multiple accounts in the ICP (and other) ledgers. You can learn more in the IC [specification](https://internetcomputer.org/docs/current/references/ic-interface-spec#principal). ::: -In this tutorial, we'll create a new identity principal with `dfx`, which we'll use to obtain cycles and deploy a cycles wallet. +In this tutorial, you'll create a new identity principal with `dfx`, which you'll use to obtain cycles and deploy a cycles wallet. First, assure that `dfx` is running; if not, use the following command to start it: @@ -44,7 +44,7 @@ First, assure that `dfx` is running; if not, use the following command to start dfx start --background ``` -Next we will create a new developer identity with the command: +Next you will create a new developer identity with the command: ```sh dfx identity new DevJourney @@ -82,7 +82,7 @@ Cycles can be obtained by converting ICP tokens into cycles. There are a few way - Receiving a grant of ICP tokens through the DFINITY Foundation. - Receiving ICP tokens in return for providing resources as a node provider. -For new developers, a free cycles coupon can be obtained and redeemed for 20T free cycles that can be used to get started with dapp deployment. For this developer journey, we'll be obtaining and using that free cycles coupon. +For new developers, a free cycles coupon can be obtained and redeemed for 20T free cycles that can be used to get started with dapp deployment. For this developer journey, you'll be obtaining and using that free cycles coupon. This coupon is good for new developers since it doesn't require that you transfer ICP tokens into cycles, and doesn't require a purchase of tokens to get started. @@ -273,7 +273,7 @@ Did you get stuck somewhere in this tutorial, or feel like you need additional h ## Next steps -In this tutorial, we set up our identity and acquired free cycles from the cycles faucet. Now that we have cycles, we can deploy our first dapp on the IC mainnet. +In this tutorial, you set up our identity and acquired free cycles from the cycles faucet. Now that you have cycles, you can deploy your first dapp on the IC mainnet. - [1.5 Deploying canisters](1.5-deploying-canisters.md). diff --git a/docs/tutorials/developer-journey/level-1/1.5-deploying-canisters.md b/docs/tutorials/developer-journey/level-1/1.5-deploying-canisters.md index 17fbfb46fb..d5be51c5f7 100644 --- a/docs/tutorials/developer-journey/level-1/1.5-deploying-canisters.md +++ b/docs/tutorials/developer-journey/level-1/1.5-deploying-canisters.md @@ -2,7 +2,7 @@ ## Overview -Now that we have some cycles to pay for our canister's resources, we can deploy our dapp on the mainnet. When a canister is deployed to the mainnet, it's code will be hosted on a node that is providing resources to one of the mainnet's subnets. The canister will be hosted on this node until it is manually uninstalled by the developer, or until it runs out of cycles and is uninstalled automatically. +Now that you have some cycles to pay for our canister's resources, you can deploy your dapp on the mainnet. When a canister is deployed to the mainnet, it's code will be hosted on a node that is providing resources to one of the mainnet's subnets. The canister will be hosted on this node until it is manually uninstalled by the developer, or until it runs out of cycles and is uninstalled automatically. Once a dapp is deployed on the mainnet, it can be accessed from the canister's public URL by end-users and can communicate with other canisters that are deployed on the mainnet. @@ -10,11 +10,11 @@ Once a dapp is deployed on the mainnet, it can be accessed from the canister's p Before you start, verify that you have set up your developer environment according to the instructions in [0.3 Developer environment setup](../level-0/03-dev-env.md). -We will be building off of the previous two modules, [1.3 Developing your first dapp](1.3-first-dapp.md) and [1.4 Acquiring and using cycles](1.4-using-cycles.md). You will need to have followed along and completed the steps outlined in these modules to complete this tutorial. +You will be building off of the previous two modules, [1.3 Developing your first dapp](1.3-first-dapp.md) and [1.4 Acquiring and using cycles](1.4-using-cycles.md). You will need to have followed along and completed the steps outlined in these modules to complete this tutorial. ## Deploying to the mainnet -To deploy your dapp to the mainnet, first assure that your terminal window is open and you've navigated into the directory of your `poll` dapp that we created in module [1.3 Developing your first dapp](1.3-first-dapp.md). +To deploy your dapp to the mainnet, first assure that your terminal window is open and you've navigated into the directory of your `poll` dapp that you created in module [1.3 Developing your first dapp](1.3-first-dapp.md). Then, assure that all necessary packages are installed for our project's frontend with the command: @@ -22,7 +22,7 @@ Then, assure that all necessary packages are installed for our project's fronten npm install ``` -Now it's time to register, build, and deploy your dapp. First, let's check to make sure we have an active connection to the mainnet. Run the command: +Now it's time to register, build, and deploy your dapp. First, let's check to make sure you have an active connection to the mainnet. Run the command: ```sh dfx ping ic @@ -37,13 +37,13 @@ A successful connection to the mainnet will return an output such as: ``` -Now, we can deploy our dapp to the mainnet by running the following command: +Now, you can deploy your dapp to the mainnet by running the following command: ```sh dfx deploy --network ic ``` -In this command, the `--network` flag specifies which network the dapp should be deployed on. Other options for this flag are `--network local` and `--network playground`. We covered these in module [1.1: exploring a live demo](1.1-live-demo.md). +In this command, the `--network` flag specifies which network the dapp should be deployed on. Other options for this flag are `--network local` and `--network playground`. This tutorial series covered these in module [1.1: exploring a live demo](1.1-live-demo.md). Using the flag `--network ic` is required to deploy your dapp on the mainnet. If this flag is not included, your dapp will be only be deployed locally by default. @@ -53,7 +53,7 @@ This command doesn't include a canister name, meaning it will automatically depl dfx deploy poll_backend --network ic ``` -We want to deploy both the `poll_backend` and `poll_frontend` canisters since they work together to create our poll dapp, so the `dfx deploy --network ic` command should be used for this tutorial. +you want to deploy both the `poll_backend` and `poll_frontend` canisters since they work together to create your poll dapp, so the `dfx deploy --network ic` command should be used for this tutorial. The output of this command will include information about what actions are happening. For example, the output should resemble the following: @@ -101,7 +101,7 @@ Canister was topped up! If you used the free cycles coupon, this step is not applicable. -Now, let's use our dapp! To access the dapp's frontend, first we need to get the canister's URL. To get this, run the command: +Now, let's use your dapp! To access the dapp's frontend, first you need to get the canister's URL. To get this, run the command: ```sh dfx canister id poll_frontend --network ic @@ -137,7 +137,7 @@ Did you get stuck somewhere in this tutorial, or feel like you need additional h ## Next steps -Now that we have canisters running on the mainnet, the next steps are to learn how we can manage these canisters, such as how to upgrade them or delete them. +Now that you have canisters running on the mainnet, the next steps are to learn how you can manage these canisters, such as how to upgrade them or delete them. - [1.6 Managing canisters](1.6-managing-canisters.md) diff --git a/docs/tutorials/developer-journey/level-1/1.6-managing-canisters.md b/docs/tutorials/developer-journey/level-1/1.6-managing-canisters.md index 8c1834ed1c..5cc9f7379f 100644 --- a/docs/tutorials/developer-journey/level-1/1.6-managing-canisters.md +++ b/docs/tutorials/developer-journey/level-1/1.6-managing-canisters.md @@ -2,7 +2,7 @@ ## Overview -Now that we have canisters deployed on the mainnet, the next step is to learn how to manage those canisters. Managing a canister includes workflows such as obtaining information, setting an identity as the canister's owner, and deleting a canister. We'll dive into these different workflows and more in this guide to assure that you have the core fundamentals of how to maintain canisters. +Now that you have canisters deployed on the mainnet, the next step is to learn how to manage those canisters. Managing a canister includes workflows such as obtaining information, setting an identity as the canister's owner, and deleting a canister. You'll dive into these different workflows and more in this guide to assure that you have the core fundamentals of how to maintain canisters. ## The IC management canister @@ -14,11 +14,11 @@ Management operations such as updating a canister, creating a canister, and stop Before you start, verify that you have set up your developer environment according to the instructions in [0.3 Developer environment setup](../level-0/03-dev-env.md). -We will be building off of the previous three modules, [1.3 Developing your first dapp](1.3-first-dapp.md), [1.4 Acquiring and using cycles](1.4-using-cycles.md), and [1.5 Deploying canisters](1.5-deploying-canisters.md). You will need to have followed along and completed the steps outlined in these modules to complete this tutorial. +You will be building off of the previous three modules, [1.3 Developing your first dapp](1.3-first-dapp.md), [1.4 Acquiring and using cycles](1.4-using-cycles.md), and [1.5 Deploying canisters](1.5-deploying-canisters.md). You will need to have followed along and completed the steps outlined in these modules to complete this tutorial. ## Obtaining a canister's ID -Each canister has a unique identifier that can be used to interact with the canister. These unique IDs can be used to access the canister's frontend or Candid UI in a web browser, such as when we accessed the frontend of our poll dapp in the last tutorial. Having a canister's ID is also important for executing management functions of the canister, such as setting ownership for the canister. +Each canister has a unique identifier that can be used to interact with the canister. These unique IDs can be used to access the canister's frontend or Candid UI in a web browser, such as when you accessed the frontend of your poll dapp in the last tutorial. Having a canister's ID is also important for executing management functions of the canister, such as setting ownership for the canister. As an example, let's get the canister ID of our `poll_backend` canister that's been deployed on the mainnet by using the command: @@ -42,7 +42,7 @@ dfx canister id poll_backend Next, let's obtain some information about our canister, such as the canister's controller(s) and the Wasm module hash. -To get this information, we can use the command `dfx canister info`, such as: +To get this information, you can use the command `dfx canister info`, such as: ```sh dfx canister info poll_backend @@ -76,7 +76,7 @@ The output will resemble the following: lalyb-uhvmt-p7ubs-u5t7l-hce6v-lp7c5-dlmj5-wi2gc-depab-wtgi3-pae ``` -Copy this value. We'll then use the `dfx canister update-settings` command to add this principal to be a controller of our `poll_backend` canister, but first, we need to switch back to our previously created identity, since only existing controllers can add new controllers: +Copy this value. You'll then use the `dfx canister update-settings` command to add this principal to be a controller of your `poll_backend` canister, but first, you need to switch back to our previously created identity, since only existing controllers can add new controllers: ```sh dfx identity use DeveloperJourney @@ -88,13 +88,13 @@ Then, use the `dfx canister update-settings` command: dfx canister update-settings poll_backend --add-controller PRINCIPAL_ID ``` -For example, to use our principal value from above: +For example, to use your principal value from above: ```sh dfx canister update-settings poll_backend --add-controller lalyb-uhvmt-p7ubs-u5t7l-hce6v-lp7c5-dlmj5-wi2gc-depab-wtgi3-pae ``` -This command adds the principal `lalyb-uhvmt-p7ubs-u5t7l-hce6v-lp7c5-dlmj5-wi2gc-depab-wtgi3-pae` as an additional controller of our `poll_backend` canister. To confirm that this principal has been added, we can run the `dfx canister info` command again: +This command adds the principal `lalyb-uhvmt-p7ubs-u5t7l-hce6v-lp7c5-dlmj5-wi2gc-depab-wtgi3-pae` as an additional controller of your `poll_backend` canister. To confirm that this principal has been added, you can run the `dfx canister info` command again: ```sh dfx canister info poll_backend @@ -119,7 +119,7 @@ Alternatively, you can use the `--set-controller` flag instead of the `--add-con dfx canister update-settings poll_backend --set-controller lalyb-uhvmt-p7ubs-u5t7l-hce6v-lp7c5-dlmj5-wi2gc-depab-wtgi3-pae ``` -You will be warned that you'll be removing yourself as a controller, since we're setting the `ControllerExample` identity as the sole controller, while we're using the `DeveloperJourney` identity. Accept this warning. +You will be warned that you'll be removing yourself as a controller, since you're setting the `ControllerExample` identity as the sole controller, while you're using the `DeveloperJourney` identity. Accept this warning. Then, rerun the `dfx canister info poll_backend` command. The output should now be: @@ -247,7 +247,7 @@ There are a few ways to top up a canister: - Using the NNS dapp web UI. - Using a third-party service such as [CycleOps](../../../developer-docs/setup/cycles/cycles_management_services). -We will cover the first two workflows in this tutorial. For more information on using a third-party service for cycles management, please see [here](../../../developer-docs/setup/cycles/cycles_management_services). +This tutorial will cover the first two workflows. For more information on using a third-party service for cycles management, please see [here](../../../developer-docs/setup/cycles/cycles_management_services). ### Using ICP @@ -334,7 +334,7 @@ Module hash: 0xf8680eb74022a1079012b7e9c644d1156580002a6126305791811533d3fd6f17 ## Deleting a canister -The last portion of canister management that we'll cover in this guide is deleting canisters. To delete a single canister, first you need to stop the canister with the command: +The last portion of canister management that will be covered in this guide is deleting canisters. To delete a single canister, first you need to stop the canister with the command: ```sh dfx canister poll_frontend --network ic stop @@ -375,7 +375,7 @@ Did you get stuck somewhere in this tutorial, or feel like you need additional h ## Next steps -In the next step of our developer journey, we'll explore upgrading canisters, storage, and persistence. +In the next step of our developer journey, you'll explore upgrading canisters, storage, and persistence. - [2.1 Storage and persistence](../level-2/2.1-storage-persistence.md). diff --git a/docs/tutorials/developer-journey/level-1/index.md b/docs/tutorials/developer-journey/level-1/index.md index 5574f4bd8c..bec928e77b 100644 --- a/docs/tutorials/developer-journey/level-1/index.md +++ b/docs/tutorials/developer-journey/level-1/index.md @@ -1,13 +1,13 @@ # Level 1: Space cadet -- [1.1 Exploring a live demo](1.1-live-demo.md): Before we begin developing our own dapps, let's explore a live, deployed canister that utilizes the Motoko playground through the `dfx deploy --playground` command. This module covers: +- [1.1 Exploring a live demo](1.1-live-demo.md): Before you begin developing your own dapps, let's explore a live, deployed canister that utilizes the Motoko playground through the `dfx deploy --playground` command. This module covers: - Overview of Motoko Playground. - An overview of the `dfx deploy --playground` command. - Deploying a canister to Motoko Playground using `dfx`. - Interacting with the canister via the CLI. - Interacting with the canister via the Candid interface. -- [1.2 Motoko level 1](1.2-motoko-lvl1.md): To develop our own dapp, we first need to cover the fundamentals of writing Motoko code. This module covers: +- [1.2 Motoko level 1](1.2-motoko-lvl1.md): To develop your own dapp, you first need to cover the fundamentals of writing Motoko code. This module covers: - Basic concepts and terms. - Motoko syntax. - Using the base library. @@ -19,7 +19,7 @@ - Printing values. - Passing text arguments. -- [1.3 Developing your first dapp](1.3-first-dapp.md): Now we're ready to develop our first dapp on the Internet Computer! This module covers: +- [1.3 Developing your first dapp](1.3-first-dapp.md): Now you're ready to develop your first dapp on the Internet Computer! This module covers: - Creating a new project. - Reviewing the project's file structure. - Writing the backend canister code. @@ -37,16 +37,16 @@ - Adding pre-developed frontend code. - Re-deploying the dapp. -- [1.4 Acquiring and using cycles](1.4-using-cycles.md): To deploy dapps on the IC mainnet, we'll need to acquire cycles. This module covers: +- [1.4 Acquiring and using cycles](1.4-using-cycles.md): To deploy dapps on the IC mainnet, you'll need to acquire cycles. This module covers: - Overview of cycles. - Creating a developer identity. - Acquiring cycles using a cycles coupon. - Converting ICP tokens to cycles. -- [1.5 Deploying canisters](1.5-deploying-canisters.md): Once we have acquired some cycles, we can deploy our dapp to the mainnet. This module covers: +- [1.5 Deploying canisters](1.5-deploying-canisters.md): Once you have acquired some cycles, you can deploy our dapp to the mainnet. This module covers: - Deploying to the mainnet. -- [1.6 Managing canisters](1.6-managing-canisters.md): Once our dapp is deployed on the mainnet, we need to learn how we can manage the canister. This module covers: +- [1.6 Managing canisters](1.6-managing-canisters.md): Once your dapp is deployed on the mainnet, you need to learn how you can manage the canister. This module covers: - Obtaining a canister's ID. - Obtaining canister information. - Adding an identity as a controller of a canister. diff --git a/docs/tutorials/developer-journey/level-2/2.1-storage-persistence.md b/docs/tutorials/developer-journey/level-2/2.1-storage-persistence.md index 5c85b92900..63e1fb02d3 100644 --- a/docs/tutorials/developer-journey/level-2/2.1-storage-persistence.md +++ b/docs/tutorials/developer-journey/level-2/2.1-storage-persistence.md @@ -8,7 +8,7 @@ To use stable memory requires anticipating and indicating which canister data yo ## Memory types and terms -There are several terms associated with memory and storage on the IC. To avoid confusion between them, we'll define them here. +There are several terms associated with memory and storage on the IC. To avoid confusion between them, let's define them here. - **Stable memory:** Stable memory refers to the Internet Computer's long-term data storage feature. Stable memory is not language specific, and can be utilized by canisters written in Motoko, Rust, or any other language. Stable memory can hold up to 96GiB if the subnet can accommodate it. @@ -50,7 +50,7 @@ For canisters written in Rust, stable memory can be utilized through two Rust cr ## Stable storage and stable variables -Motoko supports preserving a canister's state using the IC's stable memory through a Motoko-specific feature known as **stable storage**, which is designed to accommodate changes to both the application data and the Motoko compiler. Stable storage utilizes the IC's **stable memory** feature that we discussed previously. +Motoko supports preserving a canister's state using the IC's stable memory through a Motoko-specific feature known as **stable storage**, which is designed to accommodate changes to both the application data and the Motoko compiler. Stable storage utilizes the IC's **stable memory** feature that was discussed previously. :::info Upgrading canisters written in Rust and other languages use a different workflow which incorporates serialization of the canister's data. For more information on Rust upgrades, see the documentation [here](../../../developer-docs/backend/rust/7-upgrading.md). @@ -103,14 +103,14 @@ Save this file. ### Deploying your counter dapp -To upgrade our canister, first we need to deploy our initial version of the canister. Deploy the canister with the command: +To upgrade our canister, first you need to deploy our initial version of the canister. Deploy the canister with the command: ``` dfx deploy counter_backend ``` :::info -For this tutorial, we're using the local replica environment to deploy our canisters. You can deploy yours on the mainnet with the flag `--network ic`. Remember that deploying to the mainnet will cost cycles. +For this tutorial, you're using the local replica environment to deploy our canisters. You can deploy yours on the mainnet with the flag `--network ic`. Remember that deploying to the mainnet will cost cycles. ::: You can interact with the counter dapp through the Candid UI URL returned in the output of the `dfx deploy` command, such as: @@ -136,7 +136,7 @@ Now, let's make some changes to upgrade the canister. First, stop the canister w dfx canister stop counter_backend ``` -Then, let's alter the code of our canister. To keep things simple, we're going to change the counter increment value from '1' to '3'. Our altered code looks like this: +Then, let's alter the code of your canister. To keep things simple, you're going to change the counter increment value from '1' to '3'. Your altered code looks like this: ```motoko actor Counter { @@ -203,7 +203,7 @@ Did you get stuck somewhere in this tutorial, or feel like you need additional h ## Next steps -Next, we'll look at advanced canister calls, such as inter-canister calls and canister query methods. +Next, you'll look at advanced canister calls, such as inter-canister calls and canister query methods. - [2.2 Advanced canister calls](2.2-advanced-canister-calls.md). diff --git a/docs/tutorials/developer-journey/level-2/2.2-advanced-canister-calls.md b/docs/tutorials/developer-journey/level-2/2.2-advanced-canister-calls.md index f19e5fa73c..7c83c7d99f 100644 --- a/docs/tutorials/developer-journey/level-2/2.2-advanced-canister-calls.md +++ b/docs/tutorials/developer-journey/level-2/2.2-advanced-canister-calls.md @@ -2,7 +2,7 @@ ## Overview -In the previous tutorial where we [created our first dapp](../level-1/1.3-first-dapp.md), we briefly discussed query and update canister calls. In this tutorial, we'll dive deeper into these types of canister calls, but also take a look at advanced canister calls such as composite queries, certified variables, and inter-canister calls. +In the previous tutorial where you [created your first dapp](../level-1/1.3-first-dapp.md), the developer journey briefly discussed query and update canister calls. In this tutorial, you'll dive deeper into these types of canister calls, but also take a look at advanced canister calls such as composite queries, certified variables, and inter-canister calls. Let's first define the different types of canister calls and how they differ from one another: @@ -35,7 +35,7 @@ Query calls are used to query the current state of a canister or make a call to Query calls return results faster than update calls. Setting functions as query functions where appropriate can be an effective way to improve application performance. When designing your dapp, it is important to notice where query calls can be used in place of functions that perform queries. However, compared to update calls, the trade-off of a query call's increased performance is decreased security, since queries do not go through consensus and are not reflected in the transactions of the blockchain. -The amount of security your dapp needs will be dependent on your dapp's use case and functionality. For example, a blog dapp that uses a function to retrieve articles matching a tag doesn't need to have requests go through consensus and can benefit from using query calls. In contrast, a dapp that retrieves sensitive information, such as financial data, would greatly benefit from increased security and validation that the query result is accurate and secure. To return query results that are validated and secure, the IC supports **certified variables**, which we'll dive into next. +The amount of security your dapp needs will be dependent on your dapp's use case and functionality. For example, a blog dapp that uses a function to retrieve articles matching a tag doesn't need to have requests go through consensus and can benefit from using query calls. In contrast, a dapp that retrieves sensitive information, such as financial data, would greatly benefit from increased security and validation that the query result is accurate and secure. To return query results that are validated and secure, the IC supports **certified variables**, which you'll dive deeper into in a future module, [3.3: Certified variables](../level-3/3.3-certified-data.md). ### Example `query` call @@ -78,7 +78,7 @@ Certified variables utilize **chain-key cryptography** to generate digital signa Certification happens at the canister level. Certified variables can be set during an update call to a canister. Recall that an update call changes the canister's state and goes through consensus. When a certified variable is set, the certification can then be read in future query calls and return the certified variable in response to the query call in a trustworthy and secure manner. -We'll dive deeper into certified variables in a future module, [3.3: Certified variables](../level-3/3.3-certified-data.md). +You'll dive deeper into certified variables in a future module, [3.3: Certified variables](../level-3/3.3-certified-data.md). ## Composite queries @@ -99,7 +99,7 @@ For example, consider a scenario where you want to create a social media dapp th ### Using inter-canister calls -To demonstrate this inter-canister call functionality, we're going to use an example known as a 'PubSub'. In this example, we have two canisters: a **publisher** and a **subscriber**. In this setup, the 'Subscriber' canister sends an inter-canister call to the 'Publisher' canister that indicates it would like to subscribe to a 'topic', which is a key-value pair in this example of type '`Text`: `Nat`'. Then, the 'Publisher' canister can publish information to that topic, in this example the value associated with the topic's key. Let's take a closer look. +To demonstrate this inter-canister call functionality, you're going to use an example known as a 'PubSub'. In this example, you have two canisters: a **publisher** and a **subscriber**. In this setup, the 'Subscriber' canister sends an inter-canister call to the 'Publisher' canister that indicates it would like to subscribe to a 'topic', which is a key-value pair in this example of type '`Text`: `Nat`'. Then, the 'Publisher' canister can publish information to that topic, in this example the value associated with the topic's key. Let's take a closer look. ### Prerequisites @@ -107,7 +107,7 @@ Before you start, verify that you have set up your developer environment accordi ### Creating a new project -To get started, we'll be cloning the DFINITY example repo which contains this tutorial's example, plus several others. We'll be using the `motoko/pub-sub` folder. Open a terminal window, navigate into your working directory (`developer_journey`), then use the commands: +To get started, you'll be cloning the DFINITY example repo which contains this tutorial's example, plus several others. you'll be using the `motoko/pub-sub` folder. Open a terminal window, navigate into your working directory (`developer_journey`), then use the commands: ``` dfx start --clean --background @@ -130,7 +130,7 @@ Let's take a look at the project's files: ### Writing a `publisher` canister -You'll notice that this project structure is a bit different from the ones we've used thus far in our developer journey. Since this project uses two backend canisters for it's functionality, there aren't `src` folders for a backend or frontend canister, just two folders for each backend canister. +You'll notice that this project structure is a bit different from the ones you've used thus far in our developer journey. Since this project uses two backend canisters for it's functionality, there aren't `src` folders for a backend or frontend canister, just two folders for each backend canister. Now let's take a closer look at the `Main.mo` file for our 'Publisher' canister. The code can be found below with comments that explain the code's logic: @@ -221,13 +221,13 @@ Next, let's use the canister's and demonstrate their functionality. First, deplo dfx deploy ``` -Then, let's call the Subscriber canisters to create and subscribe to the topic 'Astronauts'. We can do that with the command: +Then, let's call the Subscriber canisters to create and subscribe to the topic 'Astronauts'. You can do that with the command: ``` dfx canister call sub init '("Astronauts")' ``` -Now we can publish a value to be associated with the 'Astronauts' topic. Remember that the 'value' data type is defined as type `Nat`, so this value must be a number. +Now you can publish a value to be associated with the 'Astronauts' topic. Remember that the 'value' data type is defined as type `Nat`, so this value must be a number. ``` dfx canister call pub publish '(record { "topic" = "Astronauts"; "value" = 5 })' diff --git a/docs/tutorials/developer-journey/level-2/2.3-third-party-canisters.md b/docs/tutorials/developer-journey/level-2/2.3-third-party-canisters.md index 32e612c30f..ad560801f8 100644 --- a/docs/tutorials/developer-journey/level-2/2.3-third-party-canisters.md +++ b/docs/tutorials/developer-journey/level-2/2.3-third-party-canisters.md @@ -6,11 +6,11 @@ Third-party canisters are canisters that provide a public service at a static ca `dfx` enables a **dependency** workflow, where a canister can be configured to pull third-party canisters that it depends on into the local environment. This can be useful for developers who are looking to test the accuracy of their integration with the third-party canister and perform tests without paying cycles or using production environments. It also drastically simplifies the local deployment of canisters like the II canister, since you don't need to obtain the Wasm and Candid files for the canisters yourself - `dfx` takes care of it in the background for you. -In this tutorial, we'll be focusing on pulling third-party canisters. If you're interested in developing third-party canisters that can be pulled by other developers, check out the documentation on `dfx deps` [here](/docs/developer-docs/setup/pulling-canister-dependencies.md). +In this tutorial, you'll be focusing on pulling third-party canisters. If you're interested in developing third-party canisters that can be pulled by other developers, check out the documentation on `dfx deps` [here](/docs/developer-docs/setup/pulling-canister-dependencies.md). ## Pulling third-party canister dependencies -Let's take a look at a basic example of pulling a third-party canister as a dependency. To do this, we'll use the `dfx deps` command, which is the `dfx` subcommand responsible for pulling canisters that are listed as dependencies of another canister in the project's `dfx.json` file. +Let's take a look at a basic example of pulling a third-party canister as a dependency. To do this, you'll use the `dfx deps` command, which is the `dfx` subcommand responsible for pulling canisters that are listed as dependencies of another canister in the project's `dfx.json` file. ### Prerequisites @@ -26,9 +26,9 @@ dfx new dependencies cd dependencies ``` -We'll use the default 'Hello world' project in this example, then we'll pull the Internet Identity canister as a dependency of our `dependencies_backend` canister. +You'll use the default 'Hello world' project in this example, then you'll pull the Internet Identity canister as a dependency of our `dependencies_backend` canister. -First, open the `dfx.json` file in your project's directory. We need to configure our `dependencies_backend` canister to have the dependencies of `internet_identity`, with canister ID `rdmx6-jaaaa-aaaaa-aaadq-cai` on the mainnet. This is the canister ID of the DFINITY canister used to interact with the IC's identity and authentication product called Internet Identity. We'll dive deeper into II in a later tutorial; for now, we'll just use it to demonstrate how third-party canisters can be used. We can do so by editing our `dfx.json` file to reflect the following configuration: +First, open the `dfx.json` file in your project's directory. You need to configure your `dependencies_backend` canister to have the dependencies of `internet_identity`, with canister ID `rdmx6-jaaaa-aaaaa-aaadq-cai` on the mainnet. This is the canister ID of the DFINITY canister used to interact with the IC's identity and authentication product called Internet Identity. The developer journey will dive deeper into II in a later tutorial; for now, you'll just use it to demonstrate how third-party canisters can be used. You can do so by editing our `dfx.json` file to reflect the following configuration: ``` { @@ -89,7 +89,7 @@ The `deps/` folder is also created in your project's root folder. The `deps/pull ### Using `dfx deps` -Next, we'll set the `init` arguments for the dependency canisters using the `dfx deps init` command. An `init` argument is an argument that will be passed to the canister when it is deployed. This command will iterate over all listed dependencies in the `pulled.json` file and set an empty argument for any that do not require an `init` argument. For those that require an `init` argument, they will be returned so that they can be set manually. Run the command: +Next, you'll set the `init` arguments for the dependency canisters using the `dfx deps init` command. An `init` argument is an argument that will be passed to the canister when it is deployed. This command will iterate over all listed dependencies in the `pulled.json` file and set an empty argument for any that do not require an `init` argument. For those that require an `init` argument, they will be returned so that they can be set manually. Run the command: ``` dfx deps init @@ -102,7 +102,7 @@ WARN: The following canister(s) require an init argument. Please run `dfx deps i rdmx6-jaaaa-aaaaa-aaadq-cai (internet_identity) ``` -This output shows us that the Internet Identity canister requires an `init` argument, but it doesn't give us any additional information. For more information, run the command `dfx deps init rdmx6-jaaaa-aaaaa-aaadq-cai`, which will provide an error message that shows us more details: +This output shows you that the Internet Identity canister requires an `init` argument, but it doesn't give you any additional information. For more information, run the command `dfx deps init rdmx6-jaaaa-aaaaa-aaadq-cai`, which will provide an error message that shows you more details: ``` Error: Canister rdmx6-jaaaa-aaaaa-aaadq-cai (internet_identity) requires an init argument. The following info might be helpful: @@ -110,7 +110,7 @@ init => Use '(null)' for sensible defaults. See the candid interface for more de candid:args => (opt InternetIdentityInit) ``` -In this error, we can see that to use the canister's defaults, we an use a `null` value as the `init` argument. To pass this value as an `init` argument, run the command: +In this error, you can see that to use the canister's defaults, you can use a `null` value as the `init` argument. To pass this value as an `init` argument, run the command: ``` dfx deps init rdmx6-jaaaa-aaaaa-aaadq-cai --argument null @@ -139,7 +139,7 @@ URLs: internet_identity: http://127.0.0.1:8080/?canisterId=bd3sg-teaaa-aaaaa-qaaba-cai&id=rdmx6-jaaaa-aaaaa-aaadq-cai ``` -Now, we can interact with the II canister locally using the CLI or the Candid UI. In a future tutorial we'll integrate our backend canister with the II canister. For now, that'll wrap up this module. +Now, you can interact with the II canister locally using the CLI or the Candid UI. In a future tutorial you'll integrate your backend canister with the II canister. For now, that'll wrap up this module. ## Need help? diff --git a/docs/tutorials/developer-journey/level-2/2.4-intro-candid.md b/docs/tutorials/developer-journey/level-2/2.4-intro-candid.md index 4554233e38..e463ced72d 100644 --- a/docs/tutorials/developer-journey/level-2/2.4-intro-candid.md +++ b/docs/tutorials/developer-journey/level-2/2.4-intro-candid.md @@ -8,14 +8,14 @@ Candid is language-agnostic, which is a key benefit since it allows for the inte Candid is unique since it provides functionality and features not available in other technologies, such as JSON or XML. Some of these features include the evolution of service interfaces, direct value mapping for Candid values to the types and values of the canister's language, and the ability to pass complex data such as references to services and methods. Candid also has built-in support for IC-specific features like query annotation. -Up until now in this developer journey, we've utilized the Candid UI a few times through the web browser. If you recall, in several tutorials we've interacted with the backend canisters in the web browser with the URL from an output such as: +Up until now in this developer journey, you've utilized the Candid UI a few times through the web browser. If you recall, in several tutorials you've interacted with the backend canisters in the web browser with the URL from an output such as: ``` Backend canister via Candid interface: dependencies_backend: http://127.0.0.1:8080/?canisterId=bd3sg-teaaa-aaaaa-qaaba-cai&id=bkyz2-fmaaa-aaaaa-qaaaq-cai ``` -These URLs take us to the Candid user interface (UI). Now it's time to take a closer look at the fundamentals of Candid to understand how it works and how it can be used for more complex dapp development. +These URLs take you to the Candid user interface (UI). Now it's time to take a closer look at the fundamentals of Candid to understand how it works and how it can be used for more complex dapp development. ## Candid types and values @@ -74,13 +74,13 @@ In contrast, the Candid binary format uses numeric hashes in place of field name ## Candid service descriptions -Now that we've discussed Candid types, we can learn about how to use them to describe a service. Candid uses a service description file with the file extension `.did`. Let's take a closer look at the structure of a service description. +Now that you've learned about Candid types, you can learn how to use them to describe a service. Candid uses a service description file with the file extension `.did`. Let's take a closer look at the structure of a service description. ### The `.did` file To define Candid types and describe a service, a Candid service description file can be used. This file has the extension `.did`, and can be generated from a service implementation or written manually. -The Candid files we have used thus far in the developer journey have been generated automatically. This is because a Motoko canister's Candid files are automatically generated by the Motoko compiler when the canister is compiled, then stored in the project's `/declarations` directory. When Candid files are auto-generated, it is not recommended to edit them manually, and any changes made to the file will be overwritten by `dfx` the next time the project is built and deployed. For canisters written in other languages, the Candid file must be written manually or generated using an external tool. +The Candid files you have used thus far in the developer journey have been generated automatically. This is because a Motoko canister's Candid files are automatically generated by the Motoko compiler when the canister is compiled, then stored in the project's `/declarations` directory. When Candid files are auto-generated, it is not recommended to edit them manually, and any changes made to the file will be overwritten by `dfx` the next time the project is built and deployed. For canisters written in other languages, the Candid file must be written manually or generated using an external tool. ### Example Candid service descriptions @@ -90,7 +90,7 @@ The simplest service description defines a service with no public methods. This service : {} ``` -Since this service description does not have any pubic methods, it is not very useful. To add a public method, we'll add a simple `ping` method: +Since this service description does not have any pubic methods, it is not very useful. To add a public method, you'll add a simple `ping` method: ``` service : { @@ -104,7 +104,7 @@ In this `ping` method, there are no arguments passed to the method and there are ### Generating service descriptions -Now that we've taken a look at the basic structure of a Candid service description, let's take a look at how to generate the service description from your code. +Now that you've taken a look at the basic structure of a Candid service description, let's take a look at how to generate the service description from your code. :::info Generating Candid files is supported for canisters written in Motoko. Canisters written in other languages will need to have their Candid files written manually. Check out the [Candid interface description](/docs/references/candid-ref.md) for more information on manually writing the service description. @@ -163,7 +163,7 @@ Candid supports service upgrades through a set of specific rules that indicate w For additional information about the supertypes and subtypes of any given type, check out the [Candid interface reference documentation](/docs/references/candid-ref.md) for each type. -To demonstrate an example of how a service might be upgraded, let's use the `counter` service example that we looked at in [generating service descriptions](#generating-service-descriptions). +To demonstrate an example of how a service might be upgraded, let's use the `counter` service example that you looked at in [generating service descriptions](#generating-service-descriptions). Let's start with the following Candid service description: @@ -189,7 +189,7 @@ service counter : { ## Using Candid -Now that we've taken a deep dive into Candid, let's explore the different ways to use it. There are three main ways to interact with Candid: using `dfx` on the command-line, using the web browser, and using an agent. For this tutorial, we'll look at using `dfx` and using the web browser; we'll dive into agents in a future section of the developer journey. +Now that you've taken a deep dive into Candid, let's explore the different ways to use it. There are three main ways to interact with Candid: using `dfx` on the command-line, using the web browser, and using an agent. For this tutorial, you'll look at using `dfx` and using the web browser; you'll dive into agents in a future section of the developer journey. ### Prerequisites @@ -205,7 +205,7 @@ dfx new candid_example cd candid_example ``` -We'll be using the sample Motoko canister that we looked at in the [generating service descriptions](#generating-service-descriptions) section earlier. Open the `src/candid_example_backend/main.mo` file in your code editor and replace the existing code with the following: +You'll be using the sample Motoko canister that you looked at in the [generating service descriptions](#generating-service-descriptions) section earlier. Open the `src/candid_example_backend/main.mo` file in your code editor and replace the existing code with the following: ```motoko actor { @@ -234,7 +234,7 @@ service : { ### Interacting with a service using the command-line terminal -Now that our canister is deployed, let's use `dfx` to interact with the methods defined by our Candid file. This section of tutorial will look familiar, since in previous tutorials we've interacted with canisters in the same manner - we just hadn't known we were directly interacting with the Candid defined services since the Candid files had been automatically generated for us in the background. +Now that your canister is deployed, let's use `dfx` to interact with the methods defined by your Candid file. This section of tutorial will look familiar, since in previous tutorials you've interacted with canisters in the same manner - you just hadn't known you were directly interacting with the Candid defined services since the Candid files had been automatically generated for you in the background. For example, let's call the `add` method to add a number to our counter with the command: @@ -242,14 +242,14 @@ For example, let's call the `add` method to add a number to our counter with the dfx canister call candid_example_backend add 12 ``` -Then, we can call the `get` method to return the value we just added: +Then, you can call the `get` method to return the value you just added: ``` dfx canister call candid_example_backend get (12 : int) ``` -We can then subtract from this value with the command: +You can then subtract from this value with the command: ``` dfx canister call candid_example_backend subtract 4 @@ -284,7 +284,7 @@ In this output, you can see the URL for the Candid interface under 'Backend cani ![Candid UI 1](../_attachments/candid_ui-1.png) -Let's use the same workflow we used on the command-line. First, let's add 12 to the counter by entering '12' into the 'add' method, then selecting 'call'. The output log on the left will reflect this call. +Let's use the same workflow you used on the command-line. First, let's add 12 to the counter by entering '12' into the 'add' method, then selecting 'call'. The output log on the left will reflect this call. ![Candid UI 2](../_attachments/candid_ui-2.png) diff --git a/docs/tutorials/developer-journey/level-2/2.5-unit-testing.md b/docs/tutorials/developer-journey/level-2/2.5-unit-testing.md index 6b2b8e116d..3a4d1aea58 100644 --- a/docs/tutorials/developer-journey/level-2/2.5-unit-testing.md +++ b/docs/tutorials/developer-journey/level-2/2.5-unit-testing.md @@ -102,7 +102,7 @@ Want to learn more about running large, long-running batches of tests? Take a lo ## Rust unit testing -In this developer journey series, we'll continue to focus on exploring and using Motoko. However, it's important to make note of the resources available for Rust testing. +In this developer journey series, you'll continue to focus on exploring and using Motoko. However, it's important to make note of the resources available for Rust testing. For information about Rust unit testing, see the documentation [here](https://mmapped.blog/posts/01-effective-rust-canisters.html#test-upgrades) and [here](https://mmapped.blog/posts/01-effective-rust-canisters.html#target-independent). @@ -152,7 +152,7 @@ cd e2e_tests ### Setting up the project -Then, we can remove the `src/e2e_tests_frontend` folder and any sub folders. We won't be using a frontend in this project. +Then, you can remove the `src/e2e_tests_frontend` folder and any sub folders. You won't be using a frontend in this project. ``` rm -r src/e2e_tests_frontend @@ -172,7 +172,7 @@ Then, remove the `e2e_tests_frontend` configuration from the `dfx.json` file. On } ``` -Next, we'll install `vitest` and `isomorphic-fetch` with the command: +Next, you'll install `vitest` and `isomorphic-fetch` with the command: ``` npm install --save-dev vitest isomorphic-fetch @@ -207,10 +207,10 @@ mkdir src/tests/ ### Creating an agent -Now, we'll create a mixture of JavaScript and TypeScript files to create a utility that'll be used to create an **agent** using generated declarations. This file will be called `actor.js`. +Now, you'll create a mixture of JavaScript and TypeScript files to create a utility that'll be used to create an **agent** using generated declarations. This file will be called `actor.js`. :::caution -We'll be diving a bit into using an **agent** in this portion of the tutorial. Note that we've briefly mentioned agents thus far in our developer journey, but we haven't fully explored agents yet. We will cover agents in a future tutorial, but for this tutorial it is important to know that an agent a library used to make calls to the Internet Computer public interface. We'll be using it to communicate the canister's public methods, defined in the `declarations/e2e_tests_backend/e2e_tests_backend.did.js`, to the file containing our the code for our tests. +You'll be diving a bit into using an **agent** in this portion of the tutorial. Note that the developer journey has briefly mentioned agents thus far, but hasn't fully explored agents yet. The developer journey will cover agents in a future tutorial, but for this tutorial it is important to know that an agent a library used to make calls to the Internet Computer public interface. You'll be using it to communicate the canister's public methods, defined in the `declarations/e2e_tests_backend/e2e_tests_backend.did.js`, to the file containing our the code for our tests. ::: Create a new file in `src/tests/` called `actor.js`, then insert the following content: @@ -244,7 +244,7 @@ This agent file does the following: - Sets up file handlers by reading the canister IDs from their associated JSON file. -- Fetches the root key since we are testing locally. +- Fetches the root key since you are testing locally. - Imports the interface description language (IDL) from the declarations file (`../declarations/e2e_tests_backend/e2e_tests_backend.did.js`). @@ -353,9 +353,9 @@ Then, run the test again with the `npm test` command. This time, the output shou ## Integration testing -Now that we have a mini tutorial project to use, we'll use it to demonstrate **continuous integration** testing. CI testing is a common automated testing workflow. One example of CI testing is done through Github, where a repository can be configured to run a test every time a change is pushed to the repository's code. +Now that you have a mini tutorial project to use, you'll use it to demonstrate **continuous integration** testing. CI testing is a common automated testing workflow. One example of CI testing is done through Github, where a repository can be configured to run a test every time a change is pushed to the repository's code. -Before we upload our code to Github, first edit the `package.json` file. In the `scripts` section of this file, add the following lines: +Before you upload your code to Github, first edit the `package.json` file. In the `scripts` section of this file, add the following lines: ``` "ci": "vitest run", @@ -438,7 +438,7 @@ Did you get stuck somewhere in this tutorial, or feel like you need additional h ## Next steps -To wrap up level 2 of our developer journey, we'll dive into Motoko level 2 and learn more about Motoko's fundamentals. +To wrap up level 2 of our developer journey, you'll dive into Motoko level 2 and learn more about Motoko's fundamentals. - [2.6 Motoko level 2](2.6-motoko-lvl2.md). diff --git a/docs/tutorials/developer-journey/level-2/2.6-motoko-lvl2.md b/docs/tutorials/developer-journey/level-2/2.6-motoko-lvl2.md index 28f0514c8a..29f79efd89 100644 --- a/docs/tutorials/developer-journey/level-2/2.6-motoko-lvl2.md +++ b/docs/tutorials/developer-journey/level-2/2.6-motoko-lvl2.md @@ -2,7 +2,7 @@ ## Overview -As we've seen so far in our developer journey, **actors** are at the core functionality of canisters written in Motoko. In this tutorial, we'll explore actors further by taking a look at actor type definitions, how actors interact with async data, actor classes, and using multiple actors. +As you've seen so far in our developer journey, **actors** are at the core functionality of canisters written in Motoko. In this tutorial, you'll explore actors further by taking a look at actor type definitions, how actors interact with async data, actor classes, and using multiple actors. ## Actor types @@ -68,13 +68,13 @@ A **shared function** immediately returns a value known as a **future**. This fu A shared function's arguments and return value(s) must also be shared types. This is a subset of data types that includes shared function references, actor references, and immutable data, but does not include references to local functions or mutable data. Since interactions with actors are asynchronous, an actor's functions must return types in the form `async T`, where T is the data type. -In the previous example, we used `async Nat`. Currently, shared functions can only be declared in the body of an actor or actor class. +In the previous example, you used `async Nat`. Currently, shared functions can only be declared in the body of an actor or actor class. ## Actors and async data -As we discussed earlier, shared functions must be executed asynchronously and therefore must return data types in the form of `async Type`. When a call is made to a shared function, the `await` expression must be used to access the result of the returned async value. +As you learned earlier, shared functions must be executed asynchronously and therefore must return data types in the form of `async Type`. When a call is made to a shared function, the `await` expression must be used to access the result of the returned async value. -To access the result of an async value, the receiver of the future use an `await` expression. For example, using the `Counter` actor we used previously, we can use the result of `Counter.read()` by binding the result value to an identifier (`a`), then await `a` to retrieve the `async Nat` return value, `n`: +To access the result of an async value, the receiver of the future use an `await` expression. For example, using the `Counter` actor you used previously, you can use the result of `Counter.read()` by binding the result value to an identifier (`a`), then await `a` to retrieve the `async Nat` return value, `n`: ```motoko let a : async Nat = Counter.read(); @@ -95,9 +95,9 @@ let n : Nat = await Counter.read(); ## Actor classes -Actor classes provide the ability for a series of actors to be created programmatically. To define actor classes, a separate classes source file needs to be used. We'll demonstrate how to define and import actor classes using the following example that implements a key-value store that maps keys (type `Nat`) to values (type `Text`). Then, it provides two functions, `insert` and `lookup`, which can be used for working with the key-value store. +Actor classes provide the ability for a series of actors to be created programmatically. To define actor classes, a separate classes source file needs to be used. This tutorial will demonstrate how to define and import actor classes using the following example that implements a key-value store that maps keys (type `Nat`) to values (type `Text`). Then, it provides two functions, `insert` and `lookup`, which can be used for working with the key-value store. -To distribute data, the set of keys (`k`) will be partitioned into `n` buckets. For this example, we'll set `n` as a fixed value of `8`. +To distribute data, the set of keys (`k`) will be partitioned into `n` buckets. For this example, you'll set `n` as a fixed value of `8`. The bucket index value (`i`) for the value of `k`, will be determined by the remainder value of `k` divided by `n`. Then, the `i`th bucket will receive a dedicated actor used to store the text values (`v`) associated with the keys in the bucket. @@ -143,7 +143,7 @@ Both the functions `get(k)` and `put(k, v)` use the `class` parameters of `n` an ### Defining an actor within the actor class -Then, we'll implement a coordinating `Map` actor in a file called `Map.mo`: +Then, you'll implement a coordinating `Map` actor in a file called `Map.mo`: ```motoko import Array "mo:base/Array"; @@ -210,9 +210,9 @@ Want to learn more about actor classes? Take a look at the documentation on [act ## Using multiple actors -Until this point in our developer journey, we've interacted with one actor defined in our `backend` canister Motoko file. Next, we're going to create a project that uses multiple actors. Remember that only one actor can be defined in a Motoko file, and a single actor is always compiled into a single canister. To create multiple actors, we'll create multiple Motoko files and build multiple canisters. To do this, we'll define two canisters in our project's `dfx.json` configuration file. +Until this point in our developer journey, you've interacted with one actor defined in our `backend` canister Motoko file. Next, you're going to create a project that uses multiple actors. Remember that only one actor can be defined in a Motoko file, and a single actor is always compiled into a single canister. To create multiple actors, you'll create multiple Motoko files and build multiple canisters. To do this, you'll define two canisters in your project's `dfx.json` configuration file. -We'll create two actors unrelated to one another: +You'll create two actors unrelated to one another: - A `characterCount` actor which takes a string, counts it's length, then returns a `Bool` value if the total length of the string is divisible by `2`. @@ -234,7 +234,7 @@ cd multiple_actors ### Configuring canisters in `dfx.json` -As we've seen in previous portions of our developer journey, when a new project is created with `dfx`, a default `dfx.json` file is created in the project's directory. For this guide, we'll need to edit `dfx.json` to specify our three canisters and the location of their Motoko files. +As you've seen in previous portions of our developer journey, when a new project is created with `dfx`, a default `dfx.json` file is created in the project's directory. For this guide, you'll need to edit `dfx.json` to specify our three canisters and the location of their Motoko files. First, open the `dfx.json` file in your code editor. Delete the existing content and replace it with the following: @@ -259,18 +259,18 @@ First, open the `dfx.json` file in your code editor. Delete the existing content } ``` -In this file, we can see the definition for each of our three canisters with correlate with each of our three actors. Each canister's Motoko file is configured to be at `src/CANISTER_NAME/main.mo`. Since these directories and files do not exist yet, the next step is to create them. +In this file, you can see the definition for each of your three canisters with correlate with each of your three actors. Each canister's Motoko file is configured to be at `src/CANISTER_NAME/main.mo`. Since these directories and files do not exist yet, the next step is to create them. ### Creating canister directories and Motoko files -First, we'll remove the default canister files created by `dfx` since we won't be using them: +First, you'll remove the default canister files created by `dfx` since you won't be using them: ``` rm -r src/multiple_actors_backend/ rm -r src/multiple_actors_frontend/ ``` -Then, we'll create new directories for each of our canisters and create an empty `main.mo` file in each: +Then, you'll create new directories for each of your canisters and create an empty `main.mo` file in each: ``` mkdir src/character_count && touch src/character_count/main.mo @@ -358,7 +358,7 @@ URLs: ### Interacting with multiple actors -Once the canisters containing our actors have been deployed, we can interact with each actor using the `dfx canister call` command. For example, to use the `characterCount` actor, you can make a call to the `character_count` canister such as: +Once the canisters containing your actors have been deployed, you can interact with each actor using the `dfx canister call` command. For example, to use the `characterCount` actor, you can make a call to the `character_count` canister such as: ``` dfx canister call character_count test '("Developer Journey")' @@ -396,7 +396,7 @@ Did you get stuck somewhere in this tutorial, or feel like you need additional h ## Next steps -That'll wrap up level 2 of our developer journey! In the next level, we'll start by taking a look at using package managers for Motoko. +That'll wrap up level 2 of our developer journey! In the next level, you'll start by taking a look at using package managers for Motoko. - [3.1 Using libraries with MOPS](../level-3/3.1-package-managers.md). diff --git a/docs/tutorials/developer-journey/level-2/index.md b/docs/tutorials/developer-journey/level-2/index.md index e7b34758a4..f6d1fbf476 100644 --- a/docs/tutorials/developer-journey/level-2/index.md +++ b/docs/tutorials/developer-journey/level-2/index.md @@ -13,7 +13,7 @@ - Deploying your counter app. - Stable variables in action. -- [2.2 Advanced canister calls](2.2-advanced-canister-calls.md): Now that we've covered the core functionalities of canisters and using them, let's take a look at advanced canister calls. This module covers: +- [2.2 Advanced canister calls](2.2-advanced-canister-calls.md): Now that you've covered the core functionalities of canisters and using them, let's take a look at advanced canister calls. This module covers: - The IC execution model. - Canister query calls. - Example query call. diff --git a/docs/tutorials/developer-journey/level-3/3.1-package-managers.md b/docs/tutorials/developer-journey/level-3/3.1-package-managers.md index a9f6816ac5..6437bf08ba 100644 --- a/docs/tutorials/developer-journey/level-3/3.1-package-managers.md +++ b/docs/tutorials/developer-journey/level-3/3.1-package-managers.md @@ -2,7 +2,7 @@ ## Overview -[Mops](https://mops.one) and [Vessel](https://github.com/dfinity/vessel) are package managers for Motoko. In this guide, we'll explore how to download and install Mops and Vessel, then how to import and use different libraries that have been downloaded through a package manager. +[Mops](https://mops.one) and [Vessel](https://github.com/dfinity/vessel) are package managers for Motoko. In this guide, you'll explore how to download and install Mops and Vessel, then how to import and use different libraries that have been downloaded through a package manager. ## What is a package manager? @@ -145,7 +145,7 @@ Then, edit your `dfx.json` file to use the `packtool` of `vessel sources`: Once a package has been installed, whether it was installed using Mops or Vessel, you can import them into your Motoko code file using the line `import PackageName "mo:";`. -We've used this command in previous Motoko code examples to import packages such as the Motoko `base` library. For example, recall the `characterCount` actor code from the previous module [2.6: Motoko level 2](../level-2/2.6-motoko-lvl2.md): +You've used this command in previous Motoko code examples to import packages such as the Motoko `base` library. For example, recall the `characterCount` actor code from the previous module [2.6: Motoko level 2](../level-2/2.6-motoko-lvl2.md): ```motoko import Text "mo:base/Text"; diff --git a/docs/tutorials/developer-journey/level-3/3.2-https-outcalls.md b/docs/tutorials/developer-journey/level-3/3.2-https-outcalls.md index 9e261a10e2..1ed2f5357b 100644 --- a/docs/tutorials/developer-journey/level-3/3.2-https-outcalls.md +++ b/docs/tutorials/developer-journey/level-3/3.2-https-outcalls.md @@ -7,14 +7,14 @@ In the past, blockchain networks were only able to communicate with external ser HTTPS outcalls are a feature of canisters on the IC that allow smart contracts to directly make calls to HTTPS servers that are external to the IC. The response of these HTTPS calls can then be used by the smart contract in a way that the replica can safely be updated using the response without the risk of a state divergence. :::info -In this guide, we use the term **HTTPS** to refer to both the **HTTP** and **HTTPS** protocols. This is because typically all traffic on a public network uses the secure HTTPS protocol. +This guide uses the term **HTTPS** to refer to both the **HTTP** and **HTTPS** protocols. This is because typically all traffic on a public network uses the secure HTTPS protocol. ::: HTTPS outcalls provide the ability for different use cases and have several advantages compared to using oracles to handle external requests. Some of these are HTTPS outcalls use a stronger trust model since there are no external intermediaries, such as an oracle, required for the canister to communicate with external servers, and using HTTPS outcalls for communicating with external servers makes using canisters feel much closer to a "traditional" programming workflow that may not use blockchains or oracles. Most real-world dapps have a need for accessing data stored in off-chain entities, since most digital data is still stored in traditional, 'Web 2', services. ## Supported HTTPS methods -Currently, HTTPS outcalls support `GET`, `HEAD`, and `POST` methods for HTTPS requests. In this guide, we'll look at examples for `GET` and `POST` methods. +Currently, HTTPS outcalls support `GET`, `HEAD`, and `POST` methods for HTTPS requests. In this guide, you'll look at examples for `GET` and `POST` methods. ## Cycles @@ -54,7 +54,7 @@ When deploying applications to the Internet Computers, HTTPS outcalls can **only ## HTTPS `GET` -To demonstrate how to use the HTTPS `GET` outcall, we'll create a simple canister that has one public method named `get_icp_usd_exchange()`. This method will trigger an HTTP `GET` request to the external service Coinbase, which will return current data on the exchange rate between USD and ICP. This canister will have no frontend, and we will interact with its public methods via the Candid web UI. +To demonstrate how to use the HTTPS `GET` outcall, you'll create a simple canister that has one public method named `get_icp_usd_exchange()`. This method will trigger an HTTP `GET` request to the external service Coinbase, which will return current data on the exchange rate between USD and ICP. This canister will have no frontend, and you will interact with its public methods via the Candid web UI. ### Prerequisites @@ -85,7 +85,7 @@ import Nat64 "mo:base/Nat64"; import Text "mo:base/Text"; ``` -This piece of code imports the libraries that we'll be using. Each of these libraries is part of the Motoko base package, as indicated by 'mo:base'. +This piece of code imports the libraries that you'll be using. Each of these libraries is part of the Motoko base package, as indicated by 'mo:base'. Next, insert the following line below these import statements: @@ -93,9 +93,9 @@ Next, insert the following line below these import statements: import Types "Types"; ``` -This line imports the custom types stored in `Types.mo`. We'll create this file later. +This line imports the custom types stored in `Types.mo`. You'll create this file later. -Following the `import Types "Types";` line, now let's insert the code to define our actor. This actor will contain two functions; a function to transform the response that we'll receive from our `GET` response, and a function that sends our `GET` request. The code has been annotated with notes describing in detail what each piece does: +Following the `import Types "Types";` line, now let's insert the code to define our actor. This actor will contain two functions; a function to transform the response that you'll receive from our `GET` response, and a function that sends our `GET` request. The code has been annotated with notes describing in detail what each piece does: ```motoko actor { @@ -107,7 +107,7 @@ actor { //First, declare the IC management canister let ic : Types.IC = actor ("aaaaa-aa"); - //Next, we need to set the arguments for our GET request + //Next, you need to set the arguments for our GET request // Start with the URL and its query parameters @@ -124,7 +124,7 @@ actor { { name = "User-Agent"; value = "exchange_rate_canister" }, ]; - // Next, we define a function to transform the request's context from a blob datatype to an array. + // Next, you define a function to transform the request's context from a blob datatype to an array. let transform_context : Types.TransformContext = { function = transform; @@ -142,22 +142,22 @@ actor { transform = ?transform_context; }; - // Now, we need to add some cycles to our call, since cycles to pay for the call must be transferred with the call. + // Now, you need to add some cycles to your call, since cycles to pay for the call must be transferred with the call. // The way Cycles.add() works is that it adds those cycles to the next asynchronous call. // "Function add(amount) indicates the additional amount of cycles to be transferred in the next remote call". // See: https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-http_request Cycles.add(20_949_972_000); - // Now that we have the HTTP request and cycles to send with the call, we can make the HTTP request and await the response. + // Now that you have the HTTP request and cycles to send with the call, you can make the HTTP request and await the response. let http_response : Types.HttpResponsePayload = await ic.http_request(http_request); - // Once we have the response, we need to decode it. The body of the HTTP response should come back as [Nat8], which needs to be decoded into readable text. - // To do this, we: + // Once you have the response, you need to decode it. The body of the HTTP response should come back as [Nat8], which needs to be decoded into readable text. + // To do this, you: // 1. Convert the [Nat8] into a Blob // 2. Use Blob.decodeUtf8() method to convert the Blob to a ?Text optional - // 3. We use a switch to explicitly call out both cases of decoding the Blob into ?Text + // 3. Use a switch to explicitly call out both cases of decoding the Blob into ?Text let response_body: Blob = Blob.fromArray(http_response.body); let decoded_text: Text = switch (Text.decodeUtf8(response_body)) { @@ -165,7 +165,7 @@ actor { case (?y) { y }; }; - // Finally, we can return the response of the body. + // Finally, you can return the response of the body. // The API response will looks like this: @@ -412,7 +412,7 @@ module Types { }; - // Lastly, declare the IC management canister which we use to make the HTTPS outcall. + // Lastly, declare the IC management canister which you use to make the HTTPS outcall. public type IC = actor { http_request : HttpRequestArgs -> async HttpResponsePayload; }; @@ -422,7 +422,7 @@ module Types { The code above is annotated with detailed notes and explanations. Take a moment to read through the code's content and annotations to fully understand the code's functionality. -Now, we can deploy the canister locally with the commands: +Now, you can deploy the canister locally with the commands: ``` dfx start --background --clean @@ -450,7 +450,7 @@ You can play with a version of this canister running on-chain here: https://a4gq ## HTTPS `POST` -To demonstrate how to use the HTTPS `POST` outcall, we'll create a simple canister that has one public method named `send_http_post_request()`. This method will trigger an HTTP `POST` request to a public API service where the HTTPS request can be inspected and we can inspect the request's headers and body to validate that it reflects what the canister sent. +To demonstrate how to use the HTTPS `POST` outcall, you'll create a simple canister that has one public method named `send_http_post_request()`. This method will trigger an HTTP `POST` request to a public API service where the HTTPS request can be inspected and you can inspect the request's headers and body to validate that it reflects what the canister sent. The following are some important notes on `POST` requests: @@ -462,7 +462,7 @@ The following are some important notes on `POST` requests: ### Creating a new project -For simplicity, we'll create a new project for our HTTP `POST` request. Navigate into your working directory and create another new project: +For simplicity, you'll create a new project for our HTTP `POST` request. Navigate into your working directory and create another new project: ``` dfx new https_post @@ -484,7 +484,7 @@ import Text "mo:base/Text"; import Types "Types"; ``` -This code is the same way we started out HTTPS `GET` code. Now, we'll define an actor using that contain two functions; a function to transform the response that we'll receive from our `POST` response, and a function that sends our `POST` request. The code has been annotated with notes describing in detail what each piece does: +This code is the same way you started your HTTPS `GET` code. Now, you'll define an actor using that contain two functions; a function to transform the response that you'll receive from our `POST` response, and a function that sends our `POST` request. The code has been annotated with notes describing in detail what each piece does: ```motoko actor { @@ -523,7 +523,7 @@ actor { let host : Text = "putsreq.com"; let url = "https://putsreq.com/aL1QS5IbaQd4NTqN3a81"; - // Then, prepare headers for the system http_request call. Note that idempotency keys should be unique, so we create a function that generates them. + // Then, prepare headers for the system http_request call. Note that idempotency keys should be unique, so you create a function that generates them. let idempotency_key: Text = generateUUID(); let request_headers = [ @@ -533,9 +533,9 @@ actor { { name= "Idempotency-Key"; value = idempotency_key } ]; - // Since the the request body is an array of [Nat8], next we do the following: + // Since the the request body is an array of [Nat8], next you do the following: // 1. Write a JSON string - // 2. Convert ?Text optional into a Blob, which is an intermediate representation before we cast it as an array of [Nat8] + // 2. Convert ?Text optional into a Blob, which is an intermediate representation before you cast it as an array of [Nat8] // 3. Convert the Blob into an array [Nat8] let request_body_json: Text = "{ \"name\" : \"Grogu\", \"force_sensitive\" : \"true\" }"; @@ -543,39 +543,39 @@ actor { let request_body_as_nat8: [Nat8] = Blob.toArray(request_body_as_Blob); // e.g [34, 34,12, 0] - // Then we transform the content + // Then you transform the content let transform_context : Types.TransformContext = { function = transform; context = Blob.fromArray([]); }; - // Next, we make the POST request + // Next, you make the POST request let http_request : Types.HttpRequestArgs = { url = url; max_response_bytes = null; //optional for request headers = request_headers; - //note: type of `body` is ?[Nat8] so we pass it here as "?request_body_as_nat8" instead of "request_body_as_nat8" + //note: type of `body` is ?[Nat8] so you pass it here as "?request_body_as_nat8" instead of "request_body_as_nat8" body = ?request_body_as_nat8; method = #post; transform = ?transform_context; }; - // Now, we need to add some cycles to our call, since cycles to pay for the call must be transferred with the call. + // Now, you need to add some cycles to your call, since cycles to pay for the call must be transferred with the call. // The way Cycles.add() works is that it adds those cycles to the next asynchronous call // "Function add(amount) indicates the additional amount of cycles to be transferred in the next remote call" // See: https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-http_request Cycles.add(21_850_258_000); - // Now that we have the HTTP request and cycles to send with the call, we can make the HTTP request and await the response. + // Now that you have the HTTP request and cycles to send with the call, you can make the HTTP request and await the response. let http_response : Types.HttpResponsePayload = await ic.http_request(http_request); - // Once we have the response, we need to decode it. The body of the HTTP response should come back as [Nat8], which needs to be decoded into readable text. - // To do this, we: + // Once you have the response, you need to decode it. The body of the HTTP response should come back as [Nat8], which needs to be decoded into readable text. + // To do this, you: // 1. Convert the [Nat8] into a Blob // 2. Use Blob.decodeUtf8() method to convert the Blob to a ?Text optional - // 3. We use Motoko syntax "Let... else" to unwrap what is returned from Text.decodeUtf8() + // 3. Use Motoko syntax "Let... else" to unwrap what is returned from Text.decodeUtf8() let response_body: Blob = Blob.fromArray(http_response.body); let decoded_text: Text = switch (Text.decodeUtf8(response_body)) { @@ -583,12 +583,12 @@ actor { case (?y) { y }; }; - // Finally, we can return the response of the body. + // Finally, you can return the response of the body. let result: Text = decoded_text # ". See more info of the request sent at at: " # url # "/inspect"; result }; - // As a final step, we define a private helper function that generates a universally unique identifier. In this exercise, it returns a constant but in practice it should return a unique identifier. + // As a final step, you define a private helper function that generates a universally unique identifier. In this exercise, it returns a constant but in practice it should return a unique identifier. func generateUUID() : Text { "UUID-123456789"; @@ -663,7 +663,7 @@ actor { url = url; max_response_bytes = null; //optional for request headers = request_headers; - //note: type of `body` is ?[Nat8] so we pass it here as "?request_body_as_nat8" instead of "request_body_as_nat8" + //note: type of `body` is ?[Nat8] so you pass it here as "?request_body_as_nat8" instead of "request_body_as_nat8" body = ?request_body_as_nat8; method = #post; transform = ?transform_context; @@ -679,7 +679,7 @@ actor { case (?y) { y }; }; - // Finally, we can return the response of the body. + // Finally, you can return the response of the body. let result: Text = decoded_text # ". See more info of the request sent at at: " # url # "/inspect"; result }; @@ -755,7 +755,7 @@ module Types { }; - // Lastly, declare the IC management canister which we use to make the HTTPS outcall. + // Lastly, declare the IC management canister which you use to make the HTTPS outcall. public type IC = actor { http_request : HttpRequestArgs -> async HttpResponsePayload; }; @@ -765,7 +765,7 @@ module Types { The code above is annotated with detailed notes and explanations. Take a moment to read through the code's content and annotations to fully understand the code's functionality. -Now, we can deploy the canister locally with the commands: +Now, you can deploy the canister locally with the commands: ``` dfx start --background --clean diff --git a/docs/tutorials/developer-journey/level-3/3.3-certified-data.md b/docs/tutorials/developer-journey/level-3/3.3-certified-data.md index 751143ff89..73fdfcdd9f 100644 --- a/docs/tutorials/developer-journey/level-3/3.3-certified-data.md +++ b/docs/tutorials/developer-journey/level-3/3.3-certified-data.md @@ -2,7 +2,7 @@ ## Overview -In a previous module, [2.2: Advanced canister calls](../level-2/2.2-advanced-canister-calls.md), we briefly touched on certified variables. In this guide, we'll dive deeper into certified data and take a look at an example that displays how to use certified data. +In a previous module, [2.2: Advanced canister calls](../level-2/2.2-advanced-canister-calls.md), you briefly touched on certified variables. In this guide, you'll dive deeper into certified data and take a look at an example that displays how to use certified data. Recall that certified variables are used as a way for queries to return an authenticated response that can be validated and trusted, since query calls do not go through consensus and therefore their response cannot be certified. By utilizing certified variables, developers can make query calls that return an authenticated response that they can trust. This allows for workflows that require additional layers of authentication, such as applications that handle financial data or important records. For users of the application, they can be assured that the information they're interacting with and receiving from the application is trustworthy and secure as well. @@ -103,7 +103,7 @@ More information can be found on in the [HTTP gateway protocol specification](/d ### Example -To demonstrate the concepts we've covered thus far, we'll take a look at the `/index.html` asset of the Internet Identity canister (canister ID `rdmx6-jaaaa-aaaaa-aaadq-cai`). The SHA-256 hash of this asset at the time it was retrieved was `478afb8206ca0b566a7f138e623accd169fa822602d2f6d717fb67d1045f4f0d`. The response contained the following header: +To demonstrate the concepts you've learned thus far, you'll take a look at the `/index.html` asset of the Internet Identity canister (canister ID `rdmx6-jaaaa-aaaaa-aaadq-cai`). The SHA-256 hash of this asset at the time it was retrieved was `478afb8206ca0b566a7f138e623accd169fa822602d2f6d717fb67d1045f4f0d`. The response contained the following header: ``` IC-Certificate: certificate=:2dn3omR0cmVlgwGDAYMBgwJIY2FuaXN0ZXKDAYMBggRYIIudikoDwH1gRK637olblUhMUX3HlE0Dihj8MTACxGzHgwGCBFggyCRYc8M/ugt8G7C8RPYayn+l4sdBj8gvFotzJELnQ32DAYIEWCA1/+UHZ9SF67w4ssjOi+Jv3ch7WQNzezGmhtuvB+RDpYMCSgAAAAAAAAAHAQGDAYMBgwJOY2VydGlmaWVkX2RhdGGCA1ggWUt10wjWinx0aAWyrNEi/0R7VeuhalDMjGDErzIbZzqCBFgg/VtZRZdYyK/sr3KF2jWeS1rblF+4ajwfDv2ZbCGpaTiCBFggSoI5JS0pCusHP4nh6h780ebr961E0lVnFkFwzF5pZaeCBFggcKidPEGiPoFMPYfEyNGsDRYWmry1iGX0HNUEoKhIATeCBFggR0zdKUZOMcm5EHNl5Tee3XWqbq1gArwUGzZ2FH4rWtmCBFggTkwJcNrh0eJ9FutJcn6th9eCbM2KXnloxed0acxmQNeDAYIEWCA6SNH8IT1JMHEDEE99csK1kw7bqHh7kGMfNDs6popfCoMCRHRpbWWCA0nFnbXrts/65xZpc2lnbmF0dXJlWDCkXN2tcvH5b+xFCzfkuJMqrZDcplfW8vDziJwzx08WOPI4rh2TIGYZ3R6dgQTF0CA=:, tree=:2dn3gwGDAktodHRwX2Fzc2V0c4MBggRYIDgtAGcz5VvevwiEwwZB9zpkt17C9LE6o/O37bEwQUawgwGDAksvaW5kZXguaHRtbIIDWCBHivuCBsoLVmp/E45iOszRafqCJgLS9tcX+2fRBF9PDYIEWCCx2L8SfJwOydBkUxjc8tKXDVUeoiw8qEYI+8b+HRWIWYIEWCAqZ+3yoFSA9s+jbLFbtcVz+wi0HF9x51Kx38qPcBhiDA==: @@ -167,13 +167,13 @@ HashTree { ## Using certified variables -Now that we've covered the fundamental concepts behind certified data, let's take a look at a working example using certified variables. In this example, we'll demonstrate the certification of an HTTP response using a simple interface to store both the response and the certification through a single call. +Now that you've covered the fundamental concepts behind certified data, let's take a look at a working example using certified variables. In this example, you'll demonstrate the certification of an HTTP response using a simple interface to store both the response and the certification through a single call. ### Prerequisites Before you start, verify that you have set up your developer environment according to the instructions in [0.3: Developer environment setup](../level-0/03-dev-env.md). -You will also need to install Mops, which we covered in the previous module [3.1: Motoko package managers](3.1-package-managers.md). +You will also need to install Mops, which was covered in the previous module [3.1: Motoko package managers](3.1-package-managers.md). ### Creating a new project @@ -315,7 +315,7 @@ Timestamp is: % ``` -Then, if we use this call again, the request will be returned automatically without the request having to be upgraded to an update request: +Then, if you use this call again, the request will be returned automatically without the request having to be upgraded to an update request: ``` 2023-10-02 22:42:09.868110 UTC: [Canister bkyz2-fmaaa-aaaaa-qaaaq-cai] IC certified assets demo
Request has been stored in cache: 
diff --git a/docs/tutorials/developer-journey/level-3/3.4-intro-to-agents.md b/docs/tutorials/developer-journey/level-3/3.4-intro-to-agents.md
index c957210244..7315524df0 100644
--- a/docs/tutorials/developer-journey/level-3/3.4-intro-to-agents.md
+++ b/docs/tutorials/developer-journey/level-3/3.4-intro-to-agents.md
@@ -8,7 +8,7 @@ When you have a canister running, either locally or on the mainnet, you have two
 
 ### Structuring data
 
-One of the first responsibilities of an agent is to structure data. As we've discussed in previous modules, such as [2.2: Advanced canister calls](../level-2/2.2-advanced-canister-calls.md), calls to the IC can be an update or a query call. An agent submits a `POST` request to the canister's API at the URL `/api/v2/canister//call`. This post request contains the following components:
+One of the first responsibilities of an agent is to structure data. As was discussed in previous modules, such as [2.2: Advanced canister calls](../level-2/2.2-advanced-canister-calls.md), calls to the IC can be an update or a query call. An agent submits a `POST` request to the canister's API at the URL `/api/v2/canister//call`. This post request contains the following components:
 
 - `request_type`.
 - Authentication, comprised of the `sender`, `nonce`, and `ingress_expiry`. 
@@ -90,7 +90,7 @@ npm install
 
 ### Generating Candid declarations 
 
-For this example, we'll use an example project that takes a variable size input and generates a random maze using that size. For example, if `6` is entered, a 6x6 maze will be generated. Recall  that Motoko projects have the ability to autogenerate the project's Candid files. Let's start with generating those Candid files with the command:
+For this example, you'll use an example project that takes a variable size input and generates a random maze using that size. For example, if `6` is entered, a 6x6 maze will be generated. Recall  that Motoko projects have the ability to autogenerate the project's Candid files. Let's start with generating those Candid files with the command:
 
 ```
 dfx generate
@@ -120,7 +120,7 @@ service : {
 }
 ```
 
-Recall that this Candid interface specification defines a service interface with a single method. The single method, `generate` accepts a single argument of type `Nat` and returns type `Text`. This is because we will enter a number (`Nat`) to generate the maze, which will then be displayed using emoji characters displayed using type `Text`. Recall that unless a call is defined as a query, all calls are treated as an update call by default. 
+Recall that this Candid interface specification defines a service interface with a single method. The single method, `generate` accepts a single argument of type `Nat` and returns type `Text`. This is because you will enter a number (`Nat`) to generate the maze, which will then be displayed using emoji characters displayed using type `Text`. Recall that unless a call is defined as a query, all calls are treated as an update call by default. 
 
 In JavaScript, type `Text` maps to type `String`. You can see a full mapping list of Candid types and their JavaScript equivalents in the [Candid types reference.](/docs/current/references/candid-ref).
 
@@ -146,7 +146,7 @@ export const init = ({ IDL }) => { return []; };
 
 In this file, the `idlFactory` function is defined. This handles the structuring of the network calls according to the Internet Computer API and the application's Candid declaration. Unlike the declarations in the `src/declarations/random_maze/random_maze.did.d.ts` file, the `idlFactory` must be available during the application's runtime. To accomplish this, the `idlFactory` gets loaded by an actor. 
 
-In this example, the `idlFactory` represents a service with a `generate` method using the same two arguments we defined before (type `Nat` and type `Text`), though it includes a third argument of an empty array, which represents additional annotations that the function may be tagged with, such as 'query'. 
+In this example, the `idlFactory` represents a service with a `generate` method using the same two arguments you defined before (type `Nat` and type `Text`), though it includes a third argument of an empty array, which represents additional annotations that the function may be tagged with, such as 'query'. 
 
 ### Creating the JavaScript agent
 
diff --git a/docs/tutorials/developer-journey/level-3/3.5-identities-and-auth.md b/docs/tutorials/developer-journey/level-3/3.5-identities-and-auth.md
index 1c463eb9d2..fd18461cf3 100644
--- a/docs/tutorials/developer-journey/level-3/3.5-identities-and-auth.md
+++ b/docs/tutorials/developer-journey/level-3/3.5-identities-and-auth.md
@@ -2,13 +2,13 @@
 
 ## Overview
 
-When developing on the Internet Computer, there are several types of identities and methods of authentication that you'll encounter. In the previous module where we obtained a cycles coupon, [1.4: acquiring and using cycles](../level-1/1.4-using-cycles.md), we created a **developer identity** that we used to create a **cycles wallet** to hold our cycles. We also looked at how to convert ICP tokens stored in a **ledger account** into cycles. 
+When developing on the Internet Computer, there are several types of identities and methods of authentication that you'll encounter. In the previous module where you obtained a cycles coupon, [1.4: acquiring and using cycles](../level-1/1.4-using-cycles.md), you created a **developer identity** that you used to create a **cycles wallet** to hold our cycles. You also looked at how to convert ICP tokens stored in a **ledger account** into cycles. 
 
 These three types of authentication are used for interacting with canisters and cycles, but what about interacting with applications or websites built on the IC? For that, end-users can use **Internet Identity**, the IC's native form of digital identity that can be used to authenticate with apps, such as the NNS dashboard, without having to manage a username or password. Instead, Internet Identity uses a cryptographic key pair that's stored in your local computer's hardware. Through this simple and flexible authentication method, developers can provide end-users with a frictionless way to authenticate and use their application. 
 
 ## Types of identity
 
-First, let's clearly define the difference between the different types of identity and authentication on the Internet Computer. As we've already covered some of these in previous modules, some of this will be a review.
+First, let's clearly define the difference between the different types of identity and authentication on the Internet Computer. As you've already covered some of these in previous modules, some of this will be a review.
 
 - **Developer identity**: created using `dfx`. It contains a private/public key pair, and has a `principal` data type derived from the public key.  It can be compared to a Bitcoin or Ethereum wallet address.
 
@@ -22,7 +22,7 @@ First, let's clearly define the difference between the different types of identi
 
 - **Internet Identity**: the IC's native authentication service. Internet Identity doesn't use usernames and passwords; instead it uses a **passkey** that is stored in your local device's hardware.
 
-In this guide, we'll primarily look at how to use Internet Identity, as the other forms of identity have been covered in previous modules.
+In this guide, you'll primarily look at how to use Internet Identity, as the other forms of identity have been covered in previous modules.
 
 ## Internet Identity
 
@@ -111,18 +111,18 @@ actor {
 };
 ```
 
-In this code, the actor has one method, `whoami`, which responds with the message's caller. We'll use this to test if we make a request from the frontend using an `AnonymousIdentity` or an authenticated Internet Identity.
+In this code, the actor has one method, `whoami`, which responds with the message's caller. You'll use this to test if you make a request from the frontend using an `AnonymousIdentity` or an authenticated Internet Identity.
 
 ### Importing the auth-client package
 
-Next, let's take a look at the assets for the frontend of the application. This demo project comes with a few different options for the frontend, such as React and Vue, but we'll stick with using the vanilla JavaScript option. If we take a look at the `src/auth_client_demo_assets/vanilla/index.ts` file, we can see that first, we import the `AuthClient` from `@dfinity/auth-client`:
+Next, let's take a look at the assets for the frontend of the application. This demo project comes with a few different options for the frontend, such as React and Vue, but for this guide you'll stick with using the vanilla JavaScript option. If you take a look at the `src/auth_client_demo_assets/vanilla/index.ts` file, you can see that first, you import the `AuthClient` from `@dfinity/auth-client`:
 
 ```typescript
 import { AuthClient } from "@dfinity/auth-client";
 import { handleAuthenticated, renderIndex } from "./views";
 ```
 
-Then, we define some variables to define a day in nanoseconds:
+Then, you define some variables to define a day in nanoseconds:
 
 ```typescript
 // One day in nanoseconds
@@ -131,7 +131,7 @@ const hours = BigInt(24);
 const nanoseconds = BigInt(3600000000000);
 ```
 
-Next, we'll set some default options, including the `loginOptions`, which will allow the `identityProvider` to be either the II mainnet canister if you are using the local environmental variable `DFX_NETWORK` set to `ic`, or the locally deployed II canister. Your local replica will not accept signatures from the mainnet canister. 
+Next, you'll set some default options, including the `loginOptions`, which will allow the `identityProvider` to be either the II mainnet canister if you are using the local environmental variable `DFX_NETWORK` set to `ic`, or the locally deployed II canister. Your local replica will not accept signatures from the mainnet canister. 
 
 ```typescript
 export const defaultOptions = {
@@ -152,7 +152,7 @@ export const defaultOptions = {
 };
 ```
 
-Now, let's initialize the AuthClient. Then, we check to see if the user has previously logged in. If so, their previous identity is verified:
+Now, let's initialize the AuthClient. Then, you check to see if the user has previously logged in. If so, their previous identity is verified:
 
 ```typescript
 const init = async () => {
@@ -166,7 +166,7 @@ const init = async () => {
 };
 ```
 
-Lastly, we define a function that listens for the button on the frontend to be clicked and initialize the client:
+Lastly, you define a function that listens for the button on the frontend to be clicked and initialize the client:
 
 ```typescript
 async function setupToast() {
@@ -183,7 +183,7 @@ init();
 
 ### Pulling the Internet Identity canister
 
-Now, if you noticed we didn't create a canister for the Internet Identity service. That's because, if we take a look at this project's `dfx.json` file, we **pull** the Internet Identity canister from the mainnet. This is an example of using the `dfx deps` functionality, which we covered in [2.3: Using third-party canisters](../level-2/2.3-third-party-canisters.md).
+Now, if you noticed you didn't create a canister for the Internet Identity service. That's because, if you take a look at this project's `dfx.json` file, you **pull** the Internet Identity canister from the mainnet. This is an example of using the `dfx deps` functionality, which you covered in [2.3: Using third-party canisters](../level-2/2.3-third-party-canisters.md).
 
 ```json
 {
@@ -243,7 +243,7 @@ Now let's deploy this project locally. First, pull the II canister using `dfx de
 dfx deps pull
 ```
 
-Then, we need to initialize the canister. By running the `dfx deps init` command, it'll show that our II canister requires an init argument:
+Then, you need to initialize the canister. By running the `dfx deps init` command, it'll show that our II canister requires an init argument:
 
 ```
 dfx deps init
@@ -254,7 +254,7 @@ WARN: The following canister(s) require an init argument. Please run `dfx deps i
 rdmx6-jaaaa-aaaaa-aaadq-cai (internet_identity)
 ```
 
-This output shows us that the Internet Identity canister requires an init argument, but doesn't include what that init argument is. For more information, run the command `dfx deps init rdmx6-jaaaa-aaaaa-aaadq-cai`, which will provide an error message that includes more information:
+This output shows you that the Internet Identity canister requires an init argument, but doesn't include what that init argument is. For more information, run the command `dfx deps init rdmx6-jaaaa-aaaaa-aaadq-cai`, which will provide an error message that includes more information:
 
 ```
 Error: Canister rdmx6-jaaaa-aaaaa-aaadq-cai (internet_identity) requires an init argument. The following info might be helpful:
@@ -262,13 +262,13 @@ init => Use '(null)' for sensible defaults. See the candid interface for more de
 candid:args => (opt InternetIdentityInit)
 ```
 
-From this error message, we can see that the `(null)` value can be passed to the init command to use the defaults. To do so, run the command:
+From this error message, you can see that the `(null)` value can be passed to the init command to use the defaults. To do so, run the command:
 
 ```
 dfx deps init rdmx6-jaaaa-aaaaa-aaadq-cai --argument null
 ```
 
-Then, we can deploy the II canister and the other canisters in the project with the command:
+Then, you can deploy the II canister and the other canisters in the project with the command:
 
 ```
 dfx deps deploy
@@ -297,7 +297,7 @@ Navigate to the 'Local' URL in your web browser. You will see the frontend of th
 
 ![Local integration](../_attachments/II-int-1.png)
 
-Then, select 'Log in'. You'll be redirected to the II frontend. Since we're running this locally, note that this is for **testing** only, and you should not use your production II. It is recommended to create another for local testing purposes. To do so, follow the on-screen steps that we walked through previously.
+Then, select 'Log in'. You'll be redirected to the II frontend. Since you're running this locally, note that this is for **testing** only, and you should not use your production II. It is recommended to create another for local testing purposes. To do so, follow the on-screen steps that you walked through previously.
 
 ![Local integration 2](../_attachments/II_2.png)
 
@@ -333,7 +333,7 @@ Did you get stuck somewhere in this tutorial, or feel like you need additional h
 
 ## Next steps
 
-Next, we'll take a look at Motoko level 3:
+Next, you'll take a look at Motoko level 3:
 
 - [3.6 Motoko level 3](3.6-motoko-lvl3.md).
 
diff --git a/docs/tutorials/developer-journey/level-3/3.6-motoko-lvl3.md b/docs/tutorials/developer-journey/level-3/3.6-motoko-lvl3.md
index cc39e8f1ed..936085f023 100644
--- a/docs/tutorials/developer-journey/level-3/3.6-motoko-lvl3.md
+++ b/docs/tutorials/developer-journey/level-3/3.6-motoko-lvl3.md
@@ -2,13 +2,13 @@
 
 ## Overview
 
-In the previous module, [3.5: Identities and authentication](3.5-identities-and-auth.md) we covered different forms of identities and authentication on the IC. In this Motoko level, we'll look into caller identification, adding access control with identities, plus other non-identity related functionalities such as pattern matching and periodic tasks. 
+In the previous module, [3.5: Identities and authentication](3.5-identities-and-auth.md) you covered different forms of identities and authentication on the IC. In this Motoko level, you'll look into caller identification, adding access control with identities, plus other non-identity related functionalities such as pattern matching and periodic tasks. 
 
 ## Principals and caller identification
 
 Motoko's shared functions support a form of caller identification, allowing for the principal associated with the caller of a function be returned. Recall that a principal is a unique identifier associated with the user or canister. Principals can be used to implement basic access control for an application. 
 
-In Motoko, recall that the `shared` keyword is used to declare a shared function, and that a **shared function** immediately returns a value known as a **future**. This future value indicates that an asynchronous value is expected to be returned. A shared function's arguments and return value(s) must also be shared types. Shared functions can declare an optional parameter of type `{caller : Principal}`. We covered shared functions in more detail in [2.6: Motoko level 2](../level-2/2.6-motoko-lvl2.md)
+In Motoko, recall that the `shared` keyword is used to declare a shared function, and that a **shared function** immediately returns a value known as a **future**. This future value indicates that an asynchronous value is expected to be returned. A shared function's arguments and return value(s) must also be shared types. Shared functions can declare an optional parameter of type `{caller : Principal}`. The developer journey covered shared functions in more detail in [2.6: Motoko level 2](../level-2/2.6-motoko-lvl2.md)
 
 To demonstrate this, consider the following function:
 
@@ -28,7 +28,7 @@ shared(msg) actor class Counter(init : Nat) {
 }
 ```
 
-To further this example, imagine a scenario where you have the `Counter` actor that we used in a previous example that you want to restrict access to. We can modify the original example so that only the `principal` that installed the actor can modify the actor by recording the `principal` that installed the actor and binding it to an `owner` variable, then checking that the caller of each method is equal to the owner variable:
+To further this example, imagine a scenario where you have the `Counter` actor that you used in a previous example that you want to restrict access to. You can modify the original example so that only the `principal` that installed the actor can modify the actor by recording the `principal` that installed the actor and binding it to an `owner` variable, then checking that the caller of each method is equal to the owner variable:
 
 ```motoko
 shared(msg) actor class Counter(init : Nat) {
@@ -60,7 +60,7 @@ In this code, the `assert (owner == msg.caller)` expression causes the functions
 
 Now, let's look at creating a sample dapp that uses role-based permissions to control different operations that users can perform. 
 
-In this example, we'll create a simple app that displays a different greeting for users that have been assigned different roles. We'll use three roles: `owner`, `admin`, and `authorized`:
+In this example, you'll create a simple app that displays a different greeting for users that have been assigned different roles. You'll use three roles: `owner`, `admin`, and `authorized`:
 
 - Users who have the `admin` role will receive the greeting, "You have a role with administrative privileges."
 
@@ -86,7 +86,7 @@ cd access_hello
 
 ### Creating an `owner` identity
 
-First, let's create a new identity to use. We'll call this identity 'owner', since it will be the owner of the canister we create:
+First, let's create a new identity to use. You'll call this identity 'owner', since it will be the owner of the canister you create:
 
 ```
 dfx identity new owner
@@ -371,7 +371,7 @@ dfx deploy
 
 ### Interacting with the dapp
 
-Now that our canister is deployed, we can interact with it using different identities. First, let's confirm that we're still using the `owner` identity we created earlier:
+Now that your canister is deployed, you can interact with it using different identities. First, let's confirm that you're still using the `owner` identity you created earlier:
 
 ```
 dfx identity whoami
@@ -383,7 +383,7 @@ This should return:
 owner
 ```
 
-If the command displays anything else, you can switch back to the `owner` identity with the same command we used earlier:
+If the command displays anything else, you can switch back to the `owner` identity with the same command you used earlier:
 
 ```
 dfx identity use owner
@@ -425,7 +425,7 @@ Then, make a call to the canister to see what role this identity currently has:
 dfx --identity ic_admin canister call access_hello_backend my_role
 ```
 
-This will return the response of `(null)`, since we haven't assigned the identity a role. Now, let's assign it a role, but first we'll need to get it's principal. To do that, set the `ic_admin` identity as your currently-active identity, then use the `dfx identity get-principal` command to get the identity's principal:
+This will return the response of `(null)`, since you haven't assigned the identity a role. Now, let's assign it a role, but first you'll need to get it's principal. To do that, set the `ic_admin` identity as your currently-active identity, then use the `dfx identity get-principal` command to get the identity's principal:
 
 ```
 dfx identity use ic_admin && dfx identity get-principal
@@ -509,7 +509,7 @@ Canister smart contracts can be configured to execute automatically on a periodi
 
 - Heartbeats: A legacy periodic canister invocation with intervals around 1s (the blockchain finalization rate). 
 
-Since heartbeats are a legacy feature, new canisters should opt to use timers instead of heartbeats. For that reason, we'll look at timers in this guide.
+Since heartbeats are a legacy feature, new canisters should opt to use timers instead of heartbeats. For that reason, you'll look at timers in this guide.
 
 To support timers, the Motoko `Timer.mo` library exists. The following is a simple example that creates a periodic reminder for logging a message every new year:
 
@@ -569,6 +569,6 @@ Did you get stuck somewhere in this tutorial, or feel like you need additional h
 
 ## Next steps
 
-That'll wrap up level 3 of our developer journey! In the next level, we'll start by taking a look at using the ICP ledger. 
+That'll wrap up level 3 of our developer journey! In the next level, you'll start by taking a look at using the ICP ledger. 
 
 - [4.1 Using the ICP ledger.](../level-4/4.1-icp-ledger.md)
\ No newline at end of file
diff --git a/docs/tutorials/developer-journey/level-3/index.md b/docs/tutorials/developer-journey/level-3/index.md
index e952ca36df..ddb86e1569 100644
--- a/docs/tutorials/developer-journey/level-3/index.md
+++ b/docs/tutorials/developer-journey/level-3/index.md
@@ -74,7 +74,7 @@
         - Pulling the Internet Identity canister.
         - Interacting with the integration.
 
-- [3.6 Motoko level 3](3.6-motoko-lvl3.md): In this Motoko level, we'll look into caller identification, adding access control with identities, plus other non-identity related functionalities such as pattern matching and periodic tasks. This module covers:
+- [3.6 Motoko level 3](3.6-motoko-lvl3.md): In this Motoko level, you'll look into caller identification, adding access control with identities, plus other non-identity related functionalities such as pattern matching and periodic tasks. This module covers:
     - Principals and caller identification.
     - Adding access control with identities.
         - Prerequisites.
diff --git a/docs/tutorials/developer-journey/level-4/4.1-icp-ledger.md b/docs/tutorials/developer-journey/level-4/4.1-icp-ledger.md
index 878654d9c4..67d2535b1e 100644
--- a/docs/tutorials/developer-journey/level-4/4.1-icp-ledger.md
+++ b/docs/tutorials/developer-journey/level-4/4.1-icp-ledger.md
@@ -4,15 +4,15 @@
 
 Recall from previous modules that ICP is the native token of the Internet Computer. ICP tokens have three key functionalities on the Internet Computer:
 
-- Facilitating the network's governance through neuron staking. We'll dive deeper into staking tokens in [4.4 NNS governance and staking](4.4-nns-governance.md).
+- Facilitating the network's governance through neuron staking. You'll dive deeper into staking tokens in [4.4 NNS governance and staking](4.4-nns-governance.md).
 
-- Creating cycles by converting ICP into cycles, which are then used to pay for canister computation and resources. We briefly covered converting ICP into cycles in [1.4 Acquiring and using cycles](../level-1/1.4-using-cycles.md).
+- Creating cycles by converting ICP into cycles, which are then used to pay for canister computation and resources. The developer journey briefly covered converting ICP into cycles in [1.4 Acquiring and using cycles](../level-1/1.4-using-cycles.md).
 
-- Rewarding NNS participants by providing ICP tokens to users that stake ICP in neurons and actively participate in voting on proposals. We'll dive deeper into NNS rewards in [4.4 NNS governance and staking](4.4-nns-governance.md).
+- Rewarding NNS participants by providing ICP tokens to users that stake ICP in neurons and actively participate in voting on proposals. You'll dive deeper into NNS rewards in [4.4 NNS governance and staking](4.4-nns-governance.md).
 
 To interact with the ICP token, such as send it to another account or convert it into cycles, a specialized canister known as the ICP ledger canister can be used. The ledger canister is used to hold ledger accounts and record a traceable history of all ICP transactions.
 
-In this tutorial, we'll dive into how to deploy a local instance of the ICP ledger canister and how to interact with it. This workflow is important to learn since your local replica cannot access the mainnet ICP ledger, so to test your project's integration with the ICP ledger, you need to deploy a local instance of the ledger. The local instance, however, will not have the history and balances that the mainnet ICP ledger contains. 
+In this tutorial, you'll dive into how to deploy a local instance of the ICP ledger canister and how to interact with it. This workflow is important to learn since your local replica cannot access the mainnet ICP ledger, so to test your project's integration with the ICP ledger, you need to deploy a local instance of the ledger. The local instance, however, will not have the history and balances that the mainnet ICP ledger contains. 
 
 The ICP ledger can only be used to interact with ICP tokens; to interact with other tokens, such as ICRC tokens, an ICRC ledger will need to be used. This ledger is covered in the module [4.2 ICRC tokens](4.2-icrc-tokens.md).
 
@@ -42,9 +42,9 @@ To deploy the ICP ledger canister locally, there are two workflows:
 
 - Using the `dfx-nns` command to deploy an entire instance of the NNS locally, since the ICP ledger is part of the NNS. This workflow will install an ICP ledger canister with the canister ID of `ryjl3-tyaaa-aaaaa-aaaba-cai`. This is a straightforward workflow, but it is heavyweight in the sense that it installs several things in addition to the ledger canister.
 
-- Deploy the ICP ledger canister locally using the Wasm file. This is the method that we'll showcase in this tutorial since it provides greater control over the deployment, such as defining the ledger's minting account, customizing the initialization arguments, and choosing which Wasm version of the ledger to use. 
+- Deploy the ICP ledger canister locally using the Wasm file. This is the method that will be showcased in this tutorial since it provides greater control over the deployment, such as defining the ledger's minting account, customizing the initialization arguments, and choosing which Wasm version of the ledger to use. 
 
-The ICP ledger canister running on the mainnet is not meant to be used for other token deployments. It contains legacy code designed to be backwards compatible and should not be used for developing new ledgers. To develop a new token or ledger, the ICRC ledger can be used, which we'll cover in a [future module](4.2-icrc-tokens.md). 
+The ICP ledger canister running on the mainnet is not meant to be used for other token deployments. It contains legacy code designed to be backwards compatible and should not be used for developing new ledgers. To develop a new token or ledger, the ICRC ledger can be used, which will be covered in a [future module](4.2-icrc-tokens.md). 
 
 ### Prerequisites
 
@@ -62,15 +62,15 @@ cd icp_ledger_canister
 
 ### Locating the Wasm and Candid files
 
-Next, we need to download the ledger's Wasm and Candid files from the latest replica version. You can find the latest replica version on the [dashboard](https://dashboard.internetcomputer.org/releases) under the **Elect new replica binary revision** field. 
+Next, you need to download the ledger's Wasm and Candid files from the latest replica version. You can find the latest replica version on the [dashboard](https://dashboard.internetcomputer.org/releases) under the **Elect new replica binary revision** field. 
 
 Then, use the following URL to download the Wasm module: `https://download.dfinity.systems/ic//canisters/ledger-canister.wasm.gz`.
 
-For example, in this tutorial we'll use the URL https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ledger-canister.wasm.gz.
+For example, in this tutorial you'll use the URL https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ledger-canister.wasm.gz.
 
 Similarly, the following URL can be used to download the Candid file: `https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icp_ledger/ledger.did`.
 
-In this tutorial, we'll use the URL https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icp_ledger/ledger.did.
+In this tutorial, you'll use the URL https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icp_ledger/ledger.did.
 
 Now let's open the `dfx.json` file in the project's directory and replace the existing content with the following:
 
@@ -120,7 +120,7 @@ export DEFAULT_ACCOUNT_ID=$(dfx ledger account-id)
 
 ### Deploying the canister
 
-With these variables set, we can deploy the ledger canister. To deploy the canister with archiving options enabled, run the following command:
+With these variables set, you can deploy the ledger canister. To deploy the canister with archiving options enabled, run the following command:
 
 ```
 dfx deploy --specified-id ryjl3-tyaaa-aaaaa-aaaba-cai icp_ledger_canister --argument "
@@ -146,7 +146,7 @@ dfx deploy --specified-id ryjl3-tyaaa-aaaaa-aaaba-cai icp_ledger_canister --argu
 "
 ```
 
-In this command, we deploy the ICP ledger canister locally and pass parameters that do the following:
+In this command, you can deploy the ICP ledger canister locally and pass parameters that do the following:
 
 - Deploy the ICP ledger canister with the same canister ID as the mainnet ledger canister to simplify switching between local and mainnet deployments.
 
@@ -160,7 +160,7 @@ In this command, we deploy the ICP ledger canister locally and pass parameters t
 
 
 :::info
-Since we're using the ICP ledger locally, we create a local token called LICP that we'll use for local integration testing. This LICP token does not have any value on the mainnet, and cannot be used in place of ICP for mainnet transactions.
+Since you're using the ICP ledger locally, you will create a local token called LICP that you'll use for local integration testing. This LICP token does not have any value on the mainnet, and cannot be used in place of ICP for mainnet transactions.
 :::
 
 ## Interacting with the ICP ledger canister
@@ -249,7 +249,7 @@ To transfer tokens to another account, you will need to get their `AccountIdenti
 dfx identity get-principal --identity IDENTITY
 ```
 
-For example, if you want to send LICP to the `minting` account we created earlier, you can get the principal with the command:
+For example, if you want to send LICP to the `minting` account you created earlier, you can get the principal with the command:
 
 ```
 dfx identity get-principal --identity minter
@@ -280,7 +280,7 @@ export TO_ACCOUNT = "d52f7f2b7277f025bcaa5c90b10d122274faba2891bea519105309ae1f0
 dfx canister call ryjl3-tyaaa-aaaaa-aaaba-cai transfer '(record { to = $(python3 -c 'print("vec{" + ";".join([str(b) for b in bytes.fromhex("'$TO_ACCOUNT'")]) + "}")'); memo = 1:nat64; amount = record {e8s = 200_000_000 }; fee = record { e8s = 10_000 }; })'
 ```
 
-The output of this command will return the block index that the transaction took place in. Since our example is deployed locally and we haven't run any other commands, our transaction takes place within the first block:
+The output of this command will return the block index that the transaction took place in. Since your example is deployed locally and you haven't run any other commands, your transaction takes place within the first block:
 
 ```
 (variant { Ok = 1 : nat64 })
@@ -336,7 +336,7 @@ Did you get stuck somewhere in this tutorial, or feel like you need additional h
 
 ## Next steps
 
-Next, we'll dive into ICRC-1 tokens and how to deploy your own token using the ICRC-1 standard.
+Next, you'll dive into ICRC-1 tokens and how to deploy your own token using the ICRC-1 standard.
 
 - [4.2 ICRC-1 tokens](4.2-icrc-tokens.md).
 
diff --git a/docs/tutorials/developer-journey/level-4/4.2-icrc-tokens.md b/docs/tutorials/developer-journey/level-4/4.2-icrc-tokens.md
index f2480c3fee..6ca1cec7f8 100644
--- a/docs/tutorials/developer-journey/level-4/4.2-icrc-tokens.md
+++ b/docs/tutorials/developer-journey/level-4/4.2-icrc-tokens.md
@@ -10,7 +10,7 @@ Standards defined within the ICRC group are not specific to tokens; anything can
 
 The purpose of the ICRC-1 standard is to create a universally accepted standard for creating and recording token transactions on the Internet Computer. The ICRC-1 standard defines the general functionalities of ledgers; any tokens and their corresponding ledgers that want to support the ICRC-1 standard must fulfill all requirements within the standard. A detailed account of the standard can be found [here](https://github.com/dfinity/ICRC-1/tree/main/standards/ICRC-1). 
 
-There are several extensions of the ICRC-1 standard, such as the [ICRC-2 standard](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-2/README.md). Not all ICRC standards must be extensions of the ICRC-1 standard, though. For this tutorial, we'll focus on the ICRC-1 standard, ICRC-1 ledger, and briefly look into the ICRC-2 standard's endpoints. 
+There are several extensions of the ICRC-1 standard, such as the [ICRC-2 standard](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-2/README.md). Not all ICRC standards must be extensions of the ICRC-1 standard, though. This tutorial will focus on the ICRC-1 standard, ICRC-1 ledger, and briefly look into the ICRC-2 standard's endpoints. 
 
 ## What's the difference between the ICP and ICRC-1 ledgers?
 
@@ -74,7 +74,7 @@ The ICRC-1 token standard allows for several optional metadata fields to be spec
 
 ## Deploying a ICRC-1 ledger locally
 
-Deploying an ICRC-1 ledger canister locally uses the same steps that we used in the last module to deploy the local ICP canister, but we'll use different Wasm and Candid files.
+Deploying an ICRC-1 ledger canister locally uses the same steps that you used in the last module to deploy the local ICP canister, but you'll use different Wasm and Candid files.
 
 ### Prerequisites
 
@@ -92,11 +92,11 @@ cd icrc1_ledger_canister
 
 ### Locating the Wasm and Candid files
 
-We can access the Wasm and Candid files in the same way that we located the ICP ledger files. Remember that we'll need the latest replica version, which can be found on the [dashboard](https://dashboard.internetcomputer.org/releases) under the **Elect new replica binary revision** field. 
+You can access the Wasm and Candid files in the same way that you located the ICP ledger files. Remember that you'll need the latest replica version, which can be found on the [dashboard](https://dashboard.internetcomputer.org/releases) under the **Elect new replica binary revision** field. 
 
-Then, use the following URL to download the Wasm module: `https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz`. In this tutorial we'll use the URL https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ic-icrc1-ledger.wasm.gz.
+Then, use the following URL to download the Wasm module: `https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz`. In this tutorial you'll use the URL https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ic-icrc1-ledger.wasm.gz.
 
-Use the following URL can be used to download the Candid file: `https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did`. In this tutorial, we'll use the URL https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icrc1/ledger/ledger.did.
+Use the following URL can be used to download the Candid file: `https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did`. In this tutorial, you'll use the URL https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icrc1/ledger/ledger.did.
 
 Open the `dfx.json` file in the project's directory and replace the existing content with the following:
 
@@ -120,7 +120,7 @@ Open the `dfx.json` file in the project's directory and replace the existing con
 }
 ```
 
-Next, we'll use the `minter` identity we created in the last module, [4.1 Using the ICP ledger](4.1-icp-ledger.md). If you need to export the `minter` identity's principal again, run the commands:
+Next, you'll use the `minter` identity you created in the last module, [4.1 Using the ICP ledger](4.1-icp-ledger.md). If you need to export the `minter` identity's principal again, run the commands:
 
 ```
 dfx identity use minter
@@ -138,7 +138,7 @@ export TOKEN_SYMBOL="DJTK"
 
 The environment variable `TOKEN_SYMBOL` is the token's ticker symbol, and the `TOKEN_NAME` variable is the token's full name.
 
-Then, set the identity that you want to use to deploy the ledger. In the previous module [4.1 Using the ICP ledger](4.1-icp-ledger.md), we used the `DevJourney` identity, which we'll use again:
+Then, set the identity that you want to use to deploy the ledger. In the previous module [4.1 Using the ICP ledger](4.1-icp-ledger.md), you used the `DevJourney` identity, which you'll use again:
 
 ```
 dfx identity use DevJourney
@@ -156,7 +156,7 @@ The environment variable `PRE_MINTED_TOKENS` is the number of tokens minted duri
 
 The environment variable `TRANSFER_FEE` is the fee that users will pay whenever they make a transfer using the ledger. 
 
-Next, set the values for the ledger's archiving options. The values we're setting in this tutorial are the recommended values, but you can alter them to fit your project's needs:
+Next, set the values for the ledger's archiving options. The values you're setting in this tutorial are the recommended values, but you can alter them to fit your project's needs:
 
 ```
 dfx identity new archive_controller
@@ -189,7 +189,7 @@ The `FEATURE_FLAGS` is used to enable or disable certain ICRC-1 standard extensi
 export FEATURE_FLAGS=true
 ```
 
-Now, let's deploy the ICRC-1 ledger canister locally using the environment variables that we've set using the command:
+Now, let's deploy the ICRC-1 ledger canister locally using the environment variables that you've set using the command:
 
 ```
 dfx deploy icrc1_ledger_canister --specified-id mxzaz-hqaaa-aaaar-qaada-cai --argument "(variant {Init = 
@@ -231,11 +231,11 @@ To deploy an instance of the ICRC-1 ledger on the mainnet, there are several imp
 
 ## Interacting with the ICRC-1 ledger
 
-Like the ICP ledger, the ICRC-1 ledger can be interacted with using the `dfx canister` command or the Candid UI. You can also use the `ic-cdk` for making inter-canister calls to the ICRC-1 ledger or the `ledger-icrc-js` library. In this tutorial, we'll cover using `dfx canister` and the Candid UI, and provide resources for the `ic-cdk` and `ledger-icrc-js` options.
+Like the ICP ledger, the ICRC-1 ledger can be interacted with using the `dfx canister` command or the Candid UI. You can also use the `ic-cdk` for making inter-canister calls to the ICRC-1 ledger or the `ledger-icrc-js` library. This tutorial will cover using `dfx canister` and the Candid UI, and provide resources for the `ic-cdk` and `ledger-icrc-js` options.
 
 ### Using the `dfx canister` command with ICRC-1 endpoints
 
-In this tutorial, we'll cover the endpoints for the ICRC-1 ledger canister and the endpoints for the ICRC-2 extension. For the ICRC-2 endpoints, you will need to have set `FEATURE_FLAGS=true` in the previous step before the canister was deployed. 
+This tutorial will cover the endpoints for the ICRC-1 ledger canister and the endpoints for the ICRC-2 extension. For the ICRC-2 endpoints, you will need to have set `FEATURE_FLAGS=true` in the previous step before the canister was deployed. 
 
 To confirm that your local canister supports the ICRC-2 extension, you can check the list of supported standards with the command:
 
@@ -311,7 +311,7 @@ To return the total token supply of the ICRC-1 ledger, use the command:
 dfx canister call icrc1_ledger_canister icrc1_total_supply '()' 
 ```
 
-This command should return the amount of tokens that we minted using the `PRE_MINTED_TOKENS` variable:
+This command should return the amount of tokens that you minted using the `PRE_MINTED_TOKENS` variable:
 
 ```
 (10_000_000_000 : nat)
@@ -352,7 +352,7 @@ To fetch the balance of an account, in this tutorial the `DEPLOY_ID` account, us
 dfx canister call icrc1_ledger_canister icrc1_balance_of "(record {owner = principal \"${DEPLOY_ID}\"; })" 
 ```
 
-Since we haven't transferred any tokens, this command returns the amount that we minted in the `PRE_MINTED_TOKENS` variable:
+Since you haven't transferred any tokens, this command returns the amount that you minted in the `PRE_MINTED_TOKENS` variable:
 
 ```
 (10_000_000_000 : nat)
@@ -393,7 +393,7 @@ Then, to confirm that this command worked correctly, you check the principal's a
 dfx canister call icrc1_ledger_canister icrc2_allowance "(record { account = record{owner = principal \"${DEPLOY_ID}\";}; spender = record{owner = principal \"sckqo-e2vyl-4rqqu-5g4wf-pqskh-iynjm-46ixm-awluw-ucnqa-4sl6j-mqe\";} })"  
 ```
 
-This command should reflect the 100_000 tokens we approved previously:
+This command should reflect the 100_000 tokens you approved previously:
 
 ```
 (record { allowance = 100_000 : nat; expires_at = null })
@@ -451,6 +451,6 @@ Did you get stuck somewhere in this tutorial, or feel like you need additional h
 
 ## Next steps
 
-Next, we'll dive into ckBTC:
+Next, you'll dive into ckBTC:
 
 - [4.3 ckBTC and Bitcoin integration](4.3-ckbtc-and-bitcoin.md).
\ No newline at end of file
diff --git a/docs/tutorials/developer-journey/level-4/4.3-ckbtc-and-bitcoin.md b/docs/tutorials/developer-journey/level-4/4.3-ckbtc-and-bitcoin.md
index 61059de0e1..bbab6f51e0 100644
--- a/docs/tutorials/developer-journey/level-4/4.3-ckbtc-and-bitcoin.md
+++ b/docs/tutorials/developer-journey/level-4/4.3-ckbtc-and-bitcoin.md
@@ -7,7 +7,7 @@ One of the key features of the Internet Computer is known as **chain-key cryptog
 Currently, the IC supports an integration with the Bitcoin network that includes the chain-key bitcoin (ckBTC) token, and has an Ethereum integration in development. 
 
 :::info
-In this tutorial and other pages of the IC developer documentation, note that we use the lowercase version of **bitcoin** to refer to the token BTC, and use the uppercase version **Bitcoin** to refer to the Bitcoin network itself. This capitalization distinction is in accordance with the Bitcoin style guide.
+In this tutorial and other pages of the IC developer documentation, note the use of the lowercase version of **bitcoin**, which refers to the token BTC, and use of the uppercase version **Bitcoin**, which refers to the Bitcoin network itself. This capitalization distinction is in accordance with the Bitcoin style guide.
 :::
 
 ## Bitcoin integration architecture
@@ -18,7 +18,7 @@ At the core of this integration is a novel protocol for chain-key signatures tha
 
 On a high level, subnets that have ECDSA enabled hold a threshold ECDSA master key, which is generated using the IC's key generation protocol. A master key can be used to generate canister ECDSA keys. It is important to know that an ECDSA private key only exists in a secret-shared form during it's lifetime, whether it is being generated, shared within a subnet, or shared from one subnet to another. 
 
-We'll dive deeper into threshold ECDSA in a future tutorial. You can also take a deep dive in the [technology overview to learn more](/docs/current/developer-docs/integrations/t-ecdsa/t-ecdsa-how-it-works). 
+The developer journey will dive deeper into threshold ECDSA in a future tutorial. You can also take a deep dive in the [technology overview to learn more](/docs/current/developer-docs/integrations/t-ecdsa/t-ecdsa-how-it-works). 
 
 On the protocol-level, the [Bitcoin integration](https://wiki.internetcomputer.org/wiki/Bitcoin_Integration) and chain-key ECDSA each expose an API on the IC management canister. Remember that the IC management canister isn't a canister but a facade that is used to enable functionality for management operations such as starting or stopping a canister. While the Bitcoin API is specific to the Bitcoin network, the chain-key ECDSA signature API can be used for other workflows, such as the integration with other blockchains like Ethereum.
 
@@ -50,13 +50,13 @@ The IC's Bitcoin integration enables use-cases such as:
 
 ## Deploying a Bitcoin dapp
 
-In this tutorial, we'll be deploying an example application using a local instance of the Bitcoin network and then simulate Bitcoin transactions using it. This example showcases the IC's Bitcoin integration, however it does not use ckBTC. 
+In this tutorial, you'll be deploying an example application using a local instance of the Bitcoin network and then simulate Bitcoin transactions using it. This example showcases the IC's Bitcoin integration, however it does not use ckBTC. 
 
 :::info
 Developing with ckBTC uses a different workflow, which will be showcased in a future variation of the developer journey series focused entirely on ckBTC.
 :::
 
-For this tutorial, we'll take a look at developing and testing a Bitcoin dapp using `dfx`, which supports both the Bitcoin API and the ECDSA API. 
+For this tutorial, you'll take a look at developing and testing a Bitcoin dapp using `dfx`, which supports both the Bitcoin API and the ECDSA API. 
 
 ### Prerequisites
 
@@ -186,7 +186,7 @@ brew install llvm binaryen cmake
 
 ### Deploying the example canister
 
-Now we can deploy our Bitcoin canister! To deploy the canister locally, run the command:
+Now you can deploy your Bitcoin canister! To deploy the canister locally, run the command:
 
 ```
 dfx deploy basic_bitcoin --argument '(variant { regtest })'
@@ -205,7 +205,7 @@ URLs:
     basic_bitcoin: http://127.0.0.1:4943/?canisterId=bd3sg-teaaa-aaaaa-qaaba-cai&id=bkyz2-fmaaa-aaaaa-qaaaq-cai
 ```
 
-Our local Bitcoin dapp is ready to use! Let's take a look at how we can interact with it.
+Your local Bitcoin dapp is ready to use! Let's take a look at how you can interact with it.
 
 ### Generating a Bitcoin address
 
@@ -225,7 +225,7 @@ This command will return the generated `P2PKH` address:
 
 Your output will be different, since each ECDSA public key is unique. 
 
-Alternatively, you can use the Candid UI. To use this method, open the Candid UI URL that was returned in the previous step when we deployed the `basic_bitcoin` canister. 
+Alternatively, you can use the Candid UI. To use this method, open the Candid UI URL that was returned in the previous step when you deployed the `basic_bitcoin` canister. 
 
 In the Candid UI, find the `get_p2pkh_address` method, then select the `Call` button under it. 
 
@@ -237,7 +237,7 @@ The `P2PKH` address will be returned in the UI:
 
 ### Receiving BTC
 
-To receive BTC on your local network, you need to mine blocks, since BTC are minted as a reward for mining a block. On the Bitcoin testnet and mainnet, we cannot control when blocks are mined. On our local Bitcoin network, however, we can manually mine blocks using the following command within the `bitcoind` directory:
+To receive BTC on your local network, you need to mine blocks, since BTC are minted as a reward for mining a block. On the Bitcoin testnet and mainnet, you cannot control when blocks are mined. On tour local Bitcoin network, however, you can manually mine blocks using the following command within the `bitcoind` directory:
 
 ```
 ./bin/bitcoin-cli -conf=$(pwd)/bitcoin.conf generatetoaddress  
@@ -249,7 +249,7 @@ For example, to mine a block and have the canister receive the BTC reward, use t ./bin/bitcoin-cli -conf=$(pwd)/bitcoin.conf generatetoaddress 1 BTC_ADDRESS ``` -Replace `BTC_ADDRESS` with the generated `P2PKH` address we got in the last step. +Replace `BTC_ADDRESS` with the generated `P2PKH` address you got in the last step. If successful, you'll receive the hash of the block that was just mined, which resembles the following: @@ -282,12 +282,12 @@ Replace `BTC_ADDRESS` with your generated `P2PKH` address. Our balance should be ``` :::caution -Remember that this is a local deployment. The BTC we mine here is only valid on our local Bitcoin network for testing purposes, and cannot be spent or used anywhere else. +Remember that this is a local deployment. The BTC you mine here is only valid on your local Bitcoin network for testing purposes, and cannot be spent or used anywhere else. ::: ### Sending BTC -Previously, we mined a single block and received a reward of 50 BTC for that block. One prerequisite to sending this BTC to someone else, however, is that first, 100 additional blocks must be mined. This is known as the Coinbase maturity rule. +Previously, you mined a single block and received a reward of 50 BTC for that block. One prerequisite to sending this BTC to someone else, however, is that first, 100 additional blocks must be mined. This is known as the Coinbase maturity rule. To mine 100 additional blocks, run the command: @@ -297,9 +297,9 @@ To mine 100 additional blocks, run the command: Replace `BTC_ADDRESS` with your generated `P2PKH` address. -You should receive output and `dfx` log entries similar to the ones we got for mining a single block. +You should receive output and `dfx` log entries similar to the ones you got for mining a single block. -Now we can send BTC using the canister's `send` endpoint. In this example, we'll send 1 BTC to the address `n2dcQfuwFw7M2UYzLfM6P7DwewsQaygb8S`. You can replace this address with any test address you would like. +Now you can send BTC using the canister's `send` endpoint. In this example, you'll send 1 BTC to the address `n2dcQfuwFw7M2UYzLfM6P7DwewsQaygb8S`. You can replace this address with any test address you would like. ``` dfx canister call basic_bitcoin send '(record { destination_address = "n2dcQfuwFw7M2UYzLfM6P7DwewsQaygb8S"; amount_in_satoshi = 100000000; })' @@ -309,7 +309,7 @@ dfx canister call basic_bitcoin send '(record { destination_address = "n2dcQfuwF Note that this command sends BTC in 'satoshi'. 1 BTC is equivalent to 100_000_000 satoshi. ::: -This command will create a transaction and send it to the local Bitcoin instance running. After running this command, you now need to mine a block so that the transaction we just sent becomes a part of the blockchain. Without mining a block, the transaction is not recorded on-chain. +This command will create a transaction and send it to the local Bitcoin instance running. After running this command, you now need to mine a block so that the transaction you just sent becomes a part of the blockchain. Without mining a block, the transaction is not recorded on-chain. In the `bitcoind` directory, run the following command to mine another block: @@ -317,7 +317,7 @@ In the `bitcoind` directory, run the following command to mine another block: ./bin/bitcoin-cli -conf=$(pwd)/bitcoin.conf generatetoaddress 1 mtbZzVBwLnDmhH4pE9QynWAgh6H3aC1E6M ``` -Now, we can check that the address `n2dcQfuwFw7M2UYzLfM6P7DwewsQaygb8S` has a balance of 1 BTC: +Now, you can check that the address `n2dcQfuwFw7M2UYzLfM6P7DwewsQaygb8S` has a balance of 1 BTC: ``` dfx canister call basic_bitcoin get_balance '("n2dcQfuwFw7M2UYzLfM6P7DwewsQaygb8S")' @@ -351,7 +351,7 @@ Did you get stuck somewhere in this tutorial, or feel like you need additional h ## Next steps -Next, we'll explore the IC's governance and token staking: +Next, you'll explore the IC's governance and token staking: - [4.4 NNS governance and staking](4.4-nns-governance.md). diff --git a/docs/tutorials/developer-journey/level-4/4.4-nns-governance.md b/docs/tutorials/developer-journey/level-4/4.4-nns-governance.md index a6a8409bba..34b583fc8b 100644 --- a/docs/tutorials/developer-journey/level-4/4.4-nns-governance.md +++ b/docs/tutorials/developer-journey/level-4/4.4-nns-governance.md @@ -6,7 +6,7 @@ When blockchain networks need to be upgraded, traditionally they use a method kn Each upgrade made to the IC is first introduced as an NNS proposal. Then, users who stake ICP governance tokens can vote on this proposal. If the proposal is accepted, the upgrade gets executed automatically. -In this tutorial, we'll explore how to use the NNS dapp and how to stake ICP tokens into a neuron to receive NNS voting power. +In this tutorial, you'll explore how to use the NNS dapp and how to stake ICP tokens into a neuron to receive NNS voting power. ## What is the NNS? @@ -81,7 +81,7 @@ You will be prompted to log in with your Internet Identity. If you need to creat ### Transferring ICP tokens into your Internet Identity 'Main' account -Once logged in, you can see your balance for each token on the NNS dapp. Tokens include ICP, ckBTC, and dapp-specific tokens for dapps that have an SNS, such as OpenChat (CHAT) and Hot or Not (HOT). For this tutorial, we'll be staking ICP in an IC neuron, so assure that you have some ICP tokens available. +Once logged in, you can see your balance for each token on the NNS dapp. Tokens include ICP, ckBTC, and dapp-specific tokens for dapps that have an SNS, such as OpenChat (CHAT) and Hot or Not (HOT). For this tutorial, you'll be staking ICP in an IC neuron, so assure that you have some ICP tokens available. If you need to obtain ICP tokens, they can be purchased through a crypto exchange, or they can be received through other activities such as receiving grants from the DFINITY foundation. They will need to be sent to the ICP wallet address shown in the NNS dapp. The following screenshot shows this address beneath the current balance under the 'Main' account with the balance of `5.10 ICP`: @@ -105,7 +105,7 @@ Then, check the balance of your identity's ledger account to assure that it is t dfx ledger --network ic balance ``` -The flag `--network ic` is required, since we are intending to use real ICP on the mainnet. +The flag `--network ic` is required, since you are intending to use real ICP on the mainnet. If the balance is correct, then you can transfer ICP tokens to your Internet Identity 'Main' address with the command: @@ -113,7 +113,7 @@ If the balance is correct, then you can transfer ICP tokens to your Internet Ide dfx ledger --network ic transfer --icp --memo ``` -For example, for the 'Main' account in this example, we could transfer 1 ICP to the account with the command: +For example, for the 'Main' account in this example, you could transfer 1 ICP to the account with the command: ``` dfx ledger --network ic transfer 365cf45f3521653e866a078b157a8d8701c3f63183a6d41ff8ddb913c4a978d3 --icp 1 --memo Developer Journey @@ -145,7 +145,7 @@ Then confirm the setting to create your neuron. ![NNS dapp 7](../_attachments/nns7.png) -Once your neuron has been created, you can follow other neurons. As we discussed earlier, setting up following will automate your neuron's participation in voting on proposals, allowing you to maximize your neuron rewards. To follow a specific topic, select the drop-down menu next to the group you'd like to follow. In this example, we'll select "All except Governance, and SNS & Neurons' Fund". +Once your neuron has been created, you can follow other neurons. As was discussed earlier, setting up following will automate your neuron's participation in voting on proposals, allowing you to maximize your neuron rewards. To follow a specific topic, select the drop-down menu next to the group you'd like to follow. In this example, you'll select "All except Governance, and SNS & Neurons' Fund". ![NNS dapp 8](../_attachments/nns8.png) @@ -153,7 +153,7 @@ Then, you can select a specific group of neurons to follow by selecting 'Add Fol ![NNS dapp 9](../_attachments/nns9.png) -A list of available neurons will be displayed. In this example, we'll follow the 'DFINITY Foundation' neuron. +A list of available neurons will be displayed. In this example, you'll follow the 'DFINITY Foundation' neuron. ![NNS dapp 10](../_attachments/nns10.png) @@ -179,11 +179,11 @@ Lastly, at the very bottom of the window there will be information about the neu ### Interacting with NNS proposals -Earlier, we set up following for our neuron, meaning that the neuron will automatically vote on proposals that fall into the category we configured. To interact with proposals manually, select 'Vote on Proposals' on the left navigation bar, then select 'Internet Computer'. All of the currently available proposals will be displayed. +Earlier, you set up following for our neuron, meaning that the neuron will automatically vote on proposals that fall into the category you configured. To interact with proposals manually, select 'Vote on Proposals' on the left navigation bar, then select 'Internet Computer'. All of the currently available proposals will be displayed. ![NNS dapp 16](../_attachments/nns16.png) -If you click on one, however, you'll notice that you cannot vote on it. That's because the proposals were created prior to the neuron that we just created, so we aren't eligible to vote on the currently open proposals. All future proposals will be available to us. +If you click on one, however, you'll notice that you cannot vote on it. That's because the proposals were created prior to the neuron that you just created, so you aren't eligible to vote on the currently open proposals. All future proposals will be available to you. ![NNS dapp 17](../_attachments/nns17.png) @@ -211,7 +211,7 @@ Did you get stuck somewhere in this tutorial, or feel like you need additional h ## Next steps -Next, we'll dive into how to use the tool quill: +Next, you'll dive into how to use the tool quill: - [4.5 Using quill](4.5-using-quill.md). diff --git a/docs/tutorials/developer-journey/level-4/4.5-using-quill.md b/docs/tutorials/developer-journey/level-4/4.5-using-quill.md index 09dfdc811a..563bc87dc0 100644 --- a/docs/tutorials/developer-journey/level-4/4.5-using-quill.md +++ b/docs/tutorials/developer-journey/level-4/4.5-using-quill.md @@ -2,7 +2,7 @@ ## Overview -Now that we've covered both the ICP ledger and the NNS, it's time to take a look at a CLI tool that can be used to interact with both. Quill is a ledger and governance toolkit that provides support for self-custody of ICP or ckBTC tokens and functionality to interact with the NNS, SNSs, and ICP ledger from a **cold wallet**. +Now that you've covered both the ICP ledger and the NNS, it's time to take a look at a CLI tool that can be used to interact with both. Quill is a ledger and governance toolkit that provides support for self-custody of ICP or ckBTC tokens and functionality to interact with the NNS, SNSs, and ICP ledger from a **cold wallet**. To hold tokens or digital assets, there are three types of wallet options you can use: @@ -16,7 +16,7 @@ Each of these options has their benefits, but there is an equal tradeoff between You can read more about different types of self-custody wallet options in the documentation [here](/docs/current/tokenomics/token-holders/custody-options-intro). -In this tutorial, we'll take a look at how to use quill for workflows like interacting with the ICP ledger, sending or receiving ckBTC, and interacting with the NNS and neurons. +In this tutorial, you'll take a look at how to use quill for workflows like interacting with the ICP ledger, sending or receiving ckBTC, and interacting with the NNS and neurons. ## What is quill? @@ -30,7 +30,7 @@ While it is important to know that quill supports cold wallet workflows, quill c Transactions that use query requests, such as obtaining an account's balance or returning proposal information, require an internet connection and cannot be run on cold wallets. This is because submitting these query calls locally would not be beneficial, since the mainnet canisters being queried are not running on the local replica. Additionally, query calls do not require the same cryptographic validity that update calls do, therefore they do not need a signature to be generated and can be submitted directly to the mainnet. -In this tutorial, we'll see that query calls do not generate output and can be submitted directly to the mainnet, while update calls will generate a JSON response that must be saved and submitted using `quill send`. +In this tutorial, you'll see that query calls do not generate output and can be submitted directly to the mainnet, while update calls will generate a JSON response that must be saved and submitted using `quill send`. ::: @@ -39,7 +39,7 @@ In this tutorial, we'll see that query calls do not generate output and can be s :::info To install quill on a cold wallet, you can either follow the steps below then disconnect the computer from the internet, or you can download the release file and transport it to the offline machine using a device such as a USB flash drive. -In this tutorial, we'll be using quill on a machine with an internet connection, but we'll include notes with information for cold wallet workflows. +In this tutorial, it will be assumed that you will be using quill on a machine with an internet connection, but this tutorial will include notes with information for cold wallet workflows. ::: First, start by downloading the latest quill release from GitHub [here](https://github.com/dfinity/quill/releases). @@ -66,7 +66,7 @@ quill -h ## Using quill's basic commands -First, we need an account to use with quill. We can create a new account, or we can use an existing ledger account. To create a new account, generate the account's private key by running the command: +First, you need an account to use with quill. You can create a new account, or you can use an existing ledger account. To create a new account, generate the account's private key by running the command: ``` quill generate @@ -79,7 +79,7 @@ Principal id: hzpq4-g6feu-vbvwx-oeo5c-fjiz4-de4bq-7q4y2-rldok-whjrq-mnayv-mqe Legacy account id: 438f6fdc8e33539bbf73625c141cfbfa4b41fd943595f8e1ccd0b8c9e9758772 ``` -Alternatively, we can use a private key file for our existing ledger account with an ICP balance. To use an existing ledger account, you will need the account's `.pem` file. To get this `.pem` file, we can use the `dfx identity export` command. First, assure that you're using the `dfx` identity you intend to be: +Alternatively, you can use a private key file for our existing ledger account with an ICP balance. To use an existing ledger account, you will need the account's `.pem` file. To get this `.pem` file, you can use the `dfx identity export` command. First, assure that you're using the `dfx` identity you intend to be: ``` dfx identity whoami @@ -92,10 +92,10 @@ dfx identity export default > identity.pem ``` :::info -In this command, the `>` character indicates that we want to save the output of `dfx identity export default` to a file called `identity.pem`. +In this command, the `>` character indicates that you want to save the output of `dfx identity export default` to a file called `identity.pem`. ::: -Then, we can pass this `.pem` file into our quill commands with the flag `--pem-file identity.pem`. +Then, you can pass this `.pem` file into our quill commands with the flag `--pem-file identity.pem`. Next, let's use quill to get our account's balance. Use the following command: @@ -105,7 +105,7 @@ quill --pem-file identity.pem account-balance PRINCIPAL_ID Replace `PRINCIPAL_ID` with the principal value returned from the command `dfx identity get-principal` for the identity that you generated the `.pem` file for. -Running commands with quill will generate the transaction, then ask if we'd like to send the message or not, such as: +Running commands with quill will generate the transaction, then ask if you'd like to send the message or not, such as: ``` Sending message with @@ -134,14 +134,14 @@ The request is being processed... (100_000_000 : nat) ``` -Now, if we want to transfer ICP to another account, we can use the command: +Now, if you want to transfer ICP to another account, you can use the command: ``` quill --pem-file identity.pem transfer --amount AMOUNT ACCOUNT_ID ``` :::caution -To use the quill transfer command, we need to have a balance of ICP. ICP can be bought through a crypto exchange, or ICP can be received through community activities such as participating in the NNS governance and receiving developer grants. +To use the quill transfer command, you need to have a balance of ICP. ICP can be bought through a crypto exchange, or ICP can be received through community activities such as participating in the NNS governance and receiving developer grants. ::: Replace `AMOUNT` with the numerical number of how many ICP tokens to transfer and replace `ACCOUNT_ID` with the account ID that should receive the ICP. For example: @@ -157,7 +157,7 @@ quill --pem-file identity.pem transfer --amount 0.5 365cf45f3521653e866a078b157a quill --pem-file identity.pem send transfer_transaction.json ``` -Then we'll be prompted to confirm sending this transaction to the mainnet. On a cold wallet, the `transaction1.json` file can be transferred to an online machine to be sent with the `quill --pem-file identity.pem send transfer_transaction.json` command. +Then you'll be prompted to confirm sending this transaction to the mainnet. On a cold wallet, the `transaction1.json` file can be transferred to an online machine to be sent with the `quill --pem-file identity.pem send transfer_transaction.json` command. ## Using quill with ckBTC @@ -260,13 +260,13 @@ Do you want to send this message? [y/N] Quill can be used with both the NNS and any SNS that has been launched on the IC. -In the previous module, [4.4 NNS governance and staking](4.4-nns-governance.md), we took a look at how to interact with the NNS and neurons through the NNS dapp. Now, let's look at how to use quill instead to perform the same functions. +In the previous module, [4.4 NNS governance and staking](4.4-nns-governance.md), you took a look at how to interact with the NNS and neurons through the NNS dapp. Now, let's look at how to use quill instead to perform the same functions. -First, let's get some information about a neuron. You'll need a neuron's ID, which you can find on the NNS dapp, as we took a look at in the last module: +First, let's get some information about a neuron. You'll need a neuron's ID, which you can find on the NNS dapp, as you took a look at in the last module: ![Neuron ID](../_attachments/nns14.png) -Then, we can use the command: +Then, you can use the command: ``` quill get-neuron-info NEURON_ID @@ -424,6 +424,6 @@ Did you get stuck somewhere in this tutorial, or feel like you need additional h ## Next steps -To finish the level 4 developer journey section, we'll wrap up with Motoko level 4: +To finish the level 4 developer journey section, you'll wrap up with Motoko level 4: - [4.6 Motoko level 4](4.6-motoko-lvl4.md). \ No newline at end of file diff --git a/docs/tutorials/developer-journey/level-4/4.6-motoko-lvl4.md b/docs/tutorials/developer-journey/level-4/4.6-motoko-lvl4.md index 0f8f61a929..49c730754c 100644 --- a/docs/tutorials/developer-journey/level-4/4.6-motoko-lvl4.md +++ b/docs/tutorials/developer-journey/level-4/4.6-motoko-lvl4.md @@ -2,7 +2,7 @@ ## Overview -In this final Motoko module of the developer journey series, we'll cover the following Motoko concepts and components: +In this final Motoko module of the developer journey series, you'll cover the following Motoko concepts and components: - Mutable state. @@ -38,7 +38,7 @@ var pairMutable : (Text, Nat) = (textImmutable, numImmutable); var textMutable : Text = textImmutable; ``` -To update the values of the mutable variables, we can use the following syntax with the assignment operation `:=`, which works for all types: +To update the values of the mutable variables, you can use the following syntax with the assignment operation `:=`, which works for all types: ```motoko textMutable := textMutable # "xyz"; @@ -46,7 +46,7 @@ pairMutable := (textMutable, pairMutable.1); pairMutable ``` -In this syntax, we update each mutable variable using an update rule for their current values. An actor processes calls by performing updates on its internal mutable variables using the same syntax as above. +In this syntax, you can update each mutable variable using an update rule for their current values. An actor processes calls by performing updates on its internal mutable variables using the same syntax as above. ### Reading data from mutable memory @@ -95,7 +95,7 @@ For example, consider the following immutable array: let a : [Nat] = [1, 2, 3] ; ``` -Then, to read from this array we can use the traditional bracket syntax of `[` and `]`, to read the desired index: +Then, to read from this array you can use the traditional bracket syntax of `[` and `]`, to read the desired index: ```motoko let x : Nat = a[2] + a[0] ; @@ -143,13 +143,13 @@ This is because mutable arrays require different rules for subtyping; in particu ## Local objects and classes -Motoko objects encapsulate the canister's local state using `var` bound variables, packaging the state with any public methods that are used to interact with or update it. As we mentioned earlier, any objects that include a mutable state are not shareable. To provide a workflow to overcome this limitation, an actor's objects are sharable and always execute remotely. Actor objects and classes communicate exclusively with Motoko data. +Motoko objects encapsulate the canister's local state using `var` bound variables, packaging the state with any public methods that are used to interact with or update it. As this tutorial mentioned earlier, any objects that include a mutable state are not shareable. To provide a workflow to overcome this limitation, an actor's objects are sharable and always execute remotely. Actor objects and classes communicate exclusively with Motoko data. In comparison, local objects and classes can pass any Motoko data to another object's methods, including other objects. Local objects and classes are essentially the non-shareable counterparts to actor objects and classes. Classes are defined by the keyword `class`, followed by the name for the constructor and the type being defined, optional type arguments, an argument list, and an optional type annotation for constructed objects. -In the previous section, we introduced mutable state declarations of private mutable state using `var` bound variables and mutable arrays. In this section, we'll use mutable state to implement simple objects. +The previous section introduced mutable state declarations of private mutable state using `var` bound variables and mutable arrays. In this section, you'll use mutable state to implement simple objects. ### Object classes versus actor classes @@ -229,7 +229,7 @@ The object type for the object `bumpCounter` exposes only one operation, `bump`: } ``` -This example exposes the most common operation and only permits a certain behavior. In another part of a program, we may want to implement another version with more generality, such as our example from earlier: +This example exposes the most common operation and only permits a certain behavior. In another part of a program, you may want to implement another version with more generality, such as our example from earlier: ```motoko { @@ -239,7 +239,7 @@ This example exposes the most common operation and only permits a certain behavi } ``` -Lastly, we may implement a type with additional operations, such as a `write` operation: +Lastly, you may implement a type with additional operations, such as a `write` operation: ```motoko { @@ -250,7 +250,7 @@ Lastly, we may implement a type with additional operations, such as a `write` op } ``` -If a function expects to receive an object using the first type `({ bump: () → Nat })`, any of these versions of the type will work since they are equal to, or a subtype of, the most general version. If we want to use a function that expects to receive an object that uses an additional operation not included in the other types, such as the `write` operation, then only that type will work. +If a function expects to receive an object using the first type `({ bump: () → Nat })`, any of these versions of the type will work since they are equal to, or a subtype of, the most general version. If you want to use a function that expects to receive an object that uses an additional operation not included in the other types, such as the `write` operation, then only that type will work. ### Object classes @@ -266,14 +266,14 @@ class Counter() { }; ``` -Using this definition, we can construct new counters each with their own unique state that start at zero, such as: +Using this definition, you can construct new counters each with their own unique state that start at zero, such as: ```motoko let c1 = Counter(); let c2 = Counter(); ``` -Then, we can use each counter, `c1` and `c2`, independently of one another: +Then, you can use each counter, `c1` and `c2`, independently of one another: ```motoko let x = c1.inc(); @@ -295,7 +295,7 @@ Note that the return type of this function is `{ inc : () -> Nat }`, which could ### Data arguments -In our object class, we initialized counter functions to start with a value of zero. If we want to initialize the counter with a value other than zero, we can pass a data argument into the constructor function: +In your object class, you initialized counter functions to start with a value of zero. If you want to initialize the counter with a value other than zero, you can pass a data argument into the constructor function: ```motoko class Counter(init : Nat) { @@ -380,7 +380,7 @@ public shared func markDoneOption(id : TodoId) : async ?Seconds { }; ``` -Then, we can use the following error callsite: +Then, you can use the following error callsite: ```motoko @@ -406,7 +406,7 @@ As an alternative to using `Option` types, `Result` variants can be used to retu type Result = { #ok : Ok; #err : Err } ``` -Since `Result` includes the `Err` type parameters, the `Result` type allows us to select the type used to describe errors. Consider the following example that uses `Result` variants to signal errors: +Since `Result` includes the `Err` type parameters, the `Result` type allows you to select the type used to describe errors. Consider the following example that uses `Result` variants to signal errors: ```Motoko public shared func markDoneResult(id : TodoId) : async Result.Result { @@ -426,7 +426,7 @@ public shared func markDoneResult(id : TodoId) : async Result.Result