From 15132570c8dc1145f5b15f0589e0c9b87e098829 Mon Sep 17 00:00:00 2001 From: jcstein <46639943+jcstein@users.noreply.github.com> Date: Mon, 16 Sep 2024 14:43:17 +0200 Subject: [PATCH] docs: remove useless evm tuts, rearrange menu, fix some typos --- .vitepress/config.ts | 48 +- developers/arbitrum-bridge.md | 3 + developers/arbitrum-dapp-deploy.md | 120 --- developers/arbitrum-smart-contract.md | 270 ------ developers/blobstream-proof-queries.md | 3 - ...eam-x-requesting-data-commitment-ranges.md | 6 +- developers/blobstreamx.md | 8 +- developers/bubs-testnet.md | 4 +- developers/deploy-on-bubs.md | 278 ------ .../full-stack-modular-development-guide.md | 811 ------------------ developers/gm-portal-bubs.md | 119 --- developers/intro-to-op-stack.md | 17 +- developers/optimism.md | 3 - developers/sp1-blobstream-deploy.md | 4 +- learn/staking.md | 4 +- nodes/celestia-app-commands.md | 3 - nodes/celestia-app-slashing.md | 2 +- nodes/decide-node.md | 16 +- 18 files changed, 48 insertions(+), 1671 deletions(-) delete mode 100644 developers/arbitrum-dapp-deploy.md delete mode 100644 developers/arbitrum-smart-contract.md delete mode 100644 developers/deploy-on-bubs.md delete mode 100644 developers/full-stack-modular-development-guide.md delete mode 100644 developers/gm-portal-bubs.md diff --git a/.vitepress/config.ts b/.vitepress/config.ts index 13105b53b27..da8745d92a1 100644 --- a/.vitepress/config.ts +++ b/.vitepress/config.ts @@ -475,7 +475,7 @@ function sidebarHome() { link: "/nodes/celestia-app-metrics", }, { - text: "Jailing and Slashing mechanics", + text: "Jailing and slashing mechanics", link: "/nodes/celestia-app-slashing", }, { @@ -547,14 +547,6 @@ function sidebarHome() { text: "How to customize your Orbit chain's deployment configuration", link: "https://docs.arbitrum.io/launch-orbit-chain/how-tos/customize-deployment-configuration", }, - { - text: "Deploy a smart contract on Arbitrum rollup", - link: "/developers/arbitrum-smart-contract", - }, - { - text: "Deploy a dapp on your Arbitrum rollup devnet", - link: "/developers/arbitrum-dapp-deploy", - }, { text: "Audit", link: "https://github.com/celestiaorg/nitro/blob/celestia-v2.3.3/audits/celestia/arbitrum_nitro_celestia_audit_report.pdf", @@ -567,8 +559,8 @@ function sidebarHome() { items: [ { text: "Documentation", link: "https://docs.astria.org" }, { - text: "Deploy to Dusknet", - link: "https://docs.astria.org/docs/local-rollup/introduction/", + text: "Just deploy", + link: "https://docs.astria.org/developer/tutorials/install-the-cli", }, ], }, @@ -580,33 +572,27 @@ function sidebarHome() { text: "Intro to OP Stack integration", link: "/developers/intro-to-op-stack", }, - { - text: "Bubs testnet", - link: "/developers/bubs-testnet", - }, - { - text: "Raspberry testnet", - link: "https://raas.gelato.network/rollups/details/public/opcelestia-raspberry", - }, - { - text: "Deploy a smart contract on Bubs testnet", - link: "/developers/deploy-on-bubs", - }, - { - text: "Deploy a dapp on Bubs testnet", - link: "/developers/gm-portal-bubs", - }, { text: "Run an OP Stack devnet posting Celestia", link: "/developers/optimism", }, { - text: "Audit", - link: "https://docs.celestia.org/audits/Celestia_OP_Stack_Audit.pdf", + text: "OP Stack testnets", + collapsed: true, + items: [ + { + text: "Bubs testnet", + link: "/developers/bubs-testnet", + }, + { + text: "Raspberry testnet", + link: "https://raas.gelato.network/rollups/details/public/opcelestia-raspberry", + }, + ] }, { - text: "Deploy a dapp with thirdweb", - link: "https://thirdweb.com/bubs-testnet", + text: "Audit", + link: "https://docs.celestia.org/audits/Celestia_OP_Stack_Audit.pdf", }, { text: "Rollups as a Service", diff --git a/developers/arbitrum-bridge.md b/developers/arbitrum-bridge.md index 0da3f3da6a3..bb7ffde6687 100644 --- a/developers/arbitrum-bridge.md +++ b/developers/arbitrum-bridge.md @@ -1,5 +1,8 @@ --- description: A guide on how to bridge in and out of your Arbitrum Orbit rollup. +next: + text: "Intro to OP Stack integration" + link: "/developers/intro-to-op-stack" --- # Bridging in and out of your Orbit rollup diff --git a/developers/arbitrum-dapp-deploy.md b/developers/arbitrum-dapp-deploy.md deleted file mode 100644 index 4e5bbe21f2e..00000000000 --- a/developers/arbitrum-dapp-deploy.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -description: Make your own GM Portal dapp on your Arbitrum rollup. -next: - text: "Intro to OP Stack integration" - link: "/developers/intro-to-op-stack" ---- - -# Deploy a dapp on your Arbitrum rollup devnet - -First, review the [Arbitrum integration](./arbitrum-integration.md), -[Quickstart: Deploy an Arbitrum Orbit rollup](./arbitrum-deploy.md), and -[Deploy a smart contract to your Arbitrum rollup](./arbitrum-smart-contract.md) -pages. - -## Dependencies - -- a funded account to deploy your smart contract -- an [Arbitrum rollup devnet](./arbitrum-deploy.md) running - -## Setup and contract deployment - -1. Clone the `gm-portal` from GitHub and start the frontend: - - ```bash - cd $HOME - git clone https://github.com/jcstein/gm-portal.git - cd gm-portal && git checkout arbitrum - cd frontend && yarn && yarn dev - ``` - -2. In a new terminal instance, set your private key for the - faucet as a variable and the RPC URL you're using: - - ```bash - export PRIVATE_KEY=0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 - export ARB_RPC_URL=http://localhost:8547 - ``` - -3. Change into the `gm-portal/contracts` directory in the same terminal and deploy - the contract using Foundry: - - - - ```bash - cd $HOME/gm-portal/contracts - forge script script/GmPortal.s.sol:GmPortalScript --rpc-url $ARB_RPC_URL --private-key $PRIVATE_KEY --broadcast - ``` - - - -4. In the output of the deployment, find the contract address and set it as a variable: - - ```bash - export CONTRACT_ADDRESS= - ``` - -### Interact with the contract - -Next, you're ready to interact with the contract from your terminal! - -1. Send a "gm" to the contract: - - ```bash - cast send $CONTRACT_ADDRESS \ - "gm(string)" "gm" \ - --private-key $PRIVATE_KEY \ - --rpc-url $ARB_RPC_URL - ``` - -2. Now that you've posted to the contract, you can read all "gms" (GMs) from the - contract with - this command: - - ```bash - cast call $CONTRACT_ADDRESS "getAllGms()" --rpc-url $ARB_RPC_URL - ``` - -3. Next, query the total number of gms, which will be returned as a hex value: - - ```bash - cast call $CONTRACT_ADDRESS "getTotalGms()" --rpc-url $ARB_RPC_URL - ``` - -4. (Optional) In order to interact with the contract on the frontend, you'll - need to fund an account that you have in your Ethereum wallet. Transfer to an - external account with this command: - - ```bash - export RECEIVER= - cast send --private-key $PRIVATE_KEY $RECEIVER --value 1ether --rpc-url $ARB_RPC_URL - ``` - - :::tip - If you are in a different terminal than the one you set the - private key in, you may need to set it again. - ::: - -## Update the frontend - -Next, you will need to update a few things before you can interact with the -contract on the frontend: - -1. Change the contract address on `gm-portal/frontend/src/App.tsx` to your - contract address -2. Match the chain info on `gm-portal/frontend/src/main.tsx` with the chain - config of your L2 -3. If you changed the contract, update the ABI in - `gm-portal/frontend/GmPortal.json` from - `gm-portal/contracts/out/GmPortal.sol/GmPortal.json`. This can be done with: - -```bash -cd $HOME -cp dev/gm-portal/contracts/out/GmPortal.sol/GmPortal.json dev/gm-portal/frontend -``` - -## Interact with the frontend - -Now, login with your wallet that you funded, and post a GM on your GM portal! - -![gm-arb](/img/gm-arb.png) diff --git a/developers/arbitrum-smart-contract.md b/developers/arbitrum-smart-contract.md deleted file mode 100644 index 64257114aa6..00000000000 --- a/developers/arbitrum-smart-contract.md +++ /dev/null @@ -1,270 +0,0 @@ ---- -description: A tutorial that guides you through the process of deploying a smart contract to your Arbitrum rollup using a L2 Nitro devnet, including setting up the environment, creating and testing the smart contract, and interacting with the deployed contract. ---- - -# Deploy a smart contract to your Arbitrum rollup - -## Overview - -Welcome to the guide on deploying a smart contract to your Arbitrum rollup. In -this tutorial, you will learn how to deploy a smart contract using the L2 Nitro -devnet and the provided public and private keys for testing purposes. - -## Prerequisites - -- [Nitro rollup devnet](./arbitrum-deploy.md) - running -- [Foundry](https://getfoundry.sh/) installed on your machine -- [Node.js](https://nodejs.org/en) -- Basic understanding of Ethereum -- Basic understanding of Solidity and Node.js - -## Setup - -First, in your `$HOME` directory, set up a new project folder for this -tutorial and init the project with npm: - -```bash -cd $HOME -mkdir counter-project && cd counter-project && npm init -y -``` - -Next, initialize a Foundry project with the following command: - -```bash -forge init counter_contract -``` - -## Create your smart contract - -Take a look at the `Counter.sol` file in your -`counter-project/counter_contract/src` directory: - -```solidity -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -contract Counter { - uint256 public number; - - function setNumber(uint256 newNumber) public { - number = newNumber; - } - - function increment() public { - number++; - } -} -``` - -The contract contains a public unsigned integer variable named "number". -There are two public functions in this contract. The `setNumber` function -allows anyone to set a new value for the "number" variable, while the -`increment` function increases the value of "number" by one each time it's -called. - -You can -[learn more about Solidity and smart contract programming](https://ethereum.org/en/developers/learning-tools/). - -To compile the contract, run the following forge command from the -`$HOME/counter-project/counter_contract/` directory: - -```bash -forge build -``` - -Your output should look similar to the following: - -```bash -[⠢] Compiling... -[⠔] Compiling 21 files with 0.8.19 -[⠑] Solc 0.8.19 finished in 1.24s -Compiler run successful -``` - -## Test your smart contract - -Now, open the `test/Counter.t.sol` file: - -```solidity -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -import "forge-std/Test.sol"; -import "../src/Counter.sol"; - -contract CounterTest is Test { - Counter public counter; - - function setUp() public { - counter = new Counter(); - counter.setNumber(0); - } - - function testIncrement() public { - counter.increment(); - assertEq(counter.number(), 1); - } - - function testSetNumber(uint256 x) public { - counter.setNumber(x); - assertEq(counter.number(), x); - } -} -``` - -This file performs unit testing on the contract we created in the previous -section. Here's what the test is doing: - -- The contract includes a public "Counter" type variable called "counter". - In the `setUp` function, it initializes a new instance of the "Counter" - contract and sets the "number" variable to 0. - -- There are two test functions in the contract: `testIncrement` and - `testSetNumber`. - -- The `testIncrement` function tests the "increment" function of the - "Counter" contract by calling it and then asserting that the "number" in - the "Counter" contract is 1. It verifies if the increment operation - correctly increases the number by one. - -- The `testSetNumber` function is more generic. It takes an unsigned integer - argument 'x' and tests the "setNumber" function of the "Counter" contract. - After calling the "setNumber" function with 'x', it asserts that the - "number" in the "Counter" contract is equal to 'x'. This verifies that the - "setNumber" function correctly updates the "number" in the "Counter" - contract. - -Now, to test your code, run the following: - -```bash -forge test -``` - -If the test is successful, your output should be similar to this: - -```bash -[⠆] Compiling... -No files changed, compilation skipped - -Running 2 tests for test/Counter.t.sol:CounterTest -[PASS] testIncrement() (gas: 28334) -[PASS] testSetNumber(uint256) (runs: 256, μ: 27709, ~: 28409) -Test result: ok. 2 passed; 0 failed; finished in 8.96ms -``` - -## Deploying your smart contract - -### Funded accounts - -Your L2 Nitro devnet will have a -[public and private key funded as a faucet to use for testing](https://docs.arbitrum.io/node-running/how-tos/local-dev-node#default-endpoints-and-addresses): - -- On both L1 and L2 - - Public key: `0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E` - - Private key: - `0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659` - -Alternatively, you can -[fund other addresses by using the scripts `send-l1` and `send-l2`](https://docs.arbitrum.io/node-running/how-tos/local-dev-node#helper-scripts). - -The L1 Geth devnet will be running at `http://localhost:8545` and the L2 Nitro -devnet will be on `http://localhost:8547` and `ws://localhost:8548`. - -### Using our Arbitrum devnet - -We will use the local RPC endpoint (`http://localhost:8547`) and accounts -above to test with. - -Let's deploy the contract now. First, set a private key from anvil: - -```bash -export L2_PRIVATE_KEY=0xe887f7d17d07cc7b8004053fb8826f6657084e88904bb61590e498ca04704cf2 -export ARB_RPC_URL=http://localhost:8547 -``` - -Now, deploy the contract: - -```bash -forge create --rpc-url $ARB_RPC_URL \ - --private-key $L2_PRIVATE_KEY \ - src/Counter.sol:Counter -``` - -A successful deployment will return output similar to below: - -```bash -[⠆] Compiling... -No files changed, compilation skipped -Deployer: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 -Deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 -Transaction hash: 0xf1a793a793cd9fc588f5132d99008565ea361eb3535d66499575e9e1908200b2 -``` - -Once you've deployed the contract, you're ready to interact with it! - -First, we'll set it as a variable: - -```bash -export CONTRACT_ADDRESS=0x5FbDB2315678afecb367f032d93F642f64180aa3 -``` - -## Interacting with your smart contract - -Foundry uses `cast`, a CLI for performing Ethereum RPC calls. - -To write to the contract, we'll use the `cast send` command: - - - -```bash -cast send $CONTRACT_ADDRESS "setNumber(uint256)" 10 \ - --rpc-url $ARB_RPC_URL --private-key $L2_PRIVATE_KEY -``` - -Your output will look similar: - -```bash -blockHash 0x131822bef6eb59656d7e1387c19b75be667e587006710365ec5cf58030786c42 -blockNumber 3 -contractAddress -cumulativeGasUsed 43494 -effectiveGasPrice 3767182372 -gasUsed 43494 -logs [] -logsBloom 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -root -status 1 -transactionHash 0x8f15d6004598f0662dd673a9898dceef77be8cc28408cecc284b28d7be32307d -transactionIndex 0 -type 2 -``` - - - -Now, we can make a read call to view the state of the number variable, -using the `cast call` command: - -```bash -cast call $CONTRACT_ADDRESS "number()" --rpc-url $ARB_RPC_URL -``` - -The result will look similar: - -```bash -0x000000000000000000000000000000000000000000000000000000000000000a -``` - -Convert the result from hexadecimal to a base 10 value with: - -```bash -echo $((0x000000000000000000000000000000000000000000000000000000000000000a)) -``` - -## Next steps - -Congratulations! You've learned how to deploy a smart contract to your Arbitrum -rollup devnet. - -What will you build next? In our next tutorial, we will be going over how to -deploy a dapp to your Arbitrum rollup. diff --git a/developers/blobstream-proof-queries.md b/developers/blobstream-proof-queries.md index bc8a478e409..e6648b1bdc0 100644 --- a/developers/blobstream-proof-queries.md +++ b/developers/blobstream-proof-queries.md @@ -1,8 +1,5 @@ --- description: Learn how to query the inclusion proofs used in Blobstream -next: - text: "Requesting data commitment ranges" - link: "/developers/blobstream-x-requesting-data-commitment-ranges" --- # Blobstream proofs queries diff --git a/developers/blobstream-x-requesting-data-commitment-ranges.md b/developers/blobstream-x-requesting-data-commitment-ranges.md index be35b67a653..2d524619b32 100644 --- a/developers/blobstream-x-requesting-data-commitment-ranges.md +++ b/developers/blobstream-x-requesting-data-commitment-ranges.md @@ -1,7 +1,7 @@ --- prev: - text: "Querying the Blobstream proofs" - link: "/developers/blobstream-proof-queries" + text: "Overview of Blobstream X" + link: "/developers/blobstreamx" --- # Requesting data commitment ranges @@ -32,7 +32,7 @@ Alternatively, if a team needs a very specific cadence that starts at very speci BlobstreamX contract and submit proofs to it. Deployment instructions can be found in the [BlobstreamX deploy](./blobstream-x-deploy.md) documentation. -::: Note +::: tip Requires a large cloud machine to run in a reasonable amount of time. EC2 r6a.16xlarge, i.e., 64CPU 512GB RAM, takes ~30 minutes to generate a header range proof. diff --git a/developers/blobstreamx.md b/developers/blobstreamx.md index 44afe00cab6..83c56819001 100644 --- a/developers/blobstreamx.md +++ b/developers/blobstreamx.md @@ -1,8 +1,14 @@ --- description: What is BlobstreamX +prev: + text: "New SP1 Blobstream deployments" + link: "/developers/sp1-blobstream-deploy" +next: + text: "Requesting data commitment ranges" + link: "/developers/blobstream-x-requesting-data-commitment-ranges" --- -# BlobstreamX: the previous zk implementation of Blobstream +# Blobstream X: the previous zk implementation of Blobstream ![blobstream x draft diagram](/img/blobstream/Celestia_Blobstream_X1b.png) diff --git a/developers/bubs-testnet.md b/developers/bubs-testnet.md index 7634d3e5de4..509fdd4760a 100644 --- a/developers/bubs-testnet.md +++ b/developers/bubs-testnet.md @@ -1,8 +1,8 @@ --- description: The first testnet built with OP Stack and Celestia. next: - text: "Deploy a smart contract on Bubs testnet" - link: "/developers/deploy-on-bubs" + text: "Ethereum fallback mechanism" + link: "/developers/ethereum-fallback" --- # Bubs testnet diff --git a/developers/deploy-on-bubs.md b/developers/deploy-on-bubs.md deleted file mode 100644 index e275eb6dbca..00000000000 --- a/developers/deploy-on-bubs.md +++ /dev/null @@ -1,278 +0,0 @@ ---- -prev: - text: "Bubs testnet" - link: "/developers/bubs-testnet" ---- - -# Deploy a smart contract on Bubs testnet - -In this tutorial, we will deploy a smart contract to the -Bubs testnet. - -## Dependencies - -- [Foundry](https://getfoundry.sh/) installed on your machine -- [Node.js](https://nodejs.org/en) -- Basic understanding of Ethereum -- Basic understanding of Solidity and Node.js -- Bubs ETH from the [Bubs faucet](https://bubs-sepolia.hub.caldera.xyz/) or -[Bubs bridge](https://bubs-sepolia.bridge.caldera.xyz/) -- A Bubs RPC URL from the [Bubs testnet page](./bubs-testnet.md) - -## Setup - -First, in your `$HOME` directory, set up a new project folder for this -tutorial and init the project with npm: - -```bash -cd $HOME -mkdir counter-project && cd counter-project && npm init -y -``` - -Next, initialize a Foundry project with the following command: - -```bash -forge init counter_contract -``` - -## Create your smart contract - -Take a look at the `Counter.sol` file in your -`counter-project/counter_contract/src` directory: - -```solidity -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -contract Counter { - uint256 public number; - - function setNumber(uint256 newNumber) public { - number = newNumber; - } - - function increment() public { - number++; - } -} -``` - -The contract contains a public unsigned integer variable named "number". -There are two public functions in this contract. The `setNumber` function -allows anyone to set a new value for the "number" variable, while the -`increment` function increases the value of "number" by one each time it's -called. - -You can -[learn more about Solidity and smart contract programming](https://ethereum.org/en/developers/learning-tools/). - -To compile the contract, run the following forge command from the -`$HOME/counter-project/counter_contract/` directory: - -```bash -forge build -``` - -Your output should look similar to the following: - -```bash -[⠢] Compiling... -[⠔] Compiling 21 files with 0.8.19 -[⠑] Solc 0.8.19 finished in 1.24s -Compiler run successful -``` - -## Test your smart contract - -Now, open the `test/Counter.t.sol` file: - -```solidity -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -import "forge-std/Test.sol"; -import "../src/Counter.sol"; - -contract CounterTest is Test { - Counter public counter; - - function setUp() public { - counter = new Counter(); - counter.setNumber(0); - } - - function testIncrement() public { - counter.increment(); - assertEq(counter.number(), 1); - } - - function testSetNumber(uint256 x) public { - counter.setNumber(x); - assertEq(counter.number(), x); - } -} -``` - -This file performs unit testing on the contract we created in the previous -section. Here's what the test is doing: - -- The contract includes a public "Counter" type variable called "counter". - In the `setUp` function, it initializes a new instance of the "Counter" - contract and sets the "number" variable to 0. - -- There are two test functions in the contract: `testIncrement` and - `testSetNumber`. - -- The `testIncrement` function tests the "increment" function of the - "Counter" contract by calling it and then asserting that the "number" in - the "Counter" contract is 1. It verifies if the increment operation - correctly increases the number by one. - -- The `testSetNumber` function is more generic. It takes an unsigned integer - argument 'x' and tests the "setNumber" function of the "Counter" contract. - After calling the "setNumber" function with 'x', it asserts that the - "number" in the "Counter" contract is equal to 'x'. This verifies that the - "setNumber" function correctly updates the "number" in the "Counter" - contract. - -Now, to test your code, run the following: - -```bash -forge test -``` - -If the test is successful, your output should be similar to this: - -```bash -[⠆] Compiling... -No files changed, compilation skipped - -Running 2 tests for test/Counter.t.sol:CounterTest -[PASS] testIncrement() (gas: 28334) -[PASS] testSetNumber(uint256) (runs: 256, μ: 27709, ~: 28409) -Test result: ok. 2 passed; 0 failed; finished in 8.96ms -``` - -## Deploying your smart contract - -### Using Anvil - -First, we'll test out our contract on a local devnet called "anvil". To start -the local server, run: - -```bash -anvil -``` - -You'll see a local RPC endpoint (`127.0.0.1:8545`) and accounts to test with. - -Let's deploy the contract now. First, set a private key from anvil: - -```bash -export PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 -export ANVIL_RPC_URL=http://localhost:8545 -``` - -Now, deploy the contract: - -```bash -forge create --rpc-url $ANVIL_RPC_URL \ ---private-key $PRIVATE_KEY \ -src/Counter.sol:Counter -``` - -### Using Bubs - -First, set a private key from your funded Ethereum wallet and -set the `BUBS_RPC_URL` variable with an -[RPC of your choosing](./bubs-testnet.md#rpc-urls): - -```bash -export BUBS_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 -export BUBS_RPC_URL=https://bubs-sepolia.rpc.caldera.xyz/http -``` - -Now that we're ready to deploy the smart contract onto Bubs, we will run -the `forge create` command. - -```bash -forge create --rpc-url $BUBS_RPC_URL \ ---private-key $BUBS_PRIVATE_KEY \ -src/Counter.sol:Counter -``` - -A successful deployment will return output similar to below: - -```bash -[⠆] Compiling... -No files changed, compilation skipped -Deployer: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 -Deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 -Transaction hash: 0xf1a793a793cd9fc588f5132d99008565ea361eb3535d66499575e9e1908200b2 -``` - -Once you've deployed the contract, you're ready to interact with it! - -First, we'll set it as a variable: - -```bash -export CONTRACT_ADDRESS=0x5FbDB2315678afecb367f032d93F642f64180aa3 -``` - -## Interacting with your smart contract - -Foundry uses `cast`, a CLI for performing Ethereum RPC calls. - -To write to the contract, we'll use the `cast send` command: - - - -```bash -cast send $CONTRACT_ADDRESS "setNumber(uint256)" 10 --rpc-url $BUBS_RPC_URL --private-key $BUBS_PRIVATE_KEY -``` - - - -Your output will look similar: - -```bash -blockHash 0x131822bef6eb59656d7e1387c19b75be667e587006710365ec5cf58030786c42 -blockNumber 3 -contractAddress -cumulativeGasUsed 43494 -effectiveGasPrice 3767182372 -gasUsed 43494 -logs [] -logsBloom 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -root -status 1 -transactionHash 0x8f15d6004598f0662dd673a9898dceef77be8cc28408cecc284b28d7be32307d -transactionIndex 0 -type 2 -``` - -Now, we can make a read call to view the state of the number variable, -using the `cast call` command: - -```bash -cast call $CONTRACT_ADDRESS "number()" --rpc-url $BUBS_RPC_URL -``` - -The result will look similar: - -```bash -0x000000000000000000000000000000000000000000000000000000000000000a -``` - -Convert the result from hexadecimal to a base 10 value with: - -```bash -echo $((0x000000000000000000000000000000000000000000000000000000000000000a)) -``` - -## Next steps - -Congratulations! You've learned how to deploy a smart contract to Bubs testnet. - -What will you build next? Now, you're ready to check out the -[GM Portal tutorial](./gm-portal-bubs.md). diff --git a/developers/full-stack-modular-development-guide.md b/developers/full-stack-modular-development-guide.md deleted file mode 100644 index 58994f270ec..00000000000 --- a/developers/full-stack-modular-development-guide.md +++ /dev/null @@ -1,811 +0,0 @@ ---- -description: Learn to build a full stack modular dapp. ---- - -# Full stack modular blockchain development guide - -:::tip Note -This tutorial needs to be updated -::: - -This guide will introduce you to -[modular blockchains](../learn/how-celestia-works/introduction.md) like -Celestia, explain their benefits, and show you how to build a full stack -modular dapp with React, Vite, RainbowKit, Celestia, and Foundry. - -Current blockchain architectures are not scalable and face challenges -around accessibility. In order for blockchains and web3 to reach mass -adoption, these challenges must be addressed. - -Blockchains have evolved over time from application-specific networks like -Bitcoin to shared smart contract platforms like Ethereum. This guide will -cover how to build dapps on these newer, shared platforms. - -If you're interested in learning more about modular blockchains, or are new -to the Celestia ecosystem, we recommend you read the -[build whatever page](./build-whatever.md) first. - -## Getting started - -Now that you’ve had an overview of what Celestia is, let’s start building! - -The execution environment that we’ll be leveraging today is Ethermint, an -EVM-compatible testnet that you will run locally for this tutorial. - -### Pre-requisites - -- [Node.js](https://github.com/nvm-sh/nvm) -- [Foundry](https://github.com/foundry-rs/foundry) -- [Infura account](https://infura.io) (for uploading files to IPFS) -- [A Celestia light node running](./node-tutorial.md) (to post PFBs from your - rollup) -- EVM Tutorial (Coming soon!) - for - running your own EVM rollup & deploying your smart contract -- [MetaMask wallet](https://metamask.io) (for connecting to your frontend) - -### Project setup - -To get started, create a new Foundry project: - -```bash -forge init celestia-dapp -cd celestia-dapp -``` - -Foundry has created an example smart contract located at `src/Contract.sol`. - -#### Updating the contract and tests - -Let's update the contracts to include a basic blog example. Create a new file -in the `src` directory named `Contract.sol` with the following code: - - - -```solidity title="src/Contract.sol" -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -contract Blog { - string public name; - address public owner; - - uint private _postId; - - struct Post { - uint id; - string title; - string content; - bool published; - } - /* mappings can be seen as hash tables */ - /* here we create lookups for posts by id and posts by ipfs hash */ - mapping(uint => Post) private idToPost; - mapping(string => Post) private hashToPost; - - /* events facilitate communication between smart contracts and their user interfaces */ - /* i.e. we can create listeners for events in the client and also use them in The Graph */ - event PostCreated(uint id, string title, string hash); - event PostUpdated(uint id, string title, string hash, bool published); - - /* when the blog is deployed, give it a name */ - /* also set the creator as the owner of the contract */ - constructor(string memory _name) { - name = _name; - owner = msg.sender; - } - - /* updates the blog name */ - function updateName(string memory _name) public { - name = _name; - } - - /* transfers ownership of the contract to another address */ - function transferOwnership(address newOwner) public onlyOwner { - owner = newOwner; - } - - /* fetches an individual post by the content hash */ - function fetchPost(string memory hash) public view returns(Post memory){ - return hashToPost[hash]; - } - - /* creates a new post */ - function createPost(string memory title, string memory hash) public onlyOwner { - _postId = _postId + 1; - Post storage post = idToPost[_postId]; - post.id = _postId; - post.title = title; - post.published = true; - post.content = hash; - hashToPost[hash] = post; - emit PostCreated(_postId, title, hash); - } - - /* updates an existing post */ - function updatePost(uint postId, string memory title, string memory hash, bool published) public onlyOwner { - Post storage post = idToPost[postId]; - post.title = title; - post.published = published; - post.content = hash; - idToPost[postId] = post; - hashToPost[hash] = post; - emit PostUpdated(post.id, title, hash, published); - } - - /* fetches all posts */ - function fetchPosts() public view returns (Post[] memory) { - uint itemCount = _postId; - - Post[] memory posts = new Post[](itemCount); - for (uint i = 0; i < itemCount; i++) { - uint currentId = i + 1; - Post storage currentItem = idToPost[currentId]; - posts[i] = currentItem; - } - return posts; - } - - /* this modifier means only the contract owner can */ - /* invoke the function */ - modifier onlyOwner() { - require(msg.sender == owner); - _; - } -} -``` - - - -Next, let's create a test for this contract. - -Open `test/Contract.t.sol` and update the code with the following: - -```solidity title="test/Contract.t.sol" -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import "forge-std/Test.sol"; -import "src/Contract.sol"; - -contract ContractTest is Test { - Blog blog; - - function setUp() public { - blog = new Blog("Celestia Blog"); - } - - function testCreatePost() public { - blog.createPost("My first post", "12345"); - Blog.Post[] memory posts = blog.fetchPosts(); - assertEq(posts.length, 1); - } - - function testUpdatePost() public { - blog.createPost("My first post", "12345"); - blog.updatePost(1, "My second post", "12345", true); - Blog.Post memory updatedPost = blog.fetchPost("12345"); - assertEq(updatedPost.title, "My second post"); - } - - function testFetchPosts() public { - Blog.Post[] memory posts = blog.fetchPosts(); - assertEq(posts.length, 0); - blog.createPost("My first post", "12345"); - posts = blog.fetchPosts(); - assertEq(posts.length, 1); - } - - function testOnlyOwner() public { - blog.createPost("My first post", "12345"); - address bob = address(0x1); - vm.startPrank(bob); - vm.expectRevert(); - blog.updatePost(1, "My second post", "12345", true); - } -} -``` - -Foundry uses [Dappsys Test](https://book.getfoundry.sh/reference/ds-test.html) -to provide basic logging and assertion functionality. It's included in the Forge -Standard Library. - -Here, we are using `assertEq` to assert equality. You can -[view all of the assertion functions available](https://book.getfoundry.sh/reference/ds-test.html?highlight=log_int#asserting). - -#### Running the test - -We can now run our tests to make sure our contract is working properly: - -```bash -forge test -vv -``` - -#### Updating the deployment script - -Now that we've tested the contract, let's try deploying it locally using -[Solidity Scripting](https://book.getfoundry.sh/tutorials/solidity-scripting.html). - -To do so, update the deployment script at `script/Contract.s.sol` with the -following code: - -```solidity title="script/Contract.s.sol" -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.13; - -import "forge-std/Script.sol"; - -import {Blog} from "src/Contract.sol"; - -contract ContractScript is Script { - function setUp() public {} - - function run() public { - vm.startBroadcast(); - new Blog("Celestia Blog"); - vm.stopBroadcast(); - } -} -``` - -Now we can use this script to deploy our smart contract to either a live or test -network. - -#### Deploying locally - -Next start Anvil, the local testnet: - -```bash -anvil --port 9545 -``` - -:::danger caution - -We need to use port 9545, because Ethermint will use 8545. - -::: - -Once started, Anvil will give you a local RPC endpoint as well as a handful of -Private Keys and Accounts that you can use. - -We can now use the local RPC along with one of the private keys to deploy locally: - -```bash -forge script script/Contract.s.sol:ContractScript --fork-url \ -http://localhost:9545 --private-key $PRIVATE_KEY --broadcast -``` - -Once the contract has been deployed locally, Anvil will log out the contract address. - -**Take a note of this local contract address as we’ll be using it later in the -frontend application.** - -Next, set the contract address as an environment variable: - -```bash -export CONTRACT_ADDRESS= -``` - -We can then test sending transactions to it with `cast send`. - -```bash -cast send $CONTRACT_ADDRESS \ -"createPost(string,string)" "my first post" "12345" \ ---private-key $PRIVATE_KEY -``` - -We can then perform read operations with `cast call`: - -```bash -cast call $CONTRACT_ADDRESS "fetchPosts()" -``` - -Once the contract is deployed successfully, **take a note of the contract -address as we’ll also be needing it in just a moment when we test the live contract**. - -### Deploying to the Ethermint Sovereign Rollup - -First, we will need to follow the setup from the EVM tutorial. - -:::danger Pre-requisites - -It is required that you complete dependency setup, -Rollkit installation, and -Instantiating and EVM rollup from the -EVM tutorial -to complete the remainder of the tutorial. - -::: - -Now that we've deployed and tested locally, we can deploy to our -Ethermint chain. - -First, we will need to export the private key generated by -the ethermint `init.sh` script: - -```bash -PRIVATE_KEY=$(ethermintd keys unsafe-export-eth-key mykey --keyring-backend test) -``` - -:::tip NOTE -Here, the key name from `init.sh` is `mykey` but you can modify -the `init.sh` to change the name of your key. -::: - -Now, we can start deploying the smart contract to our Ethermint chain. - -To do so, run the following script in the `celestia-dapp` directory: - -```bash -forge script script/Contract.s.sol:ContractScript \ ---rpc-url http://localhost:8545 --private-key $PRIVATE_KEY --broadcast -``` - -Set the contract address in the output as the `CONTRACT_ADDRESS` variable: - -```bash -export CONTRACT_ADDRESS= -``` - -Once the contract has been deployed to the Ethermint rollup, we can -use `cast send` to test sending transactions to it: - -```bash -cast send $CONTRACT_ADDRESS \ -"createPost(string,string)" "my first post" "12345" \ ---rpc-url http://localhost:8545 --private-key $PRIVATE_KEY -``` - -We can then perform read operations with `cast call`: - -```bash -cast call $CONTRACT_ADDRESS "fetchPosts()" --rpc-url http://localhost:8545 -``` - -:::tip NOTE -You will want to redeploy the contract for your frontend, because -the post is not uploaded to IPFS in the CLI. -::: - -### Building the frontend - -For the frontend project, we’ll be using the following libraries and frameworks: - -[React](https://reactjs.org) - JavaScript library for building user interfaces - -[Vite](https://vitejs.dev) - Project generator / rapid development tool for -modern web projects - -[Rainbowkit](https://www.rainbowkit.com) - Easy and beautiful library to connect -a wallet - -[WAGMI](https://github.com/wagmi-dev/wagmi) - 20+ hooks for working with -wallets, ENS, contracts, transactions, signing, etc - -In the root of the Foundry project, create a new React.js application using [Vite](https://vitejs.dev): - -```jsx -yarn create vite - -? Project name: › frontend -? Select a framework › React -? Select a variant > JavaScript -``` - -Next, copy the ABI that was created by Foundry into the `frontend` directory so -that we can have it later (or manually copy it into a file named `Blog.json` in -the `frontend` directory): - -```bash -cp out/Contract.sol/Blog.json frontend/ -``` - -Now, change into the `frontend` directory and install the `node_modules`: - -```bash -cd frontend -yarn -``` - -#### Configuring environment variables - -Next we need to configure the environment variables for the Infura project ID -and secret. - -First, create an Infura account and new project for IPFS. - -Create a file named `.env.local` in the `frontend/` directory and add the following -configuration with your own credentials: - -```txt -VITE_INFURA_ID=your-project-api-key -VITE_INFURA_SECRET=your-project-api-key-secret -``` - -Now that the project is created, let’s install the additional dependencies using -either **NPM**, **Yarn**, or **PNPM**: - -```jsx -npm install @rainbow-me/rainbowkit@0.8.0 wagmi@0.8.10 ethers ipfs-http-client react-markdown -``` - -### Configuring the entrypoint - -Next we’ll update the entrypoint at `src/main.jsx`. - -The main things we’re doing here have to do with the configuration of Rainbowkit -so that we can have a nice way for the user to connect their wallet. - -Rainbowkit also allows a customizable array of network providers, so we’re -creating a new network configuration for `Ethermint`. - -```jsx title="frontend/src/main.jsx" -import "./polyfills"; -import ReactDOM from "react-dom/client"; -import App from "./App"; -import "./index.css"; -import "@rainbow-me/rainbowkit/styles.css"; -import { RainbowKitProvider } from "@rainbow-me/rainbowkit"; -import { chain, configureChains, createClient, WagmiConfig } from "wagmi"; -import { publicProvider } from "wagmi/providers/public"; -import { injectedWallet, metaMaskWallet } from "@rainbow-me/rainbowkit/wallets"; -import { connectorsForWallets } from "@rainbow-me/rainbowkit"; - -/* create configuration for Ethermint testnet */ -const ethermint = { - id: 9000, - name: "Ethermint", - network: "ethermint", - nativeCurrency: { - decimals: 18, - name: "Ethermint", - symbol: "CTE", - }, - rpcUrls: { - default: { - http: ["http://localhost:8545/"], - }, - }, - testnet: true, -}; - -// remove chain.localhost or ethermint depending on which you want to connect to -const { chains, provider } = configureChains( - [chain.localhost, ethermint], - [publicProvider()], -); - -const connectors = connectorsForWallets([ - { - groupName: "Recommended", - wallets: [metaMaskWallet({ chains }), injectedWallet({ chains })], - }, -]); - -const wagmiClient = createClient({ - autoConnect: true, - connectors, - provider, -}); - -const containerStyle = { - width: "900px", - margin: "0 auto", -}; - -ReactDOM.createRoot(document.getElementById("root")).render( - - -
- -
-
-
, -); -``` - -### Creating and reading posts - -Now that the base configuration is set up we’ll create a view that allows -users to create and view posts. - -We’ll be using IPFS to upload the content of the post, then anchoring the hash -of the post on chain. When we retrieve the post, we can then read the value from -IPFS to view the post. - -Update App.jsx with the following code: - - - -```jsx title="frontend/src/App.jsx" -import { useState, useEffect } from "react"; -import { ConnectButton } from "@rainbow-me/rainbowkit"; -import { ethers } from "ethers"; -import { create } from "ipfs-http-client"; -import { Buffer } from "buffer"; -import Blog from "../Blog.json"; -import { useAccount } from "wagmi"; - -/* configure authorization for Infura and IPFS */ -const auth = - "Basic " + - Buffer.from( - import.meta.env.VITE_INFURA_ID + ":" + import.meta.env.VITE_INFURA_SECRET, - ).toString("base64"); - -/* create an IPFS client */ -const client = create({ - host: "ipfs.infura.io", - port: 5001, - protocol: "https", - headers: { - authorization: auth, - }, -}); - -const contractAddress = "your-ethermint-contract-address"; - -function App() { - useEffect(() => { - fetchPosts(); - }, []); - const [viewState, setViewState] = useState("view-posts"); - const [posts, setPosts] = useState([]); - const [title, setTitle] = useState(""); - const [content, setContent] = useState(""); - const { address } = useAccount(); - - /* when the component loads, useEffect will call this function */ - async function fetchPosts() { - const provider = new ethers.providers.Web3Provider(window.ethereum); - const contract = new ethers.Contract(contractAddress, Blog.abi, provider); - let data = await contract.fetchPosts(); - /* once the data is returned from the network we map over it and */ - /* transform the data into a more readable format */ - data = data.map((d) => ({ - content: d["content"], - title: d["title"], - published: d["published"], - id: d["id"].toString(), - })); - - /* we then fetch the post content from IPFS and add it to the post objects */ - data = await Promise.all( - data.map(async (d) => { - const endpoint = `https://infura-ipfs.io/ipfs/${d.content}`; - const options = { - mode: "no-cors", - }; - const response = await fetch(endpoint, options); - const value = await response.text(); - d.postContent = value; - return d; - }), - ); - - setPosts(data); - } - - async function createPost() { - const added = await client.add(content); - const provider = new ethers.providers.Web3Provider(window.ethereum); - const signer = provider.getSigner(); - - const contract = new ethers.Contract(contractAddress, Blog.abi, signer); - const tx = await contract.createPost(title, added.path); - await tx.wait(); - setViewState("view-posts"); - } - - function toggleView(value) { - setViewState(value); - if (value === "view-posts") { - fetchPosts(); - } - } - - return ( -
-
-

Modular Rollup Blog

-

- This allows users to securely create and share blog posts on the - blockchain without the need for a centralized server or authority. -

- {!address ? ( -
-

Getting Started

-

- First, you will need to connect your Ethereum wallet to Ethermint - to display the posts from the smart contract and make posts. -

-
- ) : null} -
-

- Connect your Ethereum wallet to begin ✨ -

-
- -
- {address ? ( -
- - -
- ) : null} - {viewState === "view-posts" && address && ( -
-
-

Posts

- {posts.map((post, index) => ( -
-

{post.title}

- - {/* - {post.postContent} - */} -

GMID: {post.id}

-
- ))} -
-
- )} - {viewState === "create-post" && ( -
-

Create Post

- setTitle(e.target.value)} - style={inputStyle} - /> -