From e8e941e3a29ab00d437446de57b7216186d7ebb8 Mon Sep 17 00:00:00 2001 From: Joel Willmore <95916148+jlwllmr@users.noreply.github.com> Date: Wed, 11 Dec 2024 09:44:20 +0000 Subject: [PATCH] Add quickstart deployment guide (#884) * Add backend quickstart guide * Feedback and adjustments * Adjustments for clarity * Filename changes etc. * Fix Infura docs link * Amend paths * Hide part 2, other minor changes --- docs/get-started/build/quickstart/app.mdx | 11 + docs/get-started/build/quickstart/deploy.mdx | 253 ++++++++++++++++++ .../how-to/deploy-smart-contract/foundry.mdx | 16 +- .../how-to/verify-smart-contract/foundry.mdx | 2 +- sidebars.js | 12 + src/pages/index.tsx | 2 +- 6 files changed, 286 insertions(+), 10 deletions(-) create mode 100644 docs/get-started/build/quickstart/app.mdx create mode 100644 docs/get-started/build/quickstart/deploy.mdx diff --git a/docs/get-started/build/quickstart/app.mdx b/docs/get-started/build/quickstart/app.mdx new file mode 100644 index 000000000..516874532 --- /dev/null +++ b/docs/get-started/build/quickstart/app.mdx @@ -0,0 +1,11 @@ +--- +title: Build your app +description: Connect your contracts to a frontend app +sidebar_position: 2 +pagination_next: null +pagination_prev: get-started/build/quickstart/deploy +unlisted: true +image: /img/socialCards/build-your-app.jpg +--- + +TODO diff --git a/docs/get-started/build/quickstart/deploy.mdx b/docs/get-started/build/quickstart/deploy.mdx new file mode 100644 index 000000000..0fb2436f9 --- /dev/null +++ b/docs/get-started/build/quickstart/deploy.mdx @@ -0,0 +1,253 @@ +--- +title: Contract deployment +description: Create a new project and deploy and verify your contracts using Foundry +sidebar_position: 1 +pagination_next: get-started/build/quickstart/app +pagination_prev: null +image: /img/socialCards/contract-deployment.jpg +--- + +Building apps on Linea needn't be complicated. In this guide, we'll walk you through using +[Foundry](https://book.getfoundry.sh/) to create a new project from scratch. + +This involves: +1. [Creating a project](#create-a-project) +2. [Deploying](#deploy-a-contract) and then [verifying](#verify-a-contract) your contract. + +> _Estimated time to complete: ~20 minutes._ + +## Prerequisites + +A Linea-compatible wallet with some Linea Sepolia ETH. We recommend using [MetaMask](https://metamask.io/). + +Get some testnet ETH by heading to our [Discord server](https://discord.gg/linea) and asking in +the `#developer-chat` channel. Our admins or other community members will help you out. + +## Create your project + +To get started, we're going to use Foundry's `forge init` command to create a new project. [`forge`](https://book.getfoundry.sh/forge/) +is the Foundry CLI tool. + +Firstly, let's [install Foundry](https://book.getfoundry.sh/getting-started/installation): + +```bash +curl -L https://foundry.paradigm.xyz | bash +``` + +Then initiate the new project, choosing whatever name you prefer. Make sure you're in the +directory you want to create your project in: + +```bash +forge init linea_test_project +``` + +Foundry will build out the file structure and create a git repository. It also installs one +dependency: `forge-std`, the Forge Standard Library, which enables you to test your project. +To get more familiar with your new project, it might help to open it in a code editor and inspect +the files. + +You can also run `forge build` to compile your project, and then `forge test` to use the `forge-std` +testing library. + +:::note + +If you already have a project set up, clone the project and run `forge install` in the directory to +use Foundry. See the [Foundry guide](https://book.getfoundry.sh/projects/working-on-an-existing-project#working-on-an-existing-project) +for more information. + +::: + +## Deploy your contract + +The default Foundry template comes with a simple placeholder contract, `Counter.sol`. You're likely +going to need something with a bit more functionality. You probably already have a idea of what +you want your app to do, and you might have the skills to write your own contract from scratch. + +For simplicity, we're going to stick with `Counter.sol`, but you can use any template you want, or +refer to our [contract templates section](../../tooling/contracts-templates/index.mdx) for more inspiration. + +We'll use the `forge create` command to deploy the contract. First, we must get an RPC endpoint and +ensure we have a secure method for using a private key. + +### RPC endpoints + +#### Get your RPC endpoint + +To deploy a contract, you need to interact with the blockchain, which means you need an [RPC endpoint](../../tooling/node-providers/index.mdx) +to send those calls to. + +To keep things simple, we're going to use the default public RPC endpoint for Linea Sepolia: +`https://rpc.sepolia.linea.build`. + +Public endpoints such as this one are rate limited, and if you intend to deploy your app for public +use, you'll need an endpoint better equipped to handle the load. We recommend heading to the +MetaMask Developer Dashboard to get a private RPC endpoint ([instructions](https://docs.metamask.io/developer-tools/dashboard/get-started/create-api/)). + +You can also find alternative public and private RPC endpoints on our [node providers page](../../tooling/node-providers/index.mdx). + +#### Update `foundry.toml` + +Add the RPC endpoint to the `foundry.toml` file: + +```toml +[profile.rpc-endpoints] +sepolia = "https://rpc.sepolia.linea.build" +``` + +### Store your private key + +Deploying a contract requires an account's private key, which means you need to either provide it in +the command line when running the deployment command (not recommended) or store it securely and +access it with alternative methods. See the [MetaMask support guide to finding your private key](https://support.metamask.io/managing-my-wallet/secret-recovery-phrase-and-private-keys/how-to-export-an-accounts-private-key/). + +:::tip[Private key security best practices] + +We recommend [creating a new account in MetaMask](https://support.metamask.io/managing-my-wallet/accounts-and-addresses/how-to-add-accounts-in-your-wallet/) +specifically for this project, and [naming it](https://support.metamask.io/managing-my-wallet/accounts-and-addresses/how-do-i-change-my-account-name-/) +something appropriate, such as "linea-project". + +Even though we're working on a testnet, it's best to behave as if real assets were at stake, and +work in a sandboxed context with a somewhat expendable account. + +::: + +A standard approach is to store your private key as an environment variable in a `.env` file that +is only stored locally (i.e. listed in `.gitignore` file). However, we're going to use Foundry's +keystore system to encrypt and store the private key, and then access it with a password. This +ensures that you won't accidentally expose your private key—for example, in a GitHub repository. + +To do this, we'll use Foundry's [`cast`](https://book.getfoundry.sh/cast/) CLI tool; specifically, +the [`cast wallet import`](https://book.getfoundry.sh/reference/cast/cast-wallet-import) command. + +```bash +cast wallet import --interactive test-account +``` + +The `--interactive` flag means that you'll be prompted to enter your private key in the terminal, +followed by a corresponding password. `test-account` is the name you want to give the account in +the keystore; choose whatever is suitable for your purposes here. + +When you enter the private key and then your password, you'll get confirmation that it has been +stored successfully: + +``` +`test-account` keystore was saved successfully. Address: +``` + +Run `cast wallet list` to see accounts in your keystore. + +### Deploy + +#### Adjust Solidity version + +By default, the `forge init` command we used originally creates the `Counter.sol` contract with the +following Solidity compiler version: + +``` +pragma solidity ^0.8.13; +``` + +This enables the compiler to use any version newer than Solidity v0.8.13. [Linea is only compatible +with Solidity 0.8.19 or lower](../../build/ethereum-differences.mdx), so we need to make some +adjustments. + +Add this line to `[profile.default]` in your `foundry.toml` file: + +```toml +solc-version = 0.8.19 +``` + +So that your `[profile.default]`, which is applied universally, now looks like this: + +```toml +[profile.default] +src = "src" +out = "out" +libs = ["lib"] +solc-version = "0.8.19" +``` + +#### Run `forge create` + +With your RPC endpoint to hand and your private key stored more securely, you're ready to deploy +using `forge create`. + +Execute this command, then enter your password to use the private key when prompted: + +```bash +forge create --rpc-url https://rpc.sepolia.linea.build --account test-account --broadcast src/Counter.sol:Counter +``` + +- `--rpc-url` is the RPC endpoint you want to use. +- `--account` is the keystore account you want to use to deploy the contract. +- `--broadcast` tells Forge to send the transaction to the network. You can test the command by +omitting this flag, but you won't actually deploy the contract. + +The format of the contract you want to deploy is `path/to/contract.sol:ContractName`; in this case, +we want the `Counter` contract from `src/Counter.sol`. + +If successful, you'll see this in the terminal: + +``` +Deployer: 0x ... // The address of the account used to deploy the contract +Deployed to: 0x ... // The address of the deployed contract +Transaction hash: 0x ... // The deployment transaction itself +``` + +You can copy each of these addresses and head to the [block explorer](https://sepolia.lineascan.build/) +to see the deployed contract. + +Make sure to copy the `Deployed to` address, as you'll need it to verify the contract. + +## Verify your contract + +Verifying a contract makes the source code publicly visible, and also confirms to others that it +originated from a genuine source. + +Verifying can be done with the `forge verify-contract` command, and requires a Lineascan API key. + +### Get a Lineascan API key + +Get a Lineascan API key by [creating an account](https://lineascan.build/myapikey). + +Since it's best practice to avoid using API keys in the command line, add the API key to your +`.env` file: + +``` +LINEASCAN_API_KEY=YOUR_LINEASCAN_API_KEY +``` + +Then modify the `foundry.toml` configuration file to include the Lineascan API key, pulling it from +the `.env` file: + +```toml +[etherscan] +linea-sepolia = { key = "${LINEASCAN_API_KEY}" } +``` + +#### Run `forge verify-contract` + +Execute this command: + +```bash +forge verify-contract --chain linea-sepolia YOUR_CONTRACT_ADDRESS path_to_contract:contract_name --watch +``` + +`--watch` automatically runs the `forge verify-check` command to report verification status in the +terminal until verification is complete. + +:::note + +You can also complete verification at the same time as deployment by adding the `--verify` and +`--verifier-url` flags to the `forge create` command, and providing your Lineascan API key. + +For example: + +```bash +forge create --rpc-url https://rpc.sepolia.linea.build --account test-account --broadcast --verify --verifier-url https://api-sepolia.lineascan.build/api --etherscan-api-key LINEASCAN_API_KEY src/Counter.sol:Counter +``` + +::: + +Now you've successfully deployed and verified your contract! It's recorded on the blockchain and +ready to receive calls from your app. diff --git a/docs/get-started/how-to/deploy-smart-contract/foundry.mdx b/docs/get-started/how-to/deploy-smart-contract/foundry.mdx index 1294fe75a..daa82e88c 100644 --- a/docs/get-started/how-to/deploy-smart-contract/foundry.mdx +++ b/docs/get-started/how-to/deploy-smart-contract/foundry.mdx @@ -47,8 +47,8 @@ cd linea-tutorial ## Deploy a smart contract -To deploy a smart contract we highly recommend using an Infura endpoint, as the public endpoint may experience -rate limiting and is not meant for production use. +To deploy a smart contract we highly recommend using an Infura endpoint, as the public endpoint may +experience rate limiting and is not meant for production use. [Sign up for an Infura account](https://docs.infura.io/api/getting-started) to get an API key that provides access to the Linea endpoints. Assign the Linea endpoints you want to access to your API key. @@ -69,7 +69,7 @@ forge create --rpc-url YOUR_LINEA_ENDPOINT src/Counter.sol:Counter --private-key In the command: - Replace `YOUR_LINEA_ENDPOINT` with the URL of a - [supported Infura Linea network](https://docs.infura.io/api/networks/linea/choose-a-network) + [supported Infura Linea network](https://docs.metamask.io/services/get-started/endpoints/) or [public endpoint URL](../../build/network-info.mdx). - Replace `YOUR_PRIVATE_KEY` with your wallet's private key. @@ -83,10 +83,10 @@ Transaction hash: 0x967e1290b285e67b3d74940ee19925416734c345f58bd1ec64dcea134647 ## Deploy a smart contract using a `.env` file -Directly pasting your private key into the command line poses security risks. To avoid exposing sensitive -information such as wallet private keys or API keys, use files with the `.env` extension to store private -data. Create a `.env` file, then add the file to the `.gitignore` file to prevent committing it. Populate -the `.env` file with the relevant private information: +Directly pasting your private key into the command line poses security risks. To avoid exposing +sensitive information such as wallet private keys or API keys, use files with the `.env` extension +to store private data. Create a `.env` file, then add the file to the `.gitignore` file to prevent +committing it. Populate the `.env` file with the relevant private information: ```bash PRIVATE_KEY=YOUR_PRIVATE_KEY @@ -102,7 +102,7 @@ source .env Finally, modify the `foundry.toml` file to store the various RPC endpoints we might be working with. For example: ```bash -[rpc_endpoints] +[profile.rpc-endpoints] linea-sepolia = "https://linea-sepolia.infura.io/v3/${INFURA_API_KEY}" linea-mainnet = "https://linea-mainnet.infura.io/v3/${INFURA_API_KEY}" ``` diff --git a/docs/get-started/how-to/verify-smart-contract/foundry.mdx b/docs/get-started/how-to/verify-smart-contract/foundry.mdx index b2fe0c7c7..2db42b24e 100644 --- a/docs/get-started/how-to/verify-smart-contract/foundry.mdx +++ b/docs/get-started/how-to/verify-smart-contract/foundry.mdx @@ -85,7 +85,7 @@ forge create --rpc-url https://linea-sepolia.infura.io/v3/INFURA_API_KEY src/Cou You can check that it was verified correctly by navigating to the [testnet block explorer](https://sepolia.lineascan.build/) or the [mainnet block explorer](https://lineascan.build/) and pasting in the deployed contract address. -## Using `.env` and `foundry.toml` to store etherscan information +## Using `.env` and `foundry.toml` to store Lineascan information If you don't want to paste your keys inline and have multiple Etherscan API keys to manage, you can use the `.env` and `foundry.toml` files to set up custom configurations. diff --git a/sidebars.js b/sidebars.js index ee1bbfd5f..06a06d3ef 100644 --- a/sidebars.js +++ b/sidebars.js @@ -12,6 +12,18 @@ const sidebars = { link: null, collapsible: false, items: [ + { + type: "category", + label: "Quickstart", + link: { + type: "doc", + id: "get-started/build/quickstart/deploy", + }, + items: [ + "get-started/build/quickstart/deploy", + "get-started/build/quickstart/app", + ] + }, "get-started/build/ethereum-differences", "get-started/build/network-info", "get-started/build/contracts", diff --git a/src/pages/index.tsx b/src/pages/index.tsx index fceca8a8e..26762cc80 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -39,7 +39,7 @@ function HomepageHeader() { "button button--secondary button--lg", styles.bannerButton, )} - to="/get-started"> + to="/get-started/build/quickstart/deploy"> START BUILDING