From fb000353c75e0109fffbb64709f7bc485b89610a Mon Sep 17 00:00:00 2001
From: douglance <4741454+douglance@users.noreply.github.com>
Date: Mon, 27 Apr 2026 09:08:34 -0400
Subject: [PATCH 1/2] Add interactive Solidity tutorial workbench
Replace the Remix-based Solidity quickstart with an in-browser
SolidityQuickstartWorkbench plus reusable interactive-tutorial
primitives (shell, checklist, steps, code walkthrough, command
block). Wire these into MDXComponents and DocItem/Content via a
new docusaurus plugin. Drop posthog-docusaurus, add react-joyride,
and update related docs links.
---
.../01-quickstart-solidity-remix.mdx | 839 +------
.../06-monitoring-tools-block-explorers.mdx | 2 +-
.../setup-custom-gateway.mdx | 2 +-
.../setup-generic-custom-gateway.mdx | 2 +-
docs/for-devs/oracles/api3/api3.mdx | 2 +-
docs/for-devs/oracles/chainlink/chainlink.mdx | 2 +-
docs/for-devs/oracles/trellor/trellor.mdx | 2 +-
docs/get-started/overview.mdx | 6 +-
docusaurus.config.js | 13 +-
package.json | 2 +-
.../InteractiveTutorials/CodeWalkthrough.tsx | 151 ++
.../InteractiveTutorialShell.tsx | 23 +
.../InteractiveTutorials/SolidityLab.tsx | 1852 +++++++++++++++
.../SolidityQuickstartWorkbench.tsx | 126 +
.../TutorialPrimitives.tsx | 137 ++
.../InteractiveTutorials/browserChain.ts | 149 ++
.../codeWalkthroughParser.ts | 109 +
src/components/InteractiveTutorials/index.ts | 11 +
.../InteractiveTutorials/styles.module.css | 2110 +++++++++++++++++
src/css/custom.scss | 48 +
src/pages/dev/solidity-lab.tsx | 274 +++
src/plugins/interactive-tutorials/index.js | 73 +
src/resources/interactiveTutorialSources.ts | 30 +
src/theme/CodeBlock/index.tsx | 22 +
src/theme/DocItem/Content/index.js | 17 +-
src/theme/MDXComponents.js | 12 +
yarn.lock | 75 +-
27 files changed, 5233 insertions(+), 858 deletions(-)
create mode 100644 src/components/InteractiveTutorials/CodeWalkthrough.tsx
create mode 100644 src/components/InteractiveTutorials/InteractiveTutorialShell.tsx
create mode 100644 src/components/InteractiveTutorials/SolidityLab.tsx
create mode 100644 src/components/InteractiveTutorials/SolidityQuickstartWorkbench.tsx
create mode 100644 src/components/InteractiveTutorials/TutorialPrimitives.tsx
create mode 100644 src/components/InteractiveTutorials/browserChain.ts
create mode 100644 src/components/InteractiveTutorials/codeWalkthroughParser.ts
create mode 100644 src/components/InteractiveTutorials/index.ts
create mode 100644 src/components/InteractiveTutorials/styles.module.css
create mode 100644 src/pages/dev/solidity-lab.tsx
create mode 100644 src/plugins/interactive-tutorials/index.js
create mode 100644 src/resources/interactiveTutorialSources.ts
create mode 100644 src/theme/CodeBlock/index.tsx
diff --git a/docs/build-decentralized-apps/01-quickstart-solidity-remix.mdx b/docs/build-decentralized-apps/01-quickstart-solidity-remix.mdx
index 5d465639e7..82c4002662 100644
--- a/docs/build-decentralized-apps/01-quickstart-solidity-remix.mdx
+++ b/docs/build-decentralized-apps/01-quickstart-solidity-remix.mdx
@@ -1,839 +1,16 @@
---
title: 'Build a decentralized app with Solidity (Quickstart)'
-description: 'Learn how to build and deploy your first Solidity smart contract on Arbitrum using Remix IDE. This beginner-friendly quickstart guides you from a JavaScript vending machine to a decentralized app deployed on Arbitrum One, covering smart contract basics, wallet setup, and testnet deployment.'
+description: 'Learn how to build and deploy your first Solidity smart contract on Arbitrum using an on-page Solidity workbench.'
author: symbolpunk
-user_story: 'As a web2 developer new to blockchain, or a web3 developer new to Arbitrum, I want a step-by-step guide to writing, compiling, and deploying a Solidity smart contract on Arbitrum using Remix IDE so that I can understand the fundamentals of decentralized app development and start building on Arbitrum.'
+user_story: 'As a web2 developer new to blockchain, or a web3 developer new to Arbitrum, I want a guided IDE-style workflow for writing, compiling, deploying, and calling a Solidity smart contract so that I can understand the fundamentals of decentralized app development and start building on Arbitrum.'
content_type: quickstart
-slug: /build-decentralized-apps/quickstart-solidity-remix
+interactive_tutorial: true
+tutorial_kind: Guided IDE quickstart
+estimated_time: 35 min
+slug: /build-decentralized-apps/quickstart-solidity
displayed_sidebar: buildAppsSidebar
---
-:::info Want to use Rust instead?
+import { SolidityQuickstartWorkbench } from '@site/src/components/InteractiveTutorials';
-Head over to [the Stylus quickstart](/stylus/quickstart) if you'd like to use Rust instead of Solidity.
-
-:::
-
-This quickstart is for web developers who want to start building **decentralized applications** using Arbitrum. It makes no assumptions about your prior experience with Ethereum, Arbitrum, or Solidity. Familiarity with Javascript and yarn is expected. If you're new to Ethereum, consider studying the [Ethereum documentation](https://ethereum.org/en/developers/docs/) before proceeding.
-
-import { VendingMachine } from '@site/src/components/VendingMachine/VendingMachine';
-
-## What we'll learn
-
-In this tutorial we will learn:
-
-1. The basics of Ethereum vs. client/server architecture
-2. What is a Solidity smart contract
-3. How to compile and deploy a smart contract
-4. How to use an Ethereum wallet
-
-We're going to build a digital cupcake vending machine using Solidity smart contracts[^1]. This vending machine will follow two rules:
-
-1. The vending machine will distribute a cupcake to anyone who hasn't recently received one.
-2. The vending machine's rules can't be changed by anyone.
-
-Here's the vending machine implemented with Javascript.
-To use it, enter a name in the form below and press the **Cupcake please!** button, you should see your cupcake balance go up.
-
-
-
-We can assume that this vending machine operates as we expect, but it's largely up to the **centralized service provider** that hosts it.
-In the case of a compromised cloud host:
-
-1. Our centralized service provider can deny access to particular users.
-2. A malicious actor can change the rules of the vending machine at any time, for example, to give their friends extra cupcakes.
-
-Centralized third-party intermediaries represent a **single point of failure** that malicious actors can exploit. With a blockchain infrastructure such as Ethereum, we decentralize our vending machine's **business logic and data**, making this type of exploits nearly impossible.
-
-This is Arbitrum's core value proposition to you, dear developer. Arbitrum makes it easy for you to deploy your vending machines to Ethereum's permissionless, trustless, decentralized network of nodes[^2] **while keeping costs low for you and your users**.
-
-Let's implement the "Web3" version of the above vending machine using Arbitrum.
-
-## Prerequisites
-
-
- VS Code is the IDE we'll use to build our vending machine. See
- [code.visualstudio.com](https://code.visualstudio.com/) to install.
-
-
-
- We will use Metamask as the wallet to interact with
- our vending machine. See [metamask.io](https://metamask.io/) and click View MetaMask Web or [OKX
- Wallet](https://www.okx.com/web3) and click Connect Wallet to install.
-
-
-
- Yarn is the package manager we'll use to install dependencies. See
- [yarnpkg.com](https://yarnpkg.com/) to install.
-
-
-
- Foundry is the toolchain we'll use to compile and deploy our smart contract. See
- [getfoundry.sh](https://getfoundry.sh) to install.
-
-
-We'll address any remaining dependencies as we go.
-
-## Ethereum and Arbitrum in a nutshell
-
-- **Ethereum**
- - Ethereum is a decentralized network of [nodes](https://docs.prylabs.network/docs/concepts/nodes-networks) that use Ethereum's client software (like [Offchain's Prysm](https://www.offchainlabs.com/prysm/docs) to maintain a public blockchain data structure.
- - The data within Ethereum's blockchain data structure changes one transaction at a time.
- - Smart contracts are small programs that execute transactions
- according to predefined rules. Ethereum's nodes host and execute smart contracts.
- - You can use smart contracts to build decentralized apps that use Ethereum's network to process transactions and store data. Think of smart contracts as your app's backend
- - Apps let users carry their data and identity between applications without trusting centralized service providers.
- - People who run Ethereum validator nodes[^3] can earn `ETH` for processing and validating transactions on behalf of users and apps.
- - These transactions can be expensive when the network is under heavy load.
-- **Arbitrum**
- - Arbitrum is a suite of child chain scaling solutions for app developers.
- - Arbitrum One is a child chain that implements the
- Arbitrum Rollup protocol.
- - You can use Arbitrum One to build user-friendly apps with high throughput, low latency, and low transaction costs while inheriting Ethereum's high-security standards[^4].
-
-
-
-## Review the Javascript vending machine
-
-Here's the vending machine implemented as a Javascript class:
-
-
-
-```js
-class VendingMachine {
- // state variables = internal memory of the vending machine
- cupcakeBalances = {};
- cupcakeDistributionTimes = {};
-
- // Vend a cupcake to the caller
- giveCupcakeTo(userId) {
- if (this.cupcakeDistributionTimes[userId] === undefined) {
- this.cupcakeBalances[userId] = 0;
- this.cupcakeDistributionTimes[userId] = 0;
- }
-
- // Rule 1: The vending machine will distribute a cupcake to anyone who hasn't recently received one.
- const fiveSeconds = 5000;
- const userCanReceiveCupcake = this.cupcakeDistributionTimes[userId] + fiveSeconds <= Date.now();
- if (userCanReceiveCupcake) {
- this.cupcakeBalances[userId]++;
- this.cupcakeDistributionTimes[userId] = Date.now();
- console.log(`Enjoy your cupcake, ${userId}!`);
- return true;
- } else {
- console.error(
- 'HTTP 429: Too Many Cupcakes (you must wait at least 5 seconds between cupcakes)',
- );
- return false;
- }
- }
-
- getCupcakeBalanceFor(userId) {
- return this.cupcakeBalances[userId];
- }
-}
-```
-
-
-
-The `VendingMachine` class uses _state variables_ and _functions_ to implement _predefined rules_. This implementation is useful because it automates cupcake distribution, but there's a problem: it's hosted by a centralized server controlled by a third-party service provider.
-
-:::info Working web2 version
-
-To use the Vending Machine (web2), copy and paste the HTML code below into a text document, then open it in your web browser.
-
-
-
-```html
-
-
-
-
-
- Cupcake Vending Machine - Arbitrum Quickstart
-
-
-
-
-
-
Cupcake Vending Machine
-
From the Arbitrum Solidity + Remix Quickstart
-
-
-
-
-
- Web2
-
Free Cupcakes
-
Pure JavaScript vending machine. Business logic runs in your browser — no blockchain involved.
-
-
-
-
-
-
-
-
-
-
-
-
- Cupcake balance for —:
- 0
-
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
-
-
-:::
-
-Now, let's decentralize our vending machine's business logic and data by porting the above JavaScript implementation into a Solidity smart contract.
-
-## Review the Solidity vending machine
-
-Here is a Solidity implementation of the vending machine.
-Solidity is a language that compiles to [EVM bytecode](https://blog.chain.link/what-are-abi-and-bytecode-in-solidity/). This means that it is deployable to any Ethereum-compatible blockchain, including Ethereum mainnet, Arbitrum One, and Arbitrum Nova.
-
-
-
-```solidity
-// SPDX-License-Identifier: MIT
-// Specify the Solidity compiler version - this contract requires version 0.8.9 or higher
-pragma solidity ^0.8.9;
-
-// Define a smart contract named VendingMachine
-// Unlike regular classes, once deployed, this contract's code cannot be modified
-// This ensures that the vending machine's rules remain constant and trustworthy
-contract VendingMachine {
- // State variables are permanently stored in blockchain storage
- // These mappings associate Ethereum addresses with unsigned integers
- // The 'private' keyword means these variables can only be accessed from within this contract
- mapping(address => uint) private _cupcakeBalances; // Tracks how many cupcakes each address owns
- mapping(address => uint) private _cupcakeDistributionTimes; // Tracks when each address last received a cupcake
-
- // Function to give a cupcake to a specified address
- // 'public' means this function can be called by anyone
- // 'returns (bool)' specifies that the function returns a boolean value
- function giveCupcakeTo(address userAddress) public returns (bool) {
- // Initialize first-time users
- // In Solidity, uninitialized values default to 0, so this check isn't strictly necessary
- // but is included to mirror the JavaScript implementation
- if (_cupcakeDistributionTimes[userAddress] == 0) {
- _cupcakeBalances[userAddress] = 0;
- _cupcakeDistributionTimes[userAddress] = 0;
- }
-
- // Calculate when the user is eligible for their next cupcake
- // 'seconds' is a built-in time unit in Solidity
- // 'block.timestamp' gives us the current time in seconds since Unix epoch
- uint fiveSecondsFromLastDistribution = _cupcakeDistributionTimes[userAddress] + 5 seconds;
- bool userCanReceiveCupcake = fiveSecondsFromLastDistribution <= block.timestamp;
-
- if (userCanReceiveCupcake) {
- // If enough time has passed, give them a cupcake and update their last distribution time
- _cupcakeBalances[userAddress]++;
- _cupcakeDistributionTimes[userAddress] = block.timestamp;
- return true;
- } else {
- // If not enough time has passed, revert the transaction with an error message
- // 'revert' cancels the transaction and returns the error message to the user
- revert("HTTP 429: Too Many Cupcakes (you must wait at least 5 seconds between cupcakes)");
- }
- }
-
- // Function to check how many cupcakes an address owns
- // 'public' means anyone can call this function
- // 'view' means this function only reads data and doesn't modify state
- // This makes it free to call (no gas cost) when called externally
- function getCupcakeBalanceFor(address userAddress) public view returns (uint) {
- return _cupcakeBalances[userAddress];
- }
-}
-```
-
-
-
-## Compile your smart contract with Remix
-
-Smart contracts need to be compiled to bytecode to be stored and executed onchain by the EVM; we'll use Remix to do that.
-
-Remix is a browser-based IDE for EVM development. There are other IDEs to choose from (Foundry, Hardhat), but Remix doesn't require any local environment setup, so we'll use it for this tutorial.
-
-Let's first add our smart contract to Remix following these steps:
-
-### 1. Load Remix: https://remix.ethereum.org
-
-### 2. Create a blank workspace in Remix:
-
-{' '}
-
-
-
-
-
-### 3. Copy your vending machine contract
-
-### 4. Paste your contract in Remix
-
-
-
-
-
-"File explorer > New file"
-
-### 5. Compile your contract in Remix
-
-
-
-
-
-
-
-Ensure that Remix's compiler version matches the one in your contract. You can find your contract's compiler version at the top of your contract's file. It looks like this:
-
-```solidity
-pragma solidity ^0.8.2;
-```
-
-You can easily select the right compiler version in Remix's the "Solidity compiler" menu.
-
-
-
-## Deploy the smart contract to a local Ethereum chain
-
-Once a smart contract gets compiled, it is deployable to a blockchain. The safest way to do this is to deploy it to a locally hosted chain, where you can test and debug your contract before deploying it to a public chain.
-
-To deploy our `VendingMachine` smart contract locally, we will:
-
-1. Run Foundry's local Ethereum node in a terminal window
-2. Configure a wallet so we can interact with our smart contract after deployment (1)
-3. Deploy our smart contract to (1)'s node using Remix
-
-### Run a local chain
-
-Here, we'll use [Foundry's **anvil**](https://book.getfoundry.sh/anvil/) to run a local Ethereum network and node.
-
-```shell
-curl -L https://foundry.paradigm.xyz | bash && anvil
-```
-
-
-
-```shell
- (_) | |
- __ _ _ __ __ __ _ | |
- / _` | | '_ \ \ \ / / | | | |
- | (_| | | | | | \ V / | | | |
- \__,_| |_| |_| \_/ |_| |_|
-
- 0.2.0 (7f0f5b4 2024-08-08T00:19:07.020431000Z)
- https://github.com/foundry-rs/foundry
-
-# Available Accounts
-
-(0) 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 (10000.000000000000000000 ETH)
-(1) 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 (10000.000000000000000000 ETH)
-(2) 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC (10000.000000000000000000 ETH)
-(3) 0x90F79bf6EB2c4f870365E785982E1f101E93b906 (10000.000000000000000000 ETH)
-(4) 0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65 (10000.000000000000000000 ETH)
-(5) 0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc (10000.000000000000000000 ETH)
-(6) 0x976EA74026E726554dB657fA54763abd0C3a0aa9 (10000.000000000000000000 ETH)
-(7) 0x14dC79964da2C08b23698B3D3cc7Ca32193d9955 (10000.000000000000000000 ETH)
-(8) 0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f (10000.000000000000000000 ETH)
-(9) 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720 (10000.000000000000000000 ETH)
-
-# Private Keys
-
-(0) 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
-(1) 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
-(2) 0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a
-(3) 0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6
-(4) 0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a
-(5) 0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba
-(6) 0x92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e
-(7) 0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356
-(8) 0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97
-(9) 0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6
-
-# Wallet
-
-Mnemonic: test test test test test test test test test test test junk
-Derivation path: m/44'/60'/0'/0/
-
-# Chain ID
-
-31337.
-```
-
-
-
-### Configure Metamask
-
-Next, open Metamask and create or import a wallet by following the displayed instructions.
-
-By default, Metamask will connect to Ethereum's mainnet. To connect to our local "testnet," enable test networks for Metamask by clicking **Show/hide test networks**.
-
-Next, click Metamask's network selector dropdown and click the **Add Network** button. Click **Add a network manually** and then provide the following information:
-
-- Network Name: `localhost`
-- New RPC URL: `http://127.0.0.1:8545`
-- Chain ID: `31337`
-- Currency Symbol: `ETH`
-
-
-
-
-
-Your wallet won't have a balance on your local testnet's node, but you can import one of the test accounts into Metamask to access to 10,000 testnet `ETH`. Copy the private key of one of the test accounts (it works with or without the `0x` prefix, so e.g., `0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80` or `ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80`) and import it into Metamask. Metamask will ask you if you want to connect this new account to Remix, to which you should answer "yes":
-
-
-
-:::caution Never share your private keys
-
-Your Ethereum Mainnet wallet's private key is the password to all of your tokens. Never share it with anyone; avoid copying it to your clipboard.
-
-:::
-
-Note that in the context of this quickstart, "account" refers to an EOA (externally owned account), and its associated private key[^5].
-
-You should see a balance of 10,000 `ETH`. Keep your private key handy; we'll use it again shortly.
-
-As we interact with our cupcake vending machine, we'll use Metamask's network selector dropdown to choose which network our cupcake transactions get sent to. We'll leave the network set to `Localhost 8545` for now.
-
-### Connect Remix to Metamask
-
-In the last step, we'll connect Remix to Metamask so we can deploy our smart contract to the local chain using Remix.
-
-
-
-
-
-At this point, we're ready to deploy our smart contract to any chain we want.
-
-### Deploy the smart contract to your local chain
-
-- In MetaMask, ensure that the `Localhost` network is selected.
-- In Remix, deploy the `VendingMachine` contract to the `Localhost` network, then go to the "Deploy & Run Transactions" tab and click "Deploy."
-
-
-
-
-
-Then copy and paste your **contract address** below and click **Get cupcake!**. A prompt should ask you to sign a transaction that gives you a cupcake.
-
-
-
-## What's going on, here?
-
-Our first `VendingMachine` is labeled "Web2" because it demonstrates traditional client-server web application architecture: the back-end lives in a centralized network of servers.
-
-
-
-The "Web3" architecture is similar to the "Web2" architecture, with one key difference: with the "Web3" version, business logic and data are hosted by decentralized network of nodes\*\*
-
-Let's take a closer look at the differences between our `VendingMachine` implementations:
-
-
-
-| | `WEB2` (the first one) | `WEB3-LOCALHOST` (the latest one) | `WEB3-ARB-SEPOLIA` (the next one) | `WEB3-ARB-MAINNET` (the final one) |
-| --------------------- | --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
-| **Data** (cupcakes) | Stored only in your **browser**. (Usually, stored by centralized infrastructure.) | Stored on your **device** in an **emulated Ethereum network** (via smart contract). | Stored on Ethereum's **decentralized test network** (via smart contract). | Stored on Ethereum's **decentralized mainnet network** (via smart contract). |
-| **Logic** (vending) | Served from **Offchain's servers**. Executed by your **browser**. | Stored and executed by your **locally emulated Ethereum network** (via smart contract). | Stored and executed by Arbitrum's **decentralized test network** (via smart contract). | Stored and executed by Arbitrum's **decentralized mainnet network** (via smart contract). |
-| **Presentation** (UI) | Served from **Offchain's servers**. Rendered and executed by your **browser**. | ← same | ← same | ← same |
-| **Money** | Devs and users pay centralized service providers for server access using fiat currency. | ← same, but only for the presentation-layer concerns (code that supports frontend UI/UX). | ← same, but devs and users pay **testnet ETH** to testnet validators. | ← same, but instead of testnet `ETH`, they use **mainnet `ETH`**. |
-
-So far, we've deployed our "Web3" app to an emulated blockchain (Anvil), which is a normal step in EVM development.
-
-Next, we'll deploy our smart contract to a network of real nodes: Arbitrum's Sepolia testnet.
-
-## Deploy the smart contract to the Arbitrum Sepolia testnet
-
-We were able to deploy to a testnet for free because we were using Remix's built-in network, but now we'll deploy our contract to Arbitrum's Sepolia testnet.
-Sepolia is powered by a network of nodes ran across the world by various participants, we'll need to compensate them with a small transaction fee in order to deploy our smart contract.
-
-To be able to pay the transaction fee, we will:
-
-- Use our MetaMask crypto wallet
-- Obtain some Arbitrum Sepolia testnet's token called `ETH`.
-
-Click Metamask's **Network selector** dropdown, and then click the **Add Network** button. Click **Add a network manually** and then provide the following information:
-
-- Network Name: `Arbitrum Sepolia`
-- New RPC URL: `https://sepolia-rollup.arbitrum.io/rpc`
-- Chain ID: `421614`
-- Currency Symbol: `ETH`
-
-As we interact with the cupcake vending machine, we'll use Metamask's network selector dropdown to determine which network our cupcake transactions are sent to.
-
-Next, let's deposit some `ETH` into the wallet corresponding to the private key we added to Remix. At the time of this quickstart's writing, the easiest way to acquire `ETH` is to bridge Sepolia `ETH` from Ethereum's parent chain Sepolia network to Arbitrum's child chain Sepolia network:
-
-1. Use a parent chain Sepolia `ETH` faucet like [sepoliafaucet.com](https://sepoliafaucet.com/) to acquire some testnet `ETH` on parent chain Sepolia.
-2. Bridge your parent chain Sepolia `ETH` into Arbitrum child chain using [the Arbitrum bridge](https://bridge.arbitrum.io/).
-
-Once you've acquired some `ETH`, you'll be able to deploy your smart contract to Arbitrum's Sepolia testnet.
-You can proceed exactly as with the local testnet.
-
-1. Connect Remix to the Arbitrum Sepolia testnet
-2. Compile your vending machine contract
-3. Deploy your vending machine contract to the Arbitrum Sepolia testnet
-
-In this last step, your compiled smart contract will be deployed through the RPC endpoint corresponding to "Arbitrum Sepolia" in MetaMask (MetaMask uses [INFURA](https://www.infura.io)'s nodes as endpoints).
-
-Congratulations! You've just deployed **business logic and data** to Arbitrum Sepolia. This logic and data will be hashed and submitted within a transaction to Ethereum's parent chian Sepolia network, and then it will be mirrored across all nodes in the Sepolia network[^6].
-
-To view your smart contract in a blockchain explorer, visit `https://sepolia.arbiscan.io/address/0x...B3`, but replace the `0x...B3` part of the URL with the full address of your deployed smart contract.
-
-Select **Arbitrum Sepolia** from Metamask's dropdown, paste your contract address into the `VendingMachine` below, and click **Get cupcake!**. You should be prompted to sign a transaction that gives you a cupcake.
-
-
-
-The final step is deploying our Cupcake machine to a production network, such as Ethereum, Arbitrum One, or Arbitrum Nitro.
-The good news is: deploying a smart contract in production is exactly the same as for Sepolia Testnet.
-The harder news: it will cost real money, this time. If you deploy on Ethereum, the fees can be significant and the transaction confirmation time 12 seconds on average.
-Arbitrum, a child chain, reduces these costs about 10X and a confirmation time in the same order while maintaining a similar level of security and decentralization.
-
-## Summary
-
-In this quickstart, we:
-
-- Identified **two business rules**: 1) fair and permissionless cupcake distribution 2) immutable business logic and data.
-- Identified a **challenge**: These rules are difficult to follow in a centralized application.
-- Identified a **solution**: Using Arbitrum, we can decentralize business logic and data.
-- Converted a vending machine's Javascript business logic into a **Solidity smart contract**.
-- **Deployed our smart contract** to a local development network, and then Arbitrum's Sepolia testnet.
-
-If you have any questions or feedback, reach out to us on [Discord](https://discord.gg/ZpZuw7p) and/or click the **Request an update** button at the top of this page—we're listening!
-
-## Learning resources
-
-| Resource | Description |
-| ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
-| [Official Solidity documentation](https://soliditylang.org) | Official documentation for Solidity programming language |
-| [Solidity by example](https://solidity-by-example.org) | Learn Solidity patterns via a series of classic examples |
-| [Upgrading Ethereum (e-book)](https://eth2book.info/altair) | Guide on upgrading Ethereum |
-| [Ethernaut](https://ethernaut.openzeppelin.com) | Interactive smart contract hacking game |
-| [RareSkills](https://www.rareskills.io/rust-bootcamp) | Rust programming course for blockchain development |
-| [CryptoZombies](https://cryptozombies.io/en/course/) | Free online smart contract courses and tutorials |
-| [LearnWeb3](https://learnweb3.io) | Web3 education platform with interactive lessons and projects |
-| [HackQuest](https://www.hackquest.io/en) | Web3 hackathon and project-based learning platform |
-| [Rise In](https://www.risein.com/bootcamps/solidity-bootcamp) | Solidity bootcamp for beginners |
-| [Encode Club](https://www.encode.club) | Community-driven coding club with a focus on Web3 development |
-| [Metana](https://metana.io) | Metana is not mentioned in the resources, please provide more information about this resource. |
-| [Alchemy University](https://www.alchemy.com/university) | Online education platform for blockchain and Web3 development courses |
-
-[^1]: The vending machine example was inspired by [Ethereum.org's "Introduction to Smart Contracts"](https://ethereum.org/en/developers/docs/smart-contracts/), which was inspired by [Nick Szabo's "From vending machines to smart contracts"](http://unenumerated.blogspot.com/2006/12/from-vending-machines-to-smart.html).
-[^2]: Although application front-ends are usually hosted by centralized services, smart contracts allow the underlying logic and data to be partially or fully decentralized. These smart contracts are hosted and executed by Ethereum's public, decentralized network of nodes. Arbitrum has its own network of nodes that use advanced cryptography techniques to "batch process" Ethereum transactions and then submit them to the Ethereum parent chain, which significantly reduces the cost of using Ethereum. All without requiring developers to compromise on security or decentralization.
-[^3]: There are multiple types of Ethereum nodes. The ones that earn `ETH` for processing and validating transactions are called _validators_. See [Nodes and Networks](https://docs.prylabs.network/docs/concepts/nodes-networks) for a beginner-friendly introduction to Ethereum's node types.
-[^4]: When our `VendingMachine` contract is deployed to Ethereum, it'll be hosted by Ethereum's decentralized network of nodes. Generally speaking, we won't be able to modify the contract's code after it's deployed.
-[^5]: To learn more about how Ethereum wallets work, see [Ethereum.org's introduction to Ethereum wallets](https://ethereum.org/en/wallets/).
-[^6]: Visit the [Gentle Introduction to Arbitrum](../intro/intro.mdx) for a beginner-friendly introduction to Arbitrum's Rollup protocol.
+
diff --git a/docs/build-decentralized-apps/reference/06-monitoring-tools-block-explorers.mdx b/docs/build-decentralized-apps/reference/06-monitoring-tools-block-explorers.mdx
index 55c6d39255..4b52b4cbfb 100644
--- a/docs/build-decentralized-apps/reference/06-monitoring-tools-block-explorers.mdx
+++ b/docs/build-decentralized-apps/reference/06-monitoring-tools-block-explorers.mdx
@@ -33,7 +33,7 @@ Build on Arbitrum or dive deeper into the network.
- [Contract addresses](/build-decentralized-apps/reference/contract-addresses) — key Arbitrum contract addresses
- [Chain info and RPC endpoints](/for-devs/dev-tools-and-resources/chain-info) — chain IDs, RPC URLs, and network parameters
- [How to estimate gas](/build-decentralized-apps/how-to-estimate-gas) — understand gas costs on Arbitrum
-- [Quickstart: Build a dApp](/build-decentralized-apps/quickstart-solidity-remix) — deploy your first contract on Arbitrum
+- [Quickstart: Build a dApp](/build-decentralized-apps/quickstart-solidity) — deploy your first contract on Arbitrum
- [Run a full node](/run-arbitrum-node/run-full-node) — run your own Arbitrum node
import KnowMoreToolsBox from '../../for-devs/partials/_know-more-tools-box-partial.mdx';
diff --git a/docs/build-decentralized-apps/token-bridging/configure-token-bridging/setup-custom-gateway.mdx b/docs/build-decentralized-apps/token-bridging/configure-token-bridging/setup-custom-gateway.mdx
index 603435851b..bcb421ddaf 100644
--- a/docs/build-decentralized-apps/token-bridging/configure-token-bridging/setup-custom-gateway.mdx
+++ b/docs/build-decentralized-apps/token-bridging/configure-token-bridging/setup-custom-gateway.mdx
@@ -15,7 +15,7 @@ Before implementing and deploying a custom gateway, it is strongly encouraged to
In this how-to, you'll learn how to bridge your own token between Ethereum (the parent chain) and Arbitrum (the child chain), using a custom gateway. For alternative ways of bridging tokens, check out the [token bridging overview](/build-decentralized-apps/token-bridging/get-started.mdx).
-Familiarity with [Arbitrum's token bridge system](/how-arbitrum-works/deep-dives/token-bridging.mdx), smart contracts, and decentralized application development is expected. If you're new to developing on Arbitrum, consider reviewing our [Quickstart: Build a dApp with Arbitrum (Solidity, Remix)](/build-decentralized-apps/01-quickstart-solidity-remix.mdx) before proceeding. We'll use [Arbitrum's SDK](https://github.com/OffchainLabs/arbitrum-sdk) throughout this how-to, although no prior knowledge is required.
+Familiarity with [Arbitrum's token bridge system](/how-arbitrum-works/deep-dives/token-bridging.mdx), smart contracts, and decentralized application development is expected. If you're new to developing on Arbitrum, consider reviewing our [Quickstart: Build a dApp with Arbitrum (Solidity)](/build-decentralized-apps/quickstart-solidity) before proceeding. We'll use [Arbitrum's SDK](https://github.com/OffchainLabs/arbitrum-sdk) throughout this how-to, although no prior knowledge is required.
We will go through all the steps involved in the process. However, if you want to jump straight to the code, we have created a [custom gateway bridging tutorial script](https://github.com/OffchainLabs/arbitrum-tutorials/tree/master/packages/custom-gateway-bridging) that encapsulates the entire process.
diff --git a/docs/build-decentralized-apps/token-bridging/configure-token-bridging/setup-generic-custom-gateway.mdx b/docs/build-decentralized-apps/token-bridging/configure-token-bridging/setup-generic-custom-gateway.mdx
index 48b83be2ff..bea356f9fb 100644
--- a/docs/build-decentralized-apps/token-bridging/configure-token-bridging/setup-generic-custom-gateway.mdx
+++ b/docs/build-decentralized-apps/token-bridging/configure-token-bridging/setup-generic-custom-gateway.mdx
@@ -8,7 +8,7 @@ displayed_sidebar: buildAppsSidebar
In this how-to, you'll learn how to bridge your own token between Ethereum (parent chain) and Arbitrum (child chain), using [Arbitrum's generic-custom gateway](/how-arbitrum-works/deep-dives/token-bridging.mdx#the-arbitrum-generic-custom-gateway). For alternative ways of bridging tokens, check out the [token bridging overview](/how-arbitrum-works/deep-dives/token-bridging.mdx).
-Familiarity with [Arbitrum's token bridge system](/how-arbitrum-works/deep-dives/token-bridging.mdx), smart contracts, and blockchain development is expected. If you're new to blockchain development, consider reviewing our [Quickstart: Build a dApp with Arbitrum (Solidity, Hardhat)](/build-decentralized-apps/01-quickstart-solidity-remix.mdx) before proceeding. We'll use [Arbitrum's SDK](https://github.com/OffchainLabs/arbitrum-sdk) throughout this how-to, although no prior knowledge is required.
+Familiarity with [Arbitrum's token bridge system](/how-arbitrum-works/deep-dives/token-bridging.mdx), smart contracts, and blockchain development is expected. If you're new to blockchain development, consider reviewing our [Quickstart: Build a dApp with Arbitrum (Solidity, Hardhat)](/build-decentralized-apps/quickstart-solidity) before proceeding. We'll use [Arbitrum's SDK](https://github.com/OffchainLabs/arbitrum-sdk) throughout this how-to, although no prior knowledge is required.
We'll go through all the steps involved in the process. However, if you want to jump straight to the code, we've created a [custom token bridging tutorial script](https://github.com/OffchainLabs/arbitrum-tutorials/tree/master/packages/custom-token-bridging) that encapsulates the entire process.
diff --git a/docs/for-devs/oracles/api3/api3.mdx b/docs/for-devs/oracles/api3/api3.mdx
index 2e37418fc1..a3a48a39a0 100644
--- a/docs/for-devs/oracles/api3/api3.mdx
+++ b/docs/for-devs/oracles/api3/api3.mdx
@@ -59,7 +59,7 @@ contract ARBPriceConsumer {
}
```
-You can adapt this contract to your needs. Just remember to use the address of the asset you want to request the price for in the appropriate network and to **deploy your contract to the same network**. Remember we have a [Quickstart](/build-decentralized-apps/01-quickstart-solidity-remix.mdx) available that goes through the process of compiling and deploying a contract.
+You can adapt this contract to your needs. Just remember to use the address of the asset you want to request the price for in the appropriate network and to **deploy your contract to the same network**. Remember we have a [Quickstart](/build-decentralized-apps/quickstart-solidity) available that goes through the process of compiling and deploying a contract.
## More examples
diff --git a/docs/for-devs/oracles/chainlink/chainlink.mdx b/docs/for-devs/oracles/chainlink/chainlink.mdx
index b421969c43..d0be253723 100644
--- a/docs/for-devs/oracles/chainlink/chainlink.mdx
+++ b/docs/for-devs/oracles/chainlink/chainlink.mdx
@@ -59,7 +59,7 @@ contract ARBPriceConsumer {
}
```
-You can adapt this contract to your needs. Just remember to use the address of the asset you want to request the price for in the appropriate network, and to **deploy your contract to the same network**. Remember we have a [Quickstart](/build-decentralized-apps/01-quickstart-solidity-remix.mdx) available that goes through the process of compiling and deploying a contract.
+You can adapt this contract to your needs. Just remember to use the address of the asset you want to request the price for in the appropriate network, and to **deploy your contract to the same network**. Remember we have a [Quickstart](/build-decentralized-apps/quickstart-solidity) available that goes through the process of compiling and deploying a contract.
## More examples
diff --git a/docs/for-devs/oracles/trellor/trellor.mdx b/docs/for-devs/oracles/trellor/trellor.mdx
index 9e8eb7608b..a5086523e6 100644
--- a/docs/for-devs/oracles/trellor/trellor.mdx
+++ b/docs/for-devs/oracles/trellor/trellor.mdx
@@ -47,7 +47,7 @@ contract ARBPriceConsumer is UsingTellor {
}
```
-You can adapt this contract to your needs. Just remember to use the ticker of the assets you want to request the price for and to **deploy your contract to the appropriate network, with the address of the Oracle contract in that network**. Remember, we have a [Quickstart](/build-decentralized-apps/01-quickstart-solidity-remix.mdx) available that goes through the process of compiling and deploying a contract.
+You can adapt this contract to your needs. Just remember to use the ticker of the assets you want to request the price for and to **deploy your contract to the appropriate network, with the address of the Oracle contract in that network**. Remember, we have a [Quickstart](/build-decentralized-apps/quickstart-solidity) available that goes through the process of compiling and deploying a contract.
## See also
diff --git a/docs/get-started/overview.mdx b/docs/get-started/overview.mdx
index 805d92302e..f77deed3f0 100644
--- a/docs/get-started/overview.mdx
+++ b/docs/get-started/overview.mdx
@@ -9,7 +9,7 @@ slug: /
Arbitrum is a suite of Ethereum scaling solutions that make it
easy to build and use decentralized applications. If you're ready to start building, try the [Solidity
-quickstart](/build-decentralized-apps/quickstart-solidity-remix) or [Stylus quickstart](/stylus/quickstart).
+quickstart](/build-decentralized-apps/quickstart-solidity) or [Stylus quickstart](/stylus/quickstart).
## Understand Arbitrum
@@ -62,8 +62,8 @@ Deploy smart contracts to Arbitrum One, Arbitrum Nova, or any Arbitrum chain.
>
= startLine && lineNumber <= endLine;
+}
+
+export function CodeWalkthrough({
+ children,
+ className,
+ language: languageProp,
+ metastring,
+ title,
+}: Props) {
+ const parsed = useMemo(() => parseCodeWalkthrough(children), [children]);
+ const language = normalizeLanguage(languageProp, className);
+ const highlightLanguage = resolveHighlightLanguage(language);
+ const prismTheme = usePrismTheme();
+ const [activeIndex, setActiveIndex] = useState(0);
+ const activeStep = parsed.steps[activeIndex];
+ const resolvedTitle = parseCodeTitle(metastring, title);
+
+ const copyCode = async () => {
+ if (typeof navigator === 'undefined' || !navigator.clipboard) return;
+ await navigator.clipboard.writeText(parsed.code);
+ };
+
+ if (parsed.steps.length === 0) {
+ return (
+
+ {processVisual === 'compile'
+ ? 'Solidity source is being compressed into ABI and EVM bytecode.'
+ : 'Compiled bytecode is being placed into a new block on the selected network.'}
+
+
+ );
+}
+
+async function ensureArbitrumSepolia(ethereum: ethers.providers.ExternalProvider) {
+ if (typeof ethereum.request !== 'function') return;
+ try {
+ await ethereum.request({
+ method: 'wallet_switchEthereumChain',
+ params: [{ chainId: ARBITRUM_SEPOLIA.chainIdHex }],
+ });
+ } catch (error) {
+ const switchError = error as { code?: number };
+ if (switchError.code !== 4902) throw error;
+ await ethereum.request({
+ method: 'wallet_addEthereumChain',
+ params: [
+ {
+ chainId: ARBITRUM_SEPOLIA.chainIdHex,
+ chainName: ARBITRUM_SEPOLIA.chainName,
+ rpcUrls: ARBITRUM_SEPOLIA.rpcUrls,
+ blockExplorerUrls: ARBITRUM_SEPOLIA.blockExplorerUrls,
+ nativeCurrency: ARBITRUM_SEPOLIA.nativeCurrency,
+ },
+ ],
+ });
+ }
+}
diff --git a/src/components/InteractiveTutorials/SolidityQuickstartWorkbench.tsx b/src/components/InteractiveTutorials/SolidityQuickstartWorkbench.tsx
new file mode 100644
index 0000000000..acee9847fd
--- /dev/null
+++ b/src/components/InteractiveTutorials/SolidityQuickstartWorkbench.tsx
@@ -0,0 +1,126 @@
+import React from 'react';
+import { vendingMachineSoliditySource } from '@site/src/resources/interactiveTutorialSources';
+import { SolidityLab, SolidityLabTask } from './SolidityLab';
+import styles from './styles.module.css';
+
+const quickstartTasks: SolidityLabTask[] = [
+ {
+ label: 'A Solidity contract becomes on-chain activity.',
+ spotlight: 'lesson',
+ note: 'A Solidity file becomes a blockchain program through a small set of concrete steps.',
+ bullets: [
+ 'Contract source contains the state and functions.',
+ 'Compilation produces EVM bytecode and an ABI.',
+ 'Deployment creates a contract address on a selected network.',
+ 'Contract calls and explorer records show how transactions change state.',
+ ],
+ },
+ {
+ label: 'Contract state lives in storage.',
+ lines: [5, 6],
+ spotlight: 'lines',
+ note: 'A blockchain app stores important state inside the smart contract, not in a private server database.',
+ bullets: [
+ 'The two mappings are persistent contract storage.',
+ 'Successful transactions can update these values.',
+ 'Anyone can later verify the resulting state from the chain.',
+ ],
+ },
+ {
+ label: 'Transactions change contract storage.',
+ lines: [8, 25],
+ spotlight: 'lines',
+ note: 'Functions that change contract storage must be sent as transactions.',
+ bullets: [
+ 'It checks whether the caller has waited long enough.',
+ 'It increments the cupcake balance and records a new timestamp.',
+ 'It can revert, which means the attempted state change is rejected.',
+ ],
+ },
+ {
+ label: 'Compile source into bytecode.',
+ lines: [1, 30],
+ action: 'compile',
+ spotlight: 'lesson',
+ placement: 'left',
+ note: 'The chain does not run Solidity source directly. Compilation turns this file into deployable machine-readable output.',
+ bullets: [
+ 'EVM bytecode is the payload that can be deployed to a network.',
+ 'The ABI tells tools which functions the contract exposes and how to call them.',
+ 'The console records the compiler output so the technical result stays inspectable.',
+ ],
+ },
+ {
+ label: 'Create a contract on the network.',
+ lines: [4, 30],
+ action: 'deploy',
+ spotlight: 'lesson',
+ placement: 'left',
+ note: 'Deployment is the first transaction for this contract. It creates the on-chain address that later calls will target.',
+ bullets: [
+ 'The selected network receives the compiled bytecode.',
+ 'A contract address is created when the deployment transaction succeeds.',
+ 'The block explorer records the deployment as contract creation history.',
+ ],
+ },
+ {
+ label: 'Send a state-changing transaction.',
+ lines: [8, 25],
+ action: 'write',
+ spotlight: 'write',
+ placement: 'left',
+ note: 'Calling the write function creates another transaction because this call changes contract storage.',
+ bullets: [
+ 'The sender is the connected wallet.',
+ 'The destination is the deployed contract address.',
+ 'The method name and status appear in the explorer transaction row.',
+ ],
+ },
+ {
+ label: 'Read state without a transaction.',
+ lines: [27, 29],
+ action: 'read',
+ spotlight: 'read',
+ placement: 'left',
+ note: 'Read calls ask a node to evaluate a view function against the latest state.',
+ bullets: [
+ 'They do not modify contract storage.',
+ 'They do not need mining and do not create a transaction row.',
+ 'The returned balance changed only because the previous write transaction succeeded.',
+ ],
+ },
+ {
+ label: 'Inspect what happened on-chain.',
+ spotlight: 'runtime',
+ placement: 'left',
+ note: 'A block explorer organizes blockchain activity into current state and historical events.',
+ bullets: [
+ 'Connected Wallet shows the active wallet, deployed contract, and readable balance.',
+ 'Transactions shows the deploy and write history.',
+ 'Expanding a transaction reveals the hash, sender, destination, action, and status.',
+ ],
+ },
+];
+
+function QuickstartSidebar() {
+ return (
+
+ Isolated harness for the Solidity IDE. Side-by-side renders the lab in light + dark frames
+ simultaneously. Use this page during iteration; it is not linked from any sidebar.
+