diff --git a/.ai/categories/smart-contracts.md b/.ai/categories/smart-contracts.md index c9cab7b91..a38557fbe 100644 --- a/.ai/categories/smart-contracts.md +++ b/.ai/categories/smart-contracts.md @@ -2319,215 +2319,2299 @@ Several SCALE codec implementations are available in various languages. Here's a --- -Page Title: Deploy an ERC-20 to Polkadot Hub +Page Title: Deploy a Basic Contract to EVM -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-erc20.md -- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-erc20/ -- Summary: Deploy an ERC-20 token on Polkadot Hub using PolkaVM. This guide covers contract creation, compilation, deployment, and interaction via Polkadot Remix IDE. +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-evm.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-evm/ +- Summary: Learn how to deploy a basic smart contract to Polkadot Hub using standard EVM tools and toolchains. -# Deploy an ERC-20 to Polkadot Hub +# Deploy a Basic Contract (EVM) -!!! smartcontract "PolkaVM Preview Release" - PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. ## Introduction -[ERC-20](https://eips.ethereum.org/EIPS/eip-20){target=\_blank} tokens are fungible tokens commonly used for creating cryptocurrencies, governance tokens, and staking mechanisms. Polkadot Hub enables easy token deployment with Ethereum-compatible smart contracts via PolkaVM. +Deploying smart contracts to the [Polkadot Hub](/smart-contracts/overview/#smart-contract-development){target=\_blank} can be accomplished using standard EVM development tools and workflows. This guide demonstrates how to deploy a basic smart contract using four popular EVM approaches: JavaScript with [Ethers.js](https://docs.ethers.org/v6/){target=\_blank}, [Remix IDE](https://remix.live/){target=\_blank}, [Hardhat](https://hardhat.org/){target=\_blank}, and [Foundry](https://getfoundry.sh/){target=\_blank}. -This tutorial covers deploying an ERC-20 contract on the Polkadot Hub TestNet using [Polkadot Remix IDE](https://remix.polkadot.io){target=\_blank}, a web-based development tool. [OpenZeppelin's ERC-20 contracts](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/v5.4.0/contracts/token/ERC20){target=\_blank} are used for security and compliance. +All these tools use standard Solidity compilation to generate EVM bytecode, making them compatible with Polkadot Hub's EVM environment. Whether you prefer working with lightweight JavaScript libraries, visual browser-based IDEs, comprehensive development frameworks, or fast command-line toolkits, this guide covers the deployment process for each approach. -## Prerequisites +**Prerequisites:** -Before starting, make sure you have: +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later (for JavaScript/Hardhat approaches). +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. -- [MetaMask](https://metamask.io/){target=\_blank} installed and connected to Polkadot Hub. For detailed instructions, see the [Connect Your Wallet](/smart-contracts/integrations/wallets){target=\_blank} section. -- A funded account with some PAS tokens (you can get them from the [Polkadot Faucet](https://faucet.polkadot.io/?parachain=1111){target=\_blank}). To learn how to get test tokens, check out the [Test Tokens](/smart-contracts/connect/#test-tokens){target=\_blank} section. -- Basic understanding of Solidity and fungible tokens. +## Deployment options -## Create the ERC-20 Contract +=== "JavaScript with Ethers.js" + Ethers.js provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications. -To create the ERC-20 contract, you can follow the steps below: + ### Setup -1. Navigate to the [Polkadot Remix IDE](https://remix.polkadot.io){target=\_blank}. -2. Click in the **Create new file** button under the **contracts** folder, and name your contract as `MyToken.sol`. + First, initialize your project and install dependencies: - ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-1.webp) + ```bash + mkdir ethers-deployment + cd ethers-deployment + npm init -y + npm install ethers@6.15.0 solc@0.8.30 + ``` -3. Now, paste the following ERC-20 contract code into the editor: + ### Create and Compile Your Contract - ```solidity title="MyToken.sol" + Create a simple storage contract in `contracts/Storage.sol`: + + ```solidity title="contracts/Storage.sol" // SPDX-License-Identifier: MIT - // Compatible with OpenZeppelin Contracts ^5.0.0 - pragma solidity ^0.8.22; + pragma solidity ^0.8.9; - import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; - import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; + contract Storage { + uint256 private storedNumber; - contract MyToken is ERC20, Ownable { - constructor(address initialOwner) - ERC20("MyToken", "MTK") - Ownable(initialOwner) - {} + function store(uint256 num) public { + storedNumber = num; + } - function mint(address to, uint256 amount) public onlyOwner { - _mint(to, amount); + function retrieve() public view returns (uint256) { + return storedNumber; } } ``` - The key components of the code above are: + Create a compilation script `compile.js`: - - Contract imports: + ```javascript title="compile.js" + const solc = require('solc'); + const { readFileSync, writeFileSync } = require('fs'); + const { basename, join } = require('path'); - - **[`ERC20.sol`](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/v5.4.0/contracts/token/ERC20/ERC20.sol){target=\_blank}**: The base contract for fungible tokens, implementing core functionality like transfers, approvals, and balance tracking. - - **[`Ownable.sol`](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/v5.4.0/contracts/access/Ownable.sol){target=\_blank}**: Provides basic authorization control, ensuring only the contract owner can mint new tokens. - - - Constructor parameters: + const compileContract = async (solidityFilePath, outputDir) => { + try { + // Read the Solidity file + const source = readFileSync(solidityFilePath, 'utf8'); + + // Construct the input object for the compiler + const input = { + language: 'Solidity', + sources: { + [basename(solidityFilePath)]: { content: source }, + }, + settings: { + outputSelection: { + '*': { + '*': ['*'], + }, + }, + }, + }; - - **`initialOwner`**: Sets the address that will have administrative rights over the contract. - - **`"MyToken"`**: The full name of your token. - - **`"MTK"`**: The symbol representing your token in wallets and exchanges. + console.log(`Compiling contract: ${basename(solidityFilePath)}...`); - - Key functions: + // Compile the contract + const output = JSON.parse(solc.compile(JSON.stringify(input))); - - **`mint(address to, uint256 amount)`**: Allows the contract owner to create new tokens for any address. The amount should include 18 decimals (e.g., 1 token = 1000000000000000000). - - Inherited [Standard ERC-20](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/){target=\_blank} functions: - - **`transfer(address recipient, uint256 amount)`**: Sends a specified amount of tokens to another address. - - **`approve(address spender, uint256 amount)`**: Grants permission for another address to spend a specific number of tokens on behalf of the token owner. - - **`transferFrom(address sender, address recipient, uint256 amount)`**: Transfers tokens from one address to another, if previously approved. - - **`balanceOf(address account)`**: Returns the token balance of a specific address. - - **`allowance(address owner, address spender)`**: Checks how many tokens an address is allowed to spend on behalf of another address. + if (output.errors) { + output.errors.forEach(error => { + console.error('Compilation error:', error.message); + }); + return; + } - !!! tip - Use the [OpenZeppelin Contracts Wizard](https://wizard.openzeppelin.com/){target=\_blank} to quickly generate customized smart contracts. Simply configure your contract, copy the generated code, and paste it into Polkadot Remix IDE for deployment. Below is an example of an ERC-20 token contract created with it: + for (const contracts of Object.values(output.contracts)) { + for (const [name, contract] of Object.entries(contracts)) { + console.log(`Compiled contract: ${name}`); + + // Write the ABI + const abiPath = join(outputDir, `${name}.json`); + writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2)); + console.log(`ABI saved to ${abiPath}`); + + // Write the bytecode + const bytecodePath = join(outputDir, `${name}.bin`); + writeFileSync(bytecodePath, + Buffer.from( + contract.evm.bytecode.object, + 'hex' + )); + console.log(`Bytecode saved to ${bytecodePath}`); + } + } + } catch (error) { + console.error('Error compiling contracts:', error); + } + }; - ![Screenshot of the OpenZeppelin Contracts Wizard showing an ERC-20 contract configuration.](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-2.webp) - + const solidityFilePath = join(__dirname, 'contracts/Storage.sol'); + const outputDir = join(__dirname, 'contracts'); -## Compile the Contract + compileContract(solidityFilePath, outputDir); + ``` -The compilation transforms your Solidity source code into bytecode that can be deployed on the blockchain. During this process, the compiler checks your contract for syntax errors, ensures type safety, and generates the machine-readable instructions needed for blockchain execution. To compile your contract, follow the instructions below: + Run the compilation: -1. Select the **Solidity Compiler** plugin from the left panel. + ```bash + node compile.js + ``` - ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-3.webp) + ### Deploy the Contract -2. Click the **Compile MyToken.sol** button. + Create a deployment script `deploy.js`: - ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-4.webp) + ```javascript title="deploy.js" + const { writeFileSync, existsSync, readFileSync } = require('fs'); + const { join } = require('path'); + const { ethers, JsonRpcProvider } = require('ethers'); -3. If the compilation succeeded, you'll see a green checkmark indicating success in the **Solidity Compiler** icon. + const codegenDir = join(__dirname); - ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-5.webp) + // Creates a provider with specified RPC URL and chain details + const createProvider = (rpcUrl, chainId, chainName) => { + const provider = new JsonRpcProvider(rpcUrl, { + chainId: chainId, + name: chainName, + }); + return provider; + }; -## Deploy the Contract + // Reads and parses the ABI file for a given contract + const getAbi = (contractName) => { + try { + return JSON.parse( + readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'), + ); + } catch (error) { + console.error( + `Could not find ABI for contract ${contractName}:`, + error.message, + ); + throw error; + } + }; -Deployment is the process of publishing your compiled smart contract to the blockchain, making it permanently available for interaction. During deployment, you'll create a new instance of your contract on the blockchain, which involves: + // Reads the compiled bytecode for a given contract + const getByteCode = (contractName) => { + try { + const bytecodePath = join( + codegenDir, + 'contracts', + `${contractName}.bin`, + ); + return `0x${readFileSync(bytecodePath).toString('hex')}`; + } catch (error) { + console.error( + `Could not find bytecode for contract ${contractName}:`, + error.message, + ); + throw error; + } + }; -1. Select the **Deploy & Run Transactions** plugin from the left panel. + const deployContract = async (contractName, mnemonic, providerConfig) => { + console.log(`Deploying ${contractName}...`); - ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-6.webp) + try { + // Step 1: Set up provider and wallet + const provider = createProvider( + providerConfig.rpc, + providerConfig.chainId, + providerConfig.name, + ); + const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic); + const wallet = walletMnemonic.connect(provider); -2. Configure the deployment settings. - 1. From the **ENVIRONMENT** dropdown, select **Injected Provider - Talisman** (check the [Deploying Contracts](/smart-contracts/dev-environments/remix/deploy-a-contract/){target=\_blank} section of the Remix IDE guide for more details). - 2. From the **ACCOUNT** dropdown, select the account you want to use for the deploy. + // Step 2: Create and deploy the contract + const factory = new ethers.ContractFactory( + getAbi(contractName), + getByteCode(contractName), + wallet, + ); + const contract = await factory.deploy(); + await contract.waitForDeployment(); - ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-7.webp) + // Step 3: Save deployment information + const address = await contract.getAddress(); + console.log(`Contract ${contractName} deployed at: ${address}`); -3. Configure the contract parameters: + const addressesFile = join(codegenDir, 'contract-address.json'); + const addresses = existsSync(addressesFile) + ? JSON.parse(readFileSync(addressesFile, 'utf8')) + : {}; + addresses[contractName] = address; + writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8'); + } catch (error) { + console.error(`Failed to deploy contract ${contractName}:`, error); + } + }; - 1. Enter the address that will own the deployed token contract. - 2. Click the **Deploy** button to initiate the deployment. + const providerConfig = { + rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + name: 'polkadot-hub-testnet', + }; - ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-8.webp) + const mnemonic = 'INSERT_MNEMONIC'; -4. **Talisman will pop up**: Review the transaction details. Click **Approve** to deploy your contract. + deployContract('Storage', mnemonic, providerConfig); + ``` - ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-9.webp){: .browser-extension} + Replace the `INSERT_MNEMONIC` placeholder with your actual mnemonic. - If the deployment process succeeded, you will see the transaction details in the terminal, including the contract address and deployment transaction hash: + Execute the deployment: - ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-10.webp) + ```bash + node deploy.js + ``` -## Interact with Your ERC-20 Contract + After running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions. -Once deployed, you can interact with your contract through Remix: +=== "Remix IDE" + Remix IDE offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development. -1. Find your contract under **Deployed/Unpinned Contracts**, and click it to expand the available methods. + ### Access Remix - ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-11.webp) + Navigate to [https://remix.ethereum.org/](https://remix.ethereum.org/){target=\_blank} in your web browser. -2. To mint new tokens: + The interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file. - 1. Click in the contract to expand its associated methods. - 2. Expand the **mint** function. - 3. Enter: - - The recipient address. - - The amount (remember to add 18 zeros for 1 whole token). - 4. Click **Transact**. + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-evm/deploy-basic-evm-01.webp) - ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-12.webp) + ### Compile -3. Click **Approve** to confirm the transaction in the Talisman popup. + 1. To compile your contract: + 1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar. + 2. Click **Compile Storage.sol** or press `Ctrl+S`. - ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-13.webp){: .browser-extension} + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-evm/deploy-basic-evm-02.webp) - If the transaction succeeds, you will see the following output in the terminal: + Compilation errors and warnings appear in the terminal panel at the bottom of the screen. - ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-14.webp) + ### Deploy -Other common functions you can use: + 1. Navigate to the **Deploy & Run Transactions** tab. + 2. Click the **Environment** dropdown and select **Browser extension**. + 3. Select **Injected Provider - MetaMask** (make sure you are logged in to MetaMask). + 4. In MetaMask, add a custom network with the following details: + - **Network Name**: Polkadot Hub TestNet + - **RPC URL**: `https://testnet-passet-hub-eth-rpc.polkadot.io` + - **Chain ID**: `420420422` + - **Currency Symbol**: `DOT` + 4. Return to Remix click on **Deploy**. + 6. Approve the transaction in your MetaMask wallet. -- **`balanceOf(address)`**: Check token balance of any address. -- **`transfer(address to, uint256 amount)`**: Send tokens to another address. -- **`approve(address spender, uint256 amount)`**: Allow another address to spend your tokens. + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-evm/deploy-basic-evm-03.webp) -Feel free to explore and interact with the contract's other functions using the same approach - selecting the method, providing any required parameters, and confirming the transaction through Talisman when needed. + Your deployed contract will appear in the **Deployed Contracts** section, ready for interaction. +=== "Hardhat" + Hardhat provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects. ---- + ### Setup -Page Title: Deploy an NFT to Polkadot Hub with Ethers.js + Initialize your Hardhat project: -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-nft-ethers.md -- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-nft/ethers/ -- Summary: Learn how to deploy an ERC-721 NFT contract to Polkadot Hub using Ethers.js, giving you complete programmatic control over the deployment process. + ```bash + mkdir hardhat-deployment + cd hardhat-deployment + npx hardhat --init + ``` -# Deploy an NFT with Ethers.js + ### Configure Hardhat -## Introduction + Edit `hardhat.config.js`: -Non-Fungible Tokens (NFTs) represent unique digital assets commonly used for digital art, collectibles, gaming, and identity verification. + ```javascript title="hardhat.config.js" hl_lines="39-43" + import type { HardhatUserConfig } from "hardhat/config"; -This guide demonstrates how to deploy an [ERC-721](https://eips.ethereum.org/EIPS/eip-721){target=\_blank} NFT contract to [Polkadot Hub](/smart-contracts/overview/#smart-contract-development){target=\_blank}. You'll use [OpenZeppelin's battle-tested NFT implementation](https://github.com/OpenZeppelin/openzeppelin-contracts){target=\_blank} and [Ethers.js](https://docs.ethers.org/v6/){target=\_blank}, a lightweight approach for deploying contracts in pure JavaScript. This method is ideal if you want programmatic control over the deployment process or need to integrate contract deployment into existing applications. + import hardhatToolboxViemPlugin from "@nomicfoundation/hardhat-toolbox-viem"; + import { configVariable } from "hardhat/config"; -## Prerequisites + const config: HardhatUserConfig = { + plugins: [hardhatToolboxViemPlugin], + solidity: { + profiles: { + default: { + version: "0.8.28", + }, + production: { + version: "0.8.28", + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, + }, + }, + }, + networks: { + hardhatMainnet: { + type: "edr-simulated", + chainType: "l1", + }, + hardhatOp: { + type: "edr-simulated", + chainType: "op", + }, + sepolia: { + type: "http", + chainType: "l1", + url: configVariable("SEPOLIA_RPC_URL"), + accounts: [configVariable("SEPOLIA_PRIVATE_KEY")], + }, + polkadotHubTestnet: { + url: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + accounts: [configVariable("PRIVATE_KEY")], + }, + }, + }; -- Basic understanding of Solidity programming and NFT standards. -- Node.js v22.13.1 or later. -- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). See the [step-by-step instructions](/smart-contracts/faucet/#get-test-tokens){target=\_blank}. -- A wallet with a private key for signing transactions. + export default config; -## Set Up Your Project + ``` -First, initialize your project and install dependencies: + ### Create Your Contract -```bash -mkdir ethers-nft-deployment -cd ethers-nft-deployment -npm init -y -npm install ethers@6.15.0 solc@0.8.30 @openzeppelin/contracts@5.0.0 -``` + Replace the default contract in `contracts/Storage.sol`: -## Create Your Contract + ```solidity + // SPDX-License-Identifier: MIT + pragma solidity ^0.8.9; -Create an NFT contract in `contracts/MyNFT.sol`: + contract Storage { + uint256 private storedNumber; -```solidity title="contracts/MyNFT.sol" -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; + function store(uint256 num) public { + storedNumber = num; + } -import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; + function retrieve() public view returns (uint256) { + return storedNumber; + } + } + ``` + + ### Compile + + ```bash + npx hardhat build + ``` + + ### Set Up Deployment + + Create a deployment module in `ignition/modules/Storage.ts`: + + ```typescript title="ignition/modules/Storage.ts" + import { buildModule } from '@nomicfoundation/hardhat-ignition/modules'; + + export default buildModule('StorageModule', (m) => { + const storage = m.contract('Storage'); + return { storage }; + }); + ``` + + ### Deploy + + Deploy to Polkadot Hub TestNet: + + ```bash + npx hardhat ignition deploy ignition/modules/Storage.ts --network polkadotHubTestnet + ``` + +=== "Foundry" + Foundry offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment. + + ### Setup + + Install Foundry: + + ```bash + curl -L https://foundry.paradigm.xyz | bash + foundryup + ``` + + Initialize your project: + + ```bash + forge init foundry-deployment + cd foundry-deployment + ``` + + ### Configure Foundry + + Edit `foundry.toml`: + + ```toml + [profile.default] + src = "src" + out = "out" + libs = ["lib"] + + [rpc_endpoints] + polkadot_hub_testnet = "https://testnet-passet-hub-eth-rpc.polkadot.io" + ``` + + ### Create Your Contract + + Replace the default contract in `src/Storage.sol`: + + ```solidity title="src/Storage.sol" + // SPDX-License-Identifier: MIT + pragma solidity ^0.8.9; + + contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } + } + ``` + + ### Compile + + ```bash + forge build + ``` + + Verify the compilation by inspecting the bytecode: + + ```bash + forge inspect Storage bytecode + ``` + + ### Deploy + + Deploy to Polkadot Hub TestNet: + + ```bash + forge create Storage \ + --rpc-url polkadot_hub_testnet \ + --private-key YOUR_PRIVATE_KEY \ + --broadcast + ``` + +## Conclusion + +This guide has demonstrated four different approaches to deploying smart contracts on Polkadot Hub using standard EVM tools. Each method offers distinct advantages: + +- **Ethers.js**: Best for lightweight, programmatic deployments and application integration +- **Remix IDE**: Ideal for rapid prototyping, learning, and visual development +- **Hardhat**: Perfect for professional workflows requiring comprehensive testing and debugging +- **Foundry**: Excellent for developers who prefer fast, command-line driven development + +All approaches use standard Solidity compilation to generate EVM bytecode, ensuring your contracts run on Polkadot Hub's EVM environment. Choose the tool that best fits your workflow and project requirements. + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). + + +--- + +Page Title: Deploy a Basic Contract to Polkadot Hub + +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/.deploy-basic-pvm/ +- Summary: Learn how to deploy a basic smart contract to Polkadot Hub using the PolkaVM. + +# Deploy a Basic Contract + +## Introduction + +Deploying smart contracts to [Polkadot Hub](/smart-contracts/overview/#smart-contract-development){target=\_blank} can be accomplished through various tools and environments, each suited to different development workflows. This guide demonstrates how to deploy a basic PolkaVM (PVM) smart contract using four popular approaches: JavaScript with [Ethers.js](https://docs.ethers.org/v6/){target=\_blank}, [Remix IDE](https://remix.live/){target=\_blank}, [Hardhat](https://hardhat.org/){target=\_blank}, and [Foundry](https://getfoundry.sh/){target=\_blank}. + +All these tools leverage the `revive` compiler to transform Solidity smart contracts into PolkaVM bytecode, making them compatible with Polkadot Hub's native smart contract environment. Whether you prefer working with lightweight JavaScript libraries, visual browser-based IDEs, comprehensive development frameworks, or fast command-line toolkits, this guide covers the deployment process for each approach. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later (for JavaScript/Hardhat approaches). +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +## JavaScript with Ethers.js + +Ethers.js provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications. + +### Setup + +First, initialize your project and install dependencies: + +```bash +mkdir ethers-deployment +cd ethers-deployment +npm init -y +npm install ethers @parity/resolc +``` + +### Create and Compile Your Contract + +Create a simple storage contract in `contracts/Storage.sol`: + +```solidity title="contracts/Storage.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +Create a compilation script `compile.js`: + +```javascript title="compile.js" +const { compile } = require('@parity/resolc'); +const { readFileSync, writeFileSync } = require('fs'); +const { basename, join } = require('path'); + +const compileContract = async (solidityFilePath, outputDir) => { + try { + // Read the Solidity file + const source = readFileSync(solidityFilePath, 'utf8'); + + // Construct the input object for the compiler + const input = { + [basename(solidityFilePath)]: { content: source }, + }; + + console.log(`Compiling contract: ${basename(solidityFilePath)}...`); + + // Compile the contract + const out = await compile(input); + + for (const contracts of Object.values(out.contracts)) { + for (const [name, contract] of Object.entries(contracts)) { + console.log(`Compiled contract: ${name}`); + + // Write the ABI + const abiPath = join(outputDir, `${name}.json`); + writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2)); + console.log(`ABI saved to ${abiPath}`); + + // Write the bytecode + const bytecodePath = join(outputDir, `${name}.polkavm`); + writeFileSync( + bytecodePath, + Buffer.from(contract.evm.bytecode.object, 'hex'), + ); + console.log(`Bytecode saved to ${bytecodePath}`); + } + } + } catch (error) { + console.error('Error compiling contracts:', error); + } +}; + +const solidityFilePath = join(__dirname, 'contracts/Storage.sol'); +const outputDir = join(__dirname, 'contracts'); + +compileContract(solidityFilePath, outputDir); +``` + +Run the compilation: + +```bash +node compile.js +``` + +### Deploy the Contract + +Create a deployment script `deploy.js`: + +```javascript title="deploy.js" +const { writeFileSync, existsSync, readFileSync } = require('fs'); +const { join } = require('path'); +const { ethers, JsonRpcProvider } = require('ethers'); + +const codegenDir = join(__dirname); + +// Creates a provider with specified RPC URL and chain details +const createProvider = (rpcUrl, chainId, chainName) => { + const provider = new JsonRpcProvider(rpcUrl, { + chainId: chainId, + name: chainName, + }); + return provider; +}; + +// Reads and parses the ABI file for a given contract +const getAbi = (contractName) => { + try { + return JSON.parse( + readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'), + ); + } catch (error) { + console.error( + `Could not find ABI for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +// Reads the compiled bytecode for a given contract +const getByteCode = (contractName) => { + try { + const bytecodePath = join( + codegenDir, + 'contracts', + `${contractName}.polkavm`, + ); + return `0x${readFileSync(bytecodePath).toString('hex')}`; + } catch (error) { + console.error( + `Could not find bytecode for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +const deployContract = async (contractName, mnemonic, providerConfig) => { + console.log(`Deploying ${contractName}...`); + + try { + // Step 1: Set up provider and wallet + const provider = createProvider( + providerConfig.rpc, + providerConfig.chainId, + providerConfig.name, + ); + const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic); + const wallet = walletMnemonic.connect(provider); + + // Step 2: Create and deploy the contract + const factory = new ethers.ContractFactory( + getAbi(contractName), + getByteCode(contractName), + wallet, + ); + const contract = await factory.deploy(); + await contract.waitForDeployment(); + + // Step 3: Save deployment information + const address = await contract.getAddress(); + console.log(`Contract ${contractName} deployed at: ${address}`); + + const addressesFile = join(codegenDir, 'contract-address.json'); + const addresses = existsSync(addressesFile) + ? JSON.parse(readFileSync(addressesFile, 'utf8')) + : {}; + addresses[contractName] = address; + writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8'); + } catch (error) { + console.error(`Failed to deploy contract ${contractName}:`, error); + } +}; + +const providerConfig = { + rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + name: 'polkadot-hub-testnet', +}; + +const mnemonic = 'INSERT_MNEMONIC'; + +deployContract('Storage', mnemonic, providerConfig); +``` + +Replace the `INSERT_MNEMONIC` placeholder with your actual mnemonic. + +Execute the deployment: + +```bash +node deploy.js +``` + +After running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions. + +## Remix IDE + +Remix IDE offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development. + +### Access Remix + +Navigate to [https://remix.polkadot.io/](https://remix.polkadot.io/){target=\_blank} in your web browser. + +The interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file: + +![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-01.webp) + +### Compile + +1. To compile your contract: + 1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar. + 2. Click **Compile Storage.sol** or press `Ctrl+S`. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-02.webp) + +Compilation errors and warnings appear in the terminal panel at the bottom of the screen. + +### Deploy + +1. Navigate to the **Deploy & Run Transactions** tab. +2. Click the **Environment** dropdown and select **Injected Provider - MetaMask** (ensure your MetaMask wallet is connected to Polkadot Hub TestNet). +3. Click **Deploy**. +4. Approve the transaction in your MetaMask wallet. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-03.webp) + +Your deployed contract will appear in the **Deployed Contracts** section, ready for interaction. + +## Hardhat + +Hardhat provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects. + +### Setup + +Initialize your Hardhat project: + +```bash +mkdir hardhat-deployment +cd hardhat-deployment +npm init -y +npm install --save-dev @parity/hardhat-polkadot@0.1.9 +npx hardhat-polkadot init +``` + +Select **Create a JavaScript project** when prompted. + +Complete the setup: + +```bash +echo '/ignition/deployments/' >> .gitignore +npm install +``` + +### Configure Hardhat + +Edit `hardhat.config.js`: + +```javascript title="hardhat.config.js" hl_lines="21-26" +require("@nomicfoundation/hardhat-toolbox") +require("@parity/hardhat-polkadot") + +/** @type import('hardhat/config').HardhatUserConfig */ +module.exports = { + solidity: "0.8.28", + resolc: { + compilerSource: "npm", + }, + networks: { + hardhat: { + polkavm: true, + forking: { + url: "https://testnet-passet-hub.polkadot.io", + }, + adapterConfig: { + adapterBinaryPath: "../bin/eth-rpc", + dev: true, + }, + }, + polkadotHubTestnet: { + polkavm: true, + url: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + accounts: [vars.get('PRIVATE_KEY')], + }, + }, +} +``` + +Run the following command to set the private key: + +```bash +npx hardhat vars set PRIVATE_KEY "INSERT_PRIVATE_KEY" +``` + +Replace `INSERT_PRIVATE_KEY` with your actual private key. + +### Create Your Contract + +Replace the default contract in `contracts/Storage.sol`: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +### Compile + +```bash +npx hardhat compile +``` + +### Set Up Deployment + +Create a deployment module in `ignition/modules/Storage.js`: + +```javascript +const { buildModule } = require('@nomicfoundation/hardhat-ignition/modules'); + +module.exports = buildModule('StorageModule', (m) => { + const storage = m.contract('Storage'); + return { storage }; +}); +``` + +### Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +npx hardhat ignition deploy ./ignition/modules/Storage.js --network polkadotHubTestnet +``` + +## Foundry + +Foundry offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment. + +### Setup + +Install Foundry for Polkadot: + +```bash +curl -L https://raw.githubusercontent.com/paritytech/foundry-polkadot/refs/heads/master/foundryup/install | bash +foundryup-polkadot +``` + +Initialize your project: + +```bash +forge init foundry-deployment +cd foundry-deployment +``` + +### Configure Foundry + +Edit `foundry.toml`: + +```toml +[profile.default] +src = "src" +out = "out" +libs = ["lib"] + +[profile.default.resolc] +resolc_compile = true + +[rpc_endpoints] +polkadot_hub_testnet = "https://testnet-passet-hub-eth-rpc.polkadot.io" +``` + +### Create Your Contract + +Replace the default contract in `src/Storage.sol`: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +### Compile + +```bash +forge build --resolc +``` + +Verify the compilation by inspecting the bytecode (should start with `0x505`): + +```bash +forge inspect Storage bytecode --resolc +``` + +### Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +forge create Storage \ + --rpc-url polkadot_hub_testnet \ + --private-key YOUR_PRIVATE_KEY \ + --resolc --broadcast +``` + +## Conclusion + +This guide has demonstrated four different approaches to deploying smart contracts on Polkadot Hub. Each method offers distinct advantages: + +- **Ethers.js**: Best for lightweight, programmatic deployments and application integration +- **Remix IDE**: Ideal for rapid prototyping, learning, and visual development +- **Hardhat**: Perfect for professional workflows requiring comprehensive testing and debugging +- **Foundry**: Excellent for developers who prefer fast, command-line driven development + +All approaches use the `resolc` compiler to generate PolkaVM-compatible bytecode, ensuring your contracts run natively on Polkadot Hub. Choose the tool that best fits your workflow and project requirements. + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). + + +--- + +Page Title: Deploy a Basic Contract to Polkadot Hub + +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-pvm.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-pvm/ +- Summary: Learn how to deploy a basic smart contract to Polkadot Hub using the PolkaVM. + +# Deploy a Basic Contract + +## Introduction + +Deploying smart contracts to [Polkadot Hub](/smart-contracts/overview/#smart-contract-development){target=\_blank} can be accomplished through various tools and environments, each suited to different development workflows. This guide demonstrates how to deploy a basic PolkaVM (PVM) smart contract using four popular approaches: JavaScript with [Ethers.js](https://docs.ethers.org/v6/){target=\_blank}, [Remix IDE](https://remix.live/){target=\_blank}, [Hardhat](https://hardhat.org/){target=\_blank}, and [Foundry](https://getfoundry.sh/){target=\_blank}. + +All these tools leverage the `revive` compiler to transform Solidity smart contracts into PolkaVM bytecode, making them compatible with Polkadot Hub's native smart contract environment. Whether you prefer working with lightweight JavaScript libraries, visual browser-based IDEs, comprehensive development frameworks, or fast command-line toolkits, this guide covers the deployment process for each approach. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later (for JavaScript/Hardhat approaches). +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +## JavaScript with Ethers.js + +Ethers.js provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications. + +### Setup + +First, initialize your project and install dependencies: + +```bash +mkdir ethers-deployment +cd ethers-deployment +npm init -y +npm install ethers @parity/resolc +``` + +### Create and Compile Your Contract + +Create a simple storage contract in `contracts/Storage.sol`: + +```solidity title="contracts/Storage.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +Create a compilation script `compile.js`: + +```javascript title="compile.js" +const { compile } = require('@parity/resolc'); +const { readFileSync, writeFileSync } = require('fs'); +const { basename, join } = require('path'); + +const compileContract = async (solidityFilePath, outputDir) => { + try { + // Read the Solidity file + const source = readFileSync(solidityFilePath, 'utf8'); + + // Construct the input object for the compiler + const input = { + [basename(solidityFilePath)]: { content: source }, + }; + + console.log(`Compiling contract: ${basename(solidityFilePath)}...`); + + // Compile the contract + const out = await compile(input); + + for (const contracts of Object.values(out.contracts)) { + for (const [name, contract] of Object.entries(contracts)) { + console.log(`Compiled contract: ${name}`); + + // Write the ABI + const abiPath = join(outputDir, `${name}.json`); + writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2)); + console.log(`ABI saved to ${abiPath}`); + + // Write the bytecode + const bytecodePath = join(outputDir, `${name}.polkavm`); + writeFileSync( + bytecodePath, + Buffer.from(contract.evm.bytecode.object, 'hex'), + ); + console.log(`Bytecode saved to ${bytecodePath}`); + } + } + } catch (error) { + console.error('Error compiling contracts:', error); + } +}; + +const solidityFilePath = join(__dirname, 'contracts/Storage.sol'); +const outputDir = join(__dirname, 'contracts'); + +compileContract(solidityFilePath, outputDir); +``` + +Run the compilation: + +```bash +node compile.js +``` + +### Deploy the Contract + +Create a deployment script `deploy.js`: + +```javascript title="deploy.js" +const { writeFileSync, existsSync, readFileSync } = require('fs'); +const { join } = require('path'); +const { ethers, JsonRpcProvider } = require('ethers'); + +const codegenDir = join(__dirname); + +// Creates a provider with specified RPC URL and chain details +const createProvider = (rpcUrl, chainId, chainName) => { + const provider = new JsonRpcProvider(rpcUrl, { + chainId: chainId, + name: chainName, + }); + return provider; +}; + +// Reads and parses the ABI file for a given contract +const getAbi = (contractName) => { + try { + return JSON.parse( + readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'), + ); + } catch (error) { + console.error( + `Could not find ABI for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +// Reads the compiled bytecode for a given contract +const getByteCode = (contractName) => { + try { + const bytecodePath = join( + codegenDir, + 'contracts', + `${contractName}.polkavm`, + ); + return `0x${readFileSync(bytecodePath).toString('hex')}`; + } catch (error) { + console.error( + `Could not find bytecode for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +const deployContract = async (contractName, mnemonic, providerConfig) => { + console.log(`Deploying ${contractName}...`); + + try { + // Step 1: Set up provider and wallet + const provider = createProvider( + providerConfig.rpc, + providerConfig.chainId, + providerConfig.name, + ); + const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic); + const wallet = walletMnemonic.connect(provider); + + // Step 2: Create and deploy the contract + const factory = new ethers.ContractFactory( + getAbi(contractName), + getByteCode(contractName), + wallet, + ); + const contract = await factory.deploy(); + await contract.waitForDeployment(); + + // Step 3: Save deployment information + const address = await contract.getAddress(); + console.log(`Contract ${contractName} deployed at: ${address}`); + + const addressesFile = join(codegenDir, 'contract-address.json'); + const addresses = existsSync(addressesFile) + ? JSON.parse(readFileSync(addressesFile, 'utf8')) + : {}; + addresses[contractName] = address; + writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8'); + } catch (error) { + console.error(`Failed to deploy contract ${contractName}:`, error); + } +}; + +const providerConfig = { + rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + name: 'polkadot-hub-testnet', +}; + +const mnemonic = 'INSERT_MNEMONIC'; + +deployContract('Storage', mnemonic, providerConfig); +``` + +Replace the `INSERT_MNEMONIC` placeholder with your actual mnemonic. + +Execute the deployment: + +```bash +node deploy.js +``` + +After running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions. + +## Remix IDE + +Remix IDE offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development. + +### Access Remix + +Navigate to [https://remix.polkadot.io/](https://remix.polkadot.io/){target=\_blank} in your web browser. + +The interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file: + +![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-01.webp) + +### Compile + +1. To compile your contract: + 1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar. + 2. Click **Compile Storage.sol** or press `Ctrl+S`. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-02.webp) + +Compilation errors and warnings appear in the terminal panel at the bottom of the screen. + +### Deploy + +1. Navigate to the **Deploy & Run Transactions** tab. +2. Click the **Environment** dropdown and select **Injected Provider - MetaMask** (ensure your MetaMask wallet is connected to Polkadot Hub TestNet). +3. Click **Deploy**. +4. Approve the transaction in your MetaMask wallet. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-03.webp) + +Your deployed contract will appear in the **Deployed Contracts** section, ready for interaction. + +## Hardhat + +Hardhat provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects. + +### Setup + +Initialize your Hardhat project: + +```bash +mkdir hardhat-deployment +cd hardhat-deployment +npm init -y +npm install --save-dev @parity/hardhat-polkadot@0.1.9 +npx hardhat-polkadot init +``` + +Select **Create a JavaScript project** when prompted. + +Complete the setup: + +```bash +echo '/ignition/deployments/' >> .gitignore +npm install +``` + +### Configure Hardhat + +Edit `hardhat.config.js`: + +```javascript title="hardhat.config.js" hl_lines="21-26" +require("@nomicfoundation/hardhat-toolbox") +require("@parity/hardhat-polkadot") + +/** @type import('hardhat/config').HardhatUserConfig */ +module.exports = { + solidity: "0.8.28", + resolc: { + compilerSource: "npm", + }, + networks: { + hardhat: { + polkavm: true, + forking: { + url: "https://testnet-passet-hub.polkadot.io", + }, + adapterConfig: { + adapterBinaryPath: "../bin/eth-rpc", + dev: true, + }, + }, + polkadotHubTestnet: { + polkavm: true, + url: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + accounts: [vars.get('PRIVATE_KEY')], + }, + }, +} +``` + +Run the following command to set the private key: + +```bash +npx hardhat vars set PRIVATE_KEY "INSERT_PRIVATE_KEY" +``` + +Replace `INSERT_PRIVATE_KEY` with your actual private key. + +### Create Your Contract + +Replace the default contract in `contracts/Storage.sol`: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +### Compile + +```bash +npx hardhat compile +``` + +### Set Up Deployment + +Create a deployment module in `ignition/modules/Storage.js`: + +```javascript +const { buildModule } = require('@nomicfoundation/hardhat-ignition/modules'); + +module.exports = buildModule('StorageModule', (m) => { + const storage = m.contract('Storage'); + return { storage }; +}); +``` + +### Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +npx hardhat ignition deploy ./ignition/modules/Storage.js --network polkadotHubTestnet +``` + +## Foundry + +Foundry offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment. + +### Setup + +Install Foundry for Polkadot: + +```bash +curl -L https://raw.githubusercontent.com/paritytech/foundry-polkadot/refs/heads/master/foundryup/install | bash +foundryup-polkadot +``` + +Initialize your project: + +```bash +forge init foundry-deployment +cd foundry-deployment +``` + +### Configure Foundry + +Edit `foundry.toml`: + +```toml +[profile.default] +src = "src" +out = "out" +libs = ["lib"] + +[profile.default.resolc] +resolc_compile = true + +[rpc_endpoints] +polkadot_hub_testnet = "https://testnet-passet-hub-eth-rpc.polkadot.io" +``` + +### Create Your Contract + +Replace the default contract in `src/Storage.sol`: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +### Compile + +```bash +forge build --resolc +``` + +Verify the compilation by inspecting the bytecode (should start with `0x505`): + +```bash +forge inspect Storage bytecode --resolc +``` + +### Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +forge create Storage \ + --rpc-url polkadot_hub_testnet \ + --private-key YOUR_PRIVATE_KEY \ + --resolc --broadcast +``` + +## Conclusion + +This guide has demonstrated four different approaches to deploying smart contracts on Polkadot Hub. Each method offers distinct advantages: + +- **Ethers.js**: Best for lightweight, programmatic deployments and application integration +- **Remix IDE**: Ideal for rapid prototyping, learning, and visual development +- **Hardhat**: Perfect for professional workflows requiring comprehensive testing and debugging +- **Foundry**: Excellent for developers who prefer fast, command-line driven development + +All approaches use the `resolc` compiler to generate PolkaVM-compatible bytecode, ensuring your contracts run natively on Polkadot Hub. Choose the tool that best fits your workflow and project requirements. + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). + + +--- + +Page Title: Deploy a Basic Contract with Ethers.js + +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-ethers.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic/ethers/ +- Summary: Learn how to deploy a basic smart contract to Polkadot Hub using Ethers.js, best for lightweight, programmatic deployments and application integration. + +# Deploy a Basic Contract with Ethers.js + +## Introduction + +This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Ethers.js](https://docs.ethers.org/v6/){target=\_blank}, which provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications. + +## Prerequisites + +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). See the [step-by-step instructions](/smart-contracts/faucet/#get-test-tokens){target=\_blank}. +- A wallet with a private key for signing transactions. + +## Set Up Your Project + +First, initialize your project and install dependencies: + +```bash +mkdir ethers-deployment +cd ethers-deployment +npm init -y +npm install ethers@6.15.0 solc@0.8.30 +``` + +## Create Your Contract + +Create a simple storage contract in `contracts/Storage.sol`: + +```solidity title="contracts/Storage.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +## Compile + +Create a compilation script `compile.js`: + +```javascript title="compile.js" +const solc = require('solc'); +const { readFileSync, writeFileSync } = require('fs'); +const { basename, join } = require('path'); + +const compileContract = async (solidityFilePath, outputDir) => { + try { + // Read the Solidity file + const source = readFileSync(solidityFilePath, 'utf8'); + + // Construct the input object for the compiler + const input = { + language: 'Solidity', + sources: { + [basename(solidityFilePath)]: { content: source }, + }, + settings: { + outputSelection: { + '*': { + '*': ['*'], + }, + }, + }, + }; + + console.log(`Compiling contract: ${basename(solidityFilePath)}...`); + + // Compile the contract + const output = JSON.parse(solc.compile(JSON.stringify(input))); + + if (output.errors) { + output.errors.forEach(error => { + console.error('Compilation error:', error.message); + }); + return; + } + + for (const contracts of Object.values(output.contracts)) { + for (const [name, contract] of Object.entries(contracts)) { + console.log(`Compiled contract: ${name}`); + + // Write the ABI + const abiPath = join(outputDir, `${name}.json`); + writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2)); + console.log(`ABI saved to ${abiPath}`); + + // Write the bytecode + const bytecodePath = join(outputDir, `${name}.bin`); + writeFileSync(bytecodePath, + Buffer.from( + contract.evm.bytecode.object, + 'hex' + )); + console.log(`Bytecode saved to ${bytecodePath}`); + } + } + } catch (error) { + console.error('Error compiling contracts:', error); + } +}; + +const solidityFilePath = join(__dirname, 'contracts/Storage.sol'); +const outputDir = join(__dirname, 'contracts'); + +compileContract(solidityFilePath, outputDir); +``` + +Run the compilation: + +```bash +node compile.js +``` + +## Deploy + +Create a deployment script `deploy.js`: + +```javascript title="deploy.js" +const { writeFileSync, existsSync, readFileSync } = require('fs'); +const { join } = require('path'); +const { ethers, JsonRpcProvider } = require('ethers'); + +const codegenDir = join(__dirname); + +// Creates a provider with specified RPC URL and chain details +const createProvider = (rpcUrl, chainId, chainName) => { + const provider = new JsonRpcProvider(rpcUrl, { + chainId: chainId, + name: chainName, + }); + return provider; +}; + +// Reads and parses the ABI file for a given contract +const getAbi = (contractName) => { + try { + return JSON.parse( + readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'), + ); + } catch (error) { + console.error( + `Could not find ABI for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +// Reads the compiled bytecode for a given contract +const getByteCode = (contractName) => { + try { + const bytecodePath = join( + codegenDir, + 'contracts', + `${contractName}.bin`, + ); + return `0x${readFileSync(bytecodePath).toString('hex')}`; + } catch (error) { + console.error( + `Could not find bytecode for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +const deployContract = async (contractName, mnemonic, providerConfig) => { + console.log(`Deploying ${contractName}...`); + + try { + // Step 1: Set up provider and wallet + const provider = createProvider( + providerConfig.rpc, + providerConfig.chainId, + providerConfig.name, + ); + const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic); + const wallet = walletMnemonic.connect(provider); + + // Step 2: Create and deploy the contract + const factory = new ethers.ContractFactory( + getAbi(contractName), + getByteCode(contractName), + wallet, + ); + const contract = await factory.deploy(); + await contract.waitForDeployment(); + + // Step 3: Save deployment information + const address = await contract.getAddress(); + console.log(`Contract ${contractName} deployed at: ${address}`); + + const addressesFile = join(codegenDir, 'contract-address.json'); + const addresses = existsSync(addressesFile) + ? JSON.parse(readFileSync(addressesFile, 'utf8')) + : {}; + addresses[contractName] = address; + writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8'); + } catch (error) { + console.error(`Failed to deploy contract ${contractName}:`, error); + } +}; + +const providerConfig = { + rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + name: 'polkadot-hub-testnet', +}; + +const mnemonic = 'INSERT_MNEMONIC'; + +deployContract('Storage', mnemonic, providerConfig); +``` + +Replace the `INSERT_MNEMONIC` placeholder with your actual mnemonic. + +!!! warning + Never embed private keys, mnemonic phrases, or security-sensitive credentials directly into your JavaScript, TypeScript, or any front-end/client-side files. + +Execute the deployment: + +```bash +node deploy.js +``` + +After running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions. + +## Where to Go Next + +
+ +- Guide __Deploy an ERC-20__ + + --- + + Walk through deploying a fully-functional ERC-20 to the Polkadot Hub using Ethers.js. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-erc20/ethers/) + +- Guide __Deploy an NFT__ + + --- + + Walk through deploying a NFT to the Polkadot Hub using Ethers.js. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-nft/ethers/) + +
+ + +--- + +Page Title: Deploy a Basic Contract with Foundry + +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-foundry.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic/foundry/ +- Summary: Learn how to deploy a basic smart contract to Polkadot Hub using Foundry, excellent for developers who prefer fast, command-line driven development. + +# Deploy a Basic Contract with Foundry + +This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Foundry](https://getfoundry.sh/){target=\_blank}, which offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment. + +## Prerequisites + +- Basic understanding of Solidity programming. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). See the [step-by-step instructions](/smart-contracts/faucet/#get-test-tokens){target=\_blank}. +- A wallet with a private key for signing transactions. + +## Set Up Your Project + +Install Foundry: + +```bash +curl -L https://foundry.paradigm.xyz | bash +foundryup +``` + +Initialize your project: + +```bash +forge init foundry-deployment +cd foundry-deployment +``` + +## Configure Foundry + +Edit `foundry.toml`: + +```toml +[profile.default] +src = "src" +out = "out" +libs = ["lib"] + +[rpc_endpoints] +polkadot_hub_testnet = "https://testnet-passet-hub-eth-rpc.polkadot.io" +``` + +## Create Your Contract + +Replace the default contract in `src/Storage.sol`: + +```solidity title="src/Storage.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +## Compile + +```bash +forge build +``` + +Verify the compilation by inspecting the bytecode: + +```bash +forge inspect Storage bytecode +``` + +## Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +forge create Storage \ + --rpc-url polkadot_hub_testnet \ + --private-key YOUR_PRIVATE_KEY \ + --broadcast +``` + +Replace the `YOUR_PRIVATE_KEY` placeholder with your actual private key. + +## Where to Go Next + +
+ +- Guide __Verify Your Contract__ + + --- + + Now that you've deployed a basic contract, learn how to verify it with Foundry. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/dev-environments/foundry/verify-a-contract/) + +- Guide __Deploy an ERC-20__ + + --- + + Walk through deploying a fully-functional ERC-20 to the Polkadot Hub using Foundry. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-erc20/foundry/) + +- Guide __Deploy an NFT__ + + --- + + Walk through deploying a NFT to the Polkadot Hub using Foundry. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-nft/foundry/) + +
+ + +--- + +Page Title: Deploy a Basic Contract with Hardhat + +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic/hardhat/ +- Summary: Learn how to deploy a basic smart contract to Polkadot Hub using Hardhat, Perfect for professional workflows requiring comprehensive testing and debugging. + +# Deploy a Basic Contract with + +## Introduction + +This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Hardhat](https://hardhat.org/){target=\_blank}, which provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects. + +## Prerequisites + +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). See the [step-by-step instructions](/smart-contracts/faucet/#get-test-tokens){target=\_blank}. +- A wallet with a private key for signing transactions. + +## Set Up Your Project + +Initialize your Hardhat project: + +```bash +mkdir hardhat-deployment +cd hardhat-deployment +npx hardhat --init +``` + +## Configure Hardhat + +Edit `hardhat.config.js`: + +```javascript title='hardhat.config.js' hl_lines='39-43' +import type { HardhatUserConfig } from 'hardhat/config'; + +import hardhatToolboxViemPlugin from '@nomicfoundation/hardhat-toolbox-viem'; +import { configVariable } from 'hardhat/config'; + +const config: HardhatUserConfig = { + plugins: [hardhatToolboxViemPlugin], + solidity: { + profiles: { + default: { + version: '0.8.28', + }, + production: { + version: '0.8.28', + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, + }, + }, + }, + networks: { + hardhatMainnet: { + type: 'edr-simulated', + chainType: 'l1', + }, + hardhatOp: { + type: 'edr-simulated', + chainType: 'op', + }, + sepolia: { + type: 'http', + chainType: 'l1', + url: configVariable('SEPOLIA_RPC_URL'), + accounts: [configVariable('SEPOLIA_PRIVATE_KEY')], + }, + polkadotHubTestnet: { + url: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + accounts: [configVariable('PRIVATE_KEY')], + }, + }, +}; + +export default config; + +``` + +!!! tip + Learn how to use Hardhat's [Config Variables](https://hardhat.org/docs/learn-more/configuration-variables){target=\_blank} to handle your private keys in a secure way. + +## Create Your Contract + +Replace the default contract in `contracts/Storage.sol`: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +## Compile + +```bash +npx hardhat build +``` + +## Set Up Deployment + +Create a deployment module in `ignition/modules/Storage.ts`: + +```typescript title="ignition/modules/Storage.ts" +import { buildModule } from '@nomicfoundation/hardhat-ignition/modules'; + +export default buildModule('StorageModule', (m) => { + const storage = m.contract('Storage'); + return { storage }; +}); +``` + +## Deploy the Contract + +Deploy to Polkadot Hub TestNet: + +```bash +npx hardhat ignition deploy ignition/modules/Storage.ts --network polkadotHubTestnet +``` + +## Where to Go Next + +
+ +- Guide __Verify Your Contract__ + + --- + + Now that you've deployed a basic contract, learn how to verify it with Hardhat. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/dev-environments/hardhat/verify-a-contract/) + +- Guide __Deploy an ERC-20__ + + --- + + Walk through deploying a fully-functional ERC-20 to the Polkadot Hub using Hardhat. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-erc20/hardhat/) + +- Guide __Deploy an NFT__ + + --- + + Walk through deploying a NFT to the Polkadot Hub using Hardhat. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-nft/hardhat/) + +
+ + +--- + +Page Title: Deploy a Basic Contract with Remix IDE + +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-remix.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic/remix/ +- Summary: Learn how to deploy a basic smart contract to Polkadot Hub using Remix IDE Ideal for rapid prototyping, learning, and visual development. + +# Deploy a Basic Contract with Remix IDE + +## Introduction + +This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Remix IDE](https://remix.ethereum.org/){target=\_blank}, which offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development. + +## Prerequisites + +- Basic understanding of Solidity programming. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). See the [step-by-step instructions](/smart-contracts/faucet/#get-test-tokens){target=\_blank}. +- A wallet with a private key for signing transactions. + +## Access Remix + +Navigate to [Remix](https://remix.ethereum.org/){target=\_blank} in your web browser. + +The interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file, which will be used as the example contract throughout this guide. + +![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-01.webp) + +## Compile + +1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar. +2. Click **Compile Storage.sol** or press `Ctrl+S`. + +![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-02.webp) + +Compilation errors and warnings appear in the terminal panel at the bottom of the screen. + +## Deploy + +1. Navigate to the **Deploy & Run Transactions** tab. +2. Click the **Environment** dropdown and select **Injected Provider - MetaMask** (ensure your MetaMask wallet is connected to Polkadot Hub TestNet). +3. Click **Deploy**. +4. Approve the transaction in your MetaMask wallet. + +![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-03.webp) + +Your deployed contract will appear in the **Deployed Contracts** section, ready for interaction. + +## Where to Go Next + +
+ +- Guide __Verify Your Contract__ + + --- + + Now that you've deployed a basic contract, learn how to verify it with Remix. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/dev-environments/remix/verify-a-contract/) + +- Guide __Deploy an ERC-20__ + + --- + + Walk through deploying a fully-functional ERC-20 to the Polkadot Hub using Remix. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-erc20/remix/) + +- Guide __Deploy an NFT__ + + --- + + Walk through deploying a NFT to the Polkadot Hub using Remix. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-nft/remix/) + +
+ + +--- + +Page Title: Deploy an ERC-20 to Polkadot Hub + +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-erc20.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-erc20/ +- Summary: Deploy an ERC-20 token on Polkadot Hub using PolkaVM. This guide covers contract creation, compilation, deployment, and interaction via Polkadot Remix IDE. + +# Deploy an ERC-20 to Polkadot Hub + +!!! smartcontract "PolkaVM Preview Release" + PolkaVM smart contracts with Ethereum compatibility are in **early-stage development and may be unstable or incomplete**. +## Introduction + +[ERC-20](https://eips.ethereum.org/EIPS/eip-20){target=\_blank} tokens are fungible tokens commonly used for creating cryptocurrencies, governance tokens, and staking mechanisms. Polkadot Hub enables easy token deployment with Ethereum-compatible smart contracts via PolkaVM. + +This tutorial covers deploying an ERC-20 contract on the Polkadot Hub TestNet using [Polkadot Remix IDE](https://remix.polkadot.io){target=\_blank}, a web-based development tool. [OpenZeppelin's ERC-20 contracts](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/v5.4.0/contracts/token/ERC20){target=\_blank} are used for security and compliance. + +## Prerequisites + +Before starting, make sure you have: + +- [MetaMask](https://metamask.io/){target=\_blank} installed and connected to Polkadot Hub. For detailed instructions, see the [Connect Your Wallet](/smart-contracts/integrations/wallets){target=\_blank} section. +- A funded account with some PAS tokens (you can get them from the [Polkadot Faucet](https://faucet.polkadot.io/?parachain=1111){target=\_blank}). To learn how to get test tokens, check out the [Test Tokens](/smart-contracts/connect/#test-tokens){target=\_blank} section. +- Basic understanding of Solidity and fungible tokens. + +## Create the ERC-20 Contract + +To create the ERC-20 contract, you can follow the steps below: + +1. Navigate to the [Polkadot Remix IDE](https://remix.polkadot.io){target=\_blank}. +2. Click in the **Create new file** button under the **contracts** folder, and name your contract as `MyToken.sol`. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-1.webp) + +3. Now, paste the following ERC-20 contract code into the editor: + + ```solidity title="MyToken.sol" + // SPDX-License-Identifier: MIT + // Compatible with OpenZeppelin Contracts ^5.0.0 + pragma solidity ^0.8.22; + + import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; + + contract MyToken is ERC20, Ownable { + constructor(address initialOwner) + ERC20("MyToken", "MTK") + Ownable(initialOwner) + {} + + function mint(address to, uint256 amount) public onlyOwner { + _mint(to, amount); + } + } + ``` + + The key components of the code above are: + + - Contract imports: + + - **[`ERC20.sol`](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/v5.4.0/contracts/token/ERC20/ERC20.sol){target=\_blank}**: The base contract for fungible tokens, implementing core functionality like transfers, approvals, and balance tracking. + - **[`Ownable.sol`](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/v5.4.0/contracts/access/Ownable.sol){target=\_blank}**: Provides basic authorization control, ensuring only the contract owner can mint new tokens. + + - Constructor parameters: + + - **`initialOwner`**: Sets the address that will have administrative rights over the contract. + - **`"MyToken"`**: The full name of your token. + - **`"MTK"`**: The symbol representing your token in wallets and exchanges. + + - Key functions: + + - **`mint(address to, uint256 amount)`**: Allows the contract owner to create new tokens for any address. The amount should include 18 decimals (e.g., 1 token = 1000000000000000000). + - Inherited [Standard ERC-20](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/){target=\_blank} functions: + - **`transfer(address recipient, uint256 amount)`**: Sends a specified amount of tokens to another address. + - **`approve(address spender, uint256 amount)`**: Grants permission for another address to spend a specific number of tokens on behalf of the token owner. + - **`transferFrom(address sender, address recipient, uint256 amount)`**: Transfers tokens from one address to another, if previously approved. + - **`balanceOf(address account)`**: Returns the token balance of a specific address. + - **`allowance(address owner, address spender)`**: Checks how many tokens an address is allowed to spend on behalf of another address. + + !!! tip + Use the [OpenZeppelin Contracts Wizard](https://wizard.openzeppelin.com/){target=\_blank} to quickly generate customized smart contracts. Simply configure your contract, copy the generated code, and paste it into Polkadot Remix IDE for deployment. Below is an example of an ERC-20 token contract created with it: + + ![Screenshot of the OpenZeppelin Contracts Wizard showing an ERC-20 contract configuration.](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-2.webp) + + +## Compile the Contract + +The compilation transforms your Solidity source code into bytecode that can be deployed on the blockchain. During this process, the compiler checks your contract for syntax errors, ensures type safety, and generates the machine-readable instructions needed for blockchain execution. To compile your contract, follow the instructions below: + +1. Select the **Solidity Compiler** plugin from the left panel. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-3.webp) + +2. Click the **Compile MyToken.sol** button. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-4.webp) + +3. If the compilation succeeded, you'll see a green checkmark indicating success in the **Solidity Compiler** icon. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-5.webp) + +## Deploy the Contract + +Deployment is the process of publishing your compiled smart contract to the blockchain, making it permanently available for interaction. During deployment, you'll create a new instance of your contract on the blockchain, which involves: + +1. Select the **Deploy & Run Transactions** plugin from the left panel. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-6.webp) + +2. Configure the deployment settings. + 1. From the **ENVIRONMENT** dropdown, select **Injected Provider - Talisman** (check the [Deploying Contracts](/smart-contracts/dev-environments/remix/deploy-a-contract/){target=\_blank} section of the Remix IDE guide for more details). + 2. From the **ACCOUNT** dropdown, select the account you want to use for the deploy. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-7.webp) + +3. Configure the contract parameters: + + 1. Enter the address that will own the deployed token contract. + 2. Click the **Deploy** button to initiate the deployment. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-8.webp) + +4. **Talisman will pop up**: Review the transaction details. Click **Approve** to deploy your contract. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-9.webp){: .browser-extension} + + If the deployment process succeeded, you will see the transaction details in the terminal, including the contract address and deployment transaction hash: + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-10.webp) + +## Interact with Your ERC-20 Contract + +Once deployed, you can interact with your contract through Remix: + +1. Find your contract under **Deployed/Unpinned Contracts**, and click it to expand the available methods. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-11.webp) + +2. To mint new tokens: + + 1. Click in the contract to expand its associated methods. + 2. Expand the **mint** function. + 3. Enter: + - The recipient address. + - The amount (remember to add 18 zeros for 1 whole token). + 4. Click **Transact**. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-12.webp) + +3. Click **Approve** to confirm the transaction in the Talisman popup. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-13.webp){: .browser-extension} + + If the transaction succeeds, you will see the following output in the terminal: + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-14.webp) + +Other common functions you can use: + +- **`balanceOf(address)`**: Check token balance of any address. +- **`transfer(address to, uint256 amount)`**: Send tokens to another address. +- **`approve(address spender, uint256 amount)`**: Allow another address to spend your tokens. + +Feel free to explore and interact with the contract's other functions using the same approach - selecting the method, providing any required parameters, and confirming the transaction through Talisman when needed. + + +--- + +Page Title: Deploy an NFT to Polkadot Hub with Ethers.js + +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-nft-ethers.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-nft/ethers/ +- Summary: Learn how to deploy an ERC-721 NFT contract to Polkadot Hub using Ethers.js, giving you complete programmatic control over the deployment process. + +# Deploy an NFT with Ethers.js + +## Introduction + +Non-Fungible Tokens (NFTs) represent unique digital assets commonly used for digital art, collectibles, gaming, and identity verification. + +This guide demonstrates how to deploy an [ERC-721](https://eips.ethereum.org/EIPS/eip-721){target=\_blank} NFT contract to [Polkadot Hub](/smart-contracts/overview/#smart-contract-development){target=\_blank}. You'll use [OpenZeppelin's battle-tested NFT implementation](https://github.com/OpenZeppelin/openzeppelin-contracts){target=\_blank} and [Ethers.js](https://docs.ethers.org/v6/){target=\_blank}, a lightweight approach for deploying contracts in pure JavaScript. This method is ideal if you want programmatic control over the deployment process or need to integrate contract deployment into existing applications. + +## Prerequisites + +- Basic understanding of Solidity programming and NFT standards. +- Node.js v22.13.1 or later. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). See the [step-by-step instructions](/smart-contracts/faucet/#get-test-tokens){target=\_blank}. +- A wallet with a private key for signing transactions. + +## Set Up Your Project + +First, initialize your project and install dependencies: + +```bash +mkdir ethers-nft-deployment +cd ethers-nft-deployment +npm init -y +npm install ethers@6.15.0 solc@0.8.30 @openzeppelin/contracts@5.0.0 +``` + +## Create Your Contract + +Create an NFT contract in `contracts/MyNFT.sol`: + +```solidity title="contracts/MyNFT.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; contract MyNFT is ERC721, Ownable { uint256 private _nextTokenId; @@ -4482,57 +6566,251 @@ npx @acala-network/chopsticks run-block \ } } - ``` + ``` + +## XCM Testing + +To test XCM (Cross-Consensus Messaging) messages between networks, you can fork multiple parachains and a relay chain locally using Chopsticks. + +- **`relaychain`**: Relay chain config file. +- **`parachain`**: Parachain config file. + +For example, to fork Moonbeam, Astar, and Polkadot enabling XCM between them, you can use the following command: + +```bash +npx @acala-network/chopsticks xcm \ +--r polkadot \ +--p moonbeam \ +--p astar +``` + +After running it, you should see output similar to the following: + +
+ npx @acala-network/chopsticks xcm \ + --r polkadot \ + --p moonbeam \ + --p astar +
+ [13:46:07.901] INFO: Loading config file https://raw.githubusercontent.com/AcalaNetwork/chopsticks/master/configs/moonbeam.yml + app: "chopsticks" + [13:46:12.631] INFO: Moonbeam RPC listening on port 8000 + app: "chopsticks" + [13:46:12.632] INFO: Loading config file https://raw.githubusercontent.com/AcalaNetwork/chopsticks/master/configs/astar.yml + app: "chopsticks" + chopsticks::executor TRACE: Calling Metadata_metadata + chopsticks::executor TRACE: Completed Metadata_metadata + [13:46:23.669] INFO: Astar RPC listening on port 8001 + app: "chopsticks" + [13:46:25.144] INFO (xcm): Connected parachains [2004,2006] + app: "chopsticks" + [13:46:25.144] INFO: Loading config file https://raw.githubusercontent.com/AcalaNetwork/chopsticks/master/configs/polkadot.yml + app: "chopsticks" + chopsticks::executor TRACE: Calling Metadata_metadata + chopsticks::executor TRACE: Completed Metadata_metadata + [13:46:53.320] INFO: Polkadot RPC listening on port 8002 + app: "chopsticks" + [13:46:54.038] INFO (xcm): Connected relaychain 'Polkadot' with parachain 'Moonbeam' + app: "chopsticks" + [13:46:55.028] INFO (xcm): Connected relaychain 'Polkadot' with parachain 'Astar' + app: "chopsticks" +
+ +Now you can interact with your forked chains using the ports specified in the output. + + +--- + +Page Title: Foundry + +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-foundry.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract/deploy-basic-foundry/ +- Summary: Learn how to deploy a basic smart contract to Polkadot Hub using Foundry, excellent for developers who prefer fast, command-line driven development. + +[Foundry](https://getfoundry.sh/){target=\_blank} offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +### Setup + +Install Foundry: + +```bash +curl -L https://foundry.paradigm.xyz | bash +foundryup +``` + +Initialize your project: + +```bash +forge init foundry-deployment +cd foundry-deployment +``` + +### Configure Foundry + +Edit `foundry.toml`: + +```toml +[profile.default] +src = "src" +out = "out" +libs = ["lib"] + +[rpc_endpoints] +polkadot_hub_testnet = "https://testnet-passet-hub-eth-rpc.polkadot.io" +``` + +### Create Your Contract + +Replace the default contract in `src/Storage.sol`: + +```solidity title="src/Storage.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +### Compile + +```bash +forge build +``` + +Verify the compilation by inspecting the bytecode: + +```bash +forge inspect Storage bytecode +``` + +### Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +forge create Storage \ + --rpc-url polkadot_hub_testnet \ + --private-key YOUR_PRIVATE_KEY \ + --broadcast +``` + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). + + +--- + +Page Title: Foundry + +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-foundry.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract-evm/deploy-basic-foundry/ +- Summary: Learn how to deploy a basic smart contract to Polkadot Hub using Foundry, excellent for developers who prefer fast, command-line driven development. + +[Foundry](https://getfoundry.sh/){target=\_blank} offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +### Setup + +Install Foundry: + +```bash +curl -L https://foundry.paradigm.xyz | bash +foundryup +``` + +Initialize your project: + +```bash +forge init foundry-deployment +cd foundry-deployment +``` + +### Configure Foundry -## XCM Testing +Edit `foundry.toml`: -To test XCM (Cross-Consensus Messaging) messages between networks, you can fork multiple parachains and a relay chain locally using Chopsticks. +```toml +[profile.default] +src = "src" +out = "out" +libs = ["lib"] -- **`relaychain`**: Relay chain config file. -- **`parachain`**: Parachain config file. +[rpc_endpoints] +polkadot_hub_testnet = "https://testnet-passet-hub-eth-rpc.polkadot.io" +``` -For example, to fork Moonbeam, Astar, and Polkadot enabling XCM between them, you can use the following command: +### Create Your Contract + +Replace the default contract in `src/Storage.sol`: + +```solidity title="src/Storage.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +### Compile ```bash -npx @acala-network/chopsticks xcm \ ---r polkadot \ ---p moonbeam \ ---p astar +forge build ``` -After running it, you should see output similar to the following: +Verify the compilation by inspecting the bytecode: -
- npx @acala-network/chopsticks xcm \ - --r polkadot \ - --p moonbeam \ - --p astar -
- [13:46:07.901] INFO: Loading config file https://raw.githubusercontent.com/AcalaNetwork/chopsticks/master/configs/moonbeam.yml - app: "chopsticks" - [13:46:12.631] INFO: Moonbeam RPC listening on port 8000 - app: "chopsticks" - [13:46:12.632] INFO: Loading config file https://raw.githubusercontent.com/AcalaNetwork/chopsticks/master/configs/astar.yml - app: "chopsticks" - chopsticks::executor TRACE: Calling Metadata_metadata - chopsticks::executor TRACE: Completed Metadata_metadata - [13:46:23.669] INFO: Astar RPC listening on port 8001 - app: "chopsticks" - [13:46:25.144] INFO (xcm): Connected parachains [2004,2006] - app: "chopsticks" - [13:46:25.144] INFO: Loading config file https://raw.githubusercontent.com/AcalaNetwork/chopsticks/master/configs/polkadot.yml - app: "chopsticks" - chopsticks::executor TRACE: Calling Metadata_metadata - chopsticks::executor TRACE: Completed Metadata_metadata - [13:46:53.320] INFO: Polkadot RPC listening on port 8002 - app: "chopsticks" - [13:46:54.038] INFO (xcm): Connected relaychain 'Polkadot' with parachain 'Moonbeam' - app: "chopsticks" - [13:46:55.028] INFO (xcm): Connected relaychain 'Polkadot' with parachain 'Astar' - app: "chopsticks" -
+```bash +forge inspect Storage bytecode +``` -Now you can interact with your forked chains using the ports specified in the output. +### Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +forge create Storage \ + --rpc-url polkadot_hub_testnet \ + --private-key YOUR_PRIVATE_KEY \ + --broadcast +``` + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). --- @@ -5077,32 +7355,306 @@ In Polkadot SDK-based blockchains, state is stored in a trie data structure that ## Validator -A validator is a node that participates in the consensus mechanism of the network. Its roles include block production, transaction validation, network integrity, and security maintenance. +A validator is a node that participates in the consensus mechanism of the network. Its roles include block production, transaction validation, network integrity, and security maintenance. + +## WebAssembly (Wasm) + +An execution architecture that allows for the efficient, platform-neutral expression of +deterministic, machine-executable logic. + +[Wasm](https://webassembly.org/){target=\_blank} can be compiled from many languages, including +the [Rust](https://www.rust-lang.org/){target=\_blank} programming language. Polkadot SDK-based chains use a Wasm binary to provide portable [runtimes](#runtime) that can be included as part of the chain's state. + +## Weight + +A convention used in Polkadot SDK-based blockchains to measure and manage the time it takes to validate a block. +Polkadot SDK defines one unit of weight as one picosecond of execution time on reference hardware. + +The maximum block weight should be equivalent to one-third of the target block time with an allocation of one-third each for: + +- Block construction +- Network propagation +- Import and verification + +By defining weights, you can trade-off the number of transactions per second and the hardware required to maintain the target block time appropriate for your use case. Weights are defined in the runtime, meaning you can tune them using runtime updates to keep up with hardware and software improvements. + +## Westend + +Westend is a Parity-maintained, Polkadot SDK-based blockchain that serves as a test network for the [Polkadot](#polkadot) network. + + +--- + +Page Title: hardhat + +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-hardhat.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract/deploy-basic-hardhat/ +- Summary: Learn how to deploy a basic smart contract to Polkadot Hub using Hardhat, Perfect for professional workflows requiring comprehensive testing and debugging. + +[Hardhat](https://hardhat.org/){target=\_blank} provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +### Setup + +Initialize your Hardhat project: + +```bash +mkdir hardhat-deployment +cd hardhat-deployment +npx hardhat --init +``` + +### Configure Hardhat + +Edit `hardhat.config.js`: + +```javascript title="hardhat.config.js" hl_lines="39-43" +import type { HardhatUserConfig } from "hardhat/config"; + +import hardhatToolboxViemPlugin from "@nomicfoundation/hardhat-toolbox-viem"; +import { configVariable } from "hardhat/config"; + +const config: HardhatUserConfig = { + plugins: [hardhatToolboxViemPlugin], + solidity: { + profiles: { + default: { + version: "0.8.28", + }, + production: { + version: "0.8.28", + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, + }, + }, + }, + networks: { + hardhatMainnet: { + type: "edr-simulated", + chainType: "l1", + }, + hardhatOp: { + type: "edr-simulated", + chainType: "op", + }, + sepolia: { + type: "http", + chainType: "l1", + url: configVariable("SEPOLIA_RPC_URL"), + accounts: [configVariable("SEPOLIA_PRIVATE_KEY")], + }, + polkadotHubTestnet: { + url: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + accounts: [configVariable("PRIVATE_KEY")], + }, + }, +}; + +export default config; + +``` + +### Create Your Contract + +Replace the default contract in `contracts/Storage.sol`: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +### Compile + +```bash +npx hardhat build +``` + +### Set Up Deployment + +Create a deployment module in `ignition/modules/Storage.ts`: + +```typescript title="ignition/modules/Storage.ts" +import { buildModule } from '@nomicfoundation/hardhat-ignition/modules'; + +export default buildModule('StorageModule', (m) => { + const storage = m.contract('Storage'); + return { storage }; +}); +``` + +### Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +npx hardhat ignition deploy ignition/modules/Storage.ts --network polkadotHubTestnet +``` + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). + + +--- + +Page Title: hardhat + +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-hardhat.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract-evm/deploy-basic-hardhat/ +- Summary: Learn how to deploy a basic smart contract to Polkadot Hub using Hardhat, Perfect for professional workflows requiring comprehensive testing and debugging. + +[Hardhat](https://hardhat.org/){target=\_blank} provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +### Setup + +Initialize your Hardhat project: + +```bash +mkdir hardhat-deployment +cd hardhat-deployment +npx hardhat --init +``` + +### Configure Hardhat + +Edit `hardhat.config.js`: + +```javascript title="hardhat.config.js" hl_lines="39-43" +import type { HardhatUserConfig } from "hardhat/config"; + +import hardhatToolboxViemPlugin from "@nomicfoundation/hardhat-toolbox-viem"; +import { configVariable } from "hardhat/config"; + +const config: HardhatUserConfig = { + plugins: [hardhatToolboxViemPlugin], + solidity: { + profiles: { + default: { + version: "0.8.28", + }, + production: { + version: "0.8.28", + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, + }, + }, + }, + networks: { + hardhatMainnet: { + type: "edr-simulated", + chainType: "l1", + }, + hardhatOp: { + type: "edr-simulated", + chainType: "op", + }, + sepolia: { + type: "http", + chainType: "l1", + url: configVariable("SEPOLIA_RPC_URL"), + accounts: [configVariable("SEPOLIA_PRIVATE_KEY")], + }, + polkadotHubTestnet: { + url: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + accounts: [configVariable("PRIVATE_KEY")], + }, + }, +}; + +export default config; + +``` + +### Create Your Contract + +Replace the default contract in `contracts/Storage.sol`: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +### Compile -## WebAssembly (Wasm) +```bash +npx hardhat build +``` -An execution architecture that allows for the efficient, platform-neutral expression of -deterministic, machine-executable logic. +### Set Up Deployment -[Wasm](https://webassembly.org/){target=\_blank} can be compiled from many languages, including -the [Rust](https://www.rust-lang.org/){target=\_blank} programming language. Polkadot SDK-based chains use a Wasm binary to provide portable [runtimes](#runtime) that can be included as part of the chain's state. +Create a deployment module in `ignition/modules/Storage.ts`: -## Weight +```typescript title="ignition/modules/Storage.ts" +import { buildModule } from '@nomicfoundation/hardhat-ignition/modules'; -A convention used in Polkadot SDK-based blockchains to measure and manage the time it takes to validate a block. -Polkadot SDK defines one unit of weight as one picosecond of execution time on reference hardware. +export default buildModule('StorageModule', (m) => { + const storage = m.contract('Storage'); + return { storage }; +}); +``` -The maximum block weight should be equivalent to one-third of the target block time with an allocation of one-third each for: +### Deploy -- Block construction -- Network propagation -- Import and verification +Deploy to Polkadot Hub TestNet: -By defining weights, you can trade-off the number of transactions per second and the hardware required to maintain the target block time appropriate for your use case. Weights are defined in the runtime, meaning you can tune them using runtime updates to keep up with hardware and software improvements. +```bash +npx hardhat ignition deploy ignition/modules/Storage.ts --network polkadotHubTestnet +``` -## Westend +### Next Steps -Westend is a Parity-maintained, Polkadot SDK-based blockchain that serves as a test network for the [Polkadot](#polkadot) network. +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). --- @@ -5972,313 +8524,797 @@ The interface defines a `Weight` struct that represents the computational cost o - **`refTime`**: Computational time on reference hardware. - **`proofSize`**: The size of the proof required for execution. -All XCM messages must be encoded using the [SCALE codec](/reference/parachains/data-encoding/#data-encoding){target=\_blank}, Polkadot's standard serialization format. +All XCM messages must be encoded using the [SCALE codec](/reference/parachains/data-encoding/#data-encoding){target=\_blank}, Polkadot's standard serialization format. + +For further information, check the [`precompiles/IXCM.sol`](https://github.com/paritytech/polkadot-sdk/blob/cb629d46ebf00aa65624013a61f9c69ebf02b0b4/polkadot/xcm/pallet-xcm/src/precompiles/IXcm.sol){target=\_blank} file present in `pallet-xcm`. + +## Interact with the XCM Precompile + +To interact with the XCM precompile, you can use the precompile interface directly in [Remix IDE](/smart-contracts/dev-environments/remix/get-started/){target=\_blank}: + +1. Create a new file called `IXcm.sol` in Remix. +2. Copy and paste the `IXcm` interface code into the file. +3. Compile the interface by selecting the button or using **Ctrl +S** keys: + + ![](/images/smart-contracts/precompiles/xcm/xcm-01.webp) + +4. In the **Deploy & Run Transactions** tab, select the `IXcm` interface from the contract dropdown. +5. Enter the precompile address `0x00000000000000000000000000000000000a0000` in the **At Address** input field. +6. Select the **At Address** button to connect to the precompile. + + ![](/images/smart-contracts/precompiles/xcm/xcm-02.webp) + +7. Once connected, you can use the Remix interface to interact with the XCM precompile's `execute`, `send`, and `weighMessage` functions. + + ![](/images/smart-contracts/precompiles/xcm/xcm-03.webp) + +The main entrypoint of the precompile is the `execute` function. However, it's necessary to first call `weighMessage` to fill in the required parameters. + +### Weigh a Message + +The `weighMessage` function estimates the computational cost required to execute an XCM message. This estimate is crucial for understanding the resources needed before actually executing or sending a message. + +To test this functionality in Remix, you can call `callWeighMessage` with a SCALE-encoded XCM message. For example, for testing, you can use the following encoded XCM message: + +```text title="encoded-xcm-message-example" +0x050c000401000003008c86471301000003008c8647000d010101000000010100368e8759910dab756d344995f1d3c79374ca8f70066d3a709e48029f6bf0ee7e +``` + +![](/images/smart-contracts/precompiles/xcm/xcm-04.webp) + +This encoded message represents a sequence of XCM instructions: + +- **[Withdraw Asset](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#withdrawasset){target=\_blank}**: This instruction removes assets from the local chain's sovereign account or the caller's account, making them available for use in subsequent XCM instructions. +- **[Buy Execution](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#buyexecution){target=\_blank}**: This instruction purchases execution time on the destination chain using the withdrawn assets, ensuring the message can be processed. +- **[Deposit Asset](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#depositasset){target=\_blank}**: This instruction deposits the remaining assets into a specified account on the destination chain after execution costs have been deducted. + +This encoded message is provided as an example. You can craft your own XCM message tailored to your specific use case as needed. + +The function returns a `Weight` struct containing `refTime` and `proofSize` values, which indicate the estimated computational cost of executing this message. If successful, after calling the `callWeighMessage` function, you should see the `refTime` and `proofSize` of the message: + +![](/images/smart-contracts/precompiles/xcm/xcm-05.webp) + +!!!note + You can find many more examples of XCMs in this [gist](https://gist.github.com/franciscoaguirre/a6dea0c55e81faba65bedf700033a1a2){target=\_blank}, which connects to the Polkadot Hub TestNet. + +### Execute a Message + +The `execute` function runs an XCM message locally using the caller's origin. +This function is the main entrypoint to cross-chain interactions. + +Follow these steps to execute a message: + +1. Call `weighMessage` with your message to get the required weight. +2. Pass the same message bytes and the weight obtained from the previous step to `execute`. +For example, using the same message from the weighing example, you would call `execute` with: + + - **`message`**: The encoded XCM message bytes. + - **`weight`**: The `Weight` struct returned from `weighMessage`. + + You can use the [papi console](https://dev.papi.how/extrinsics#networkId=localhost&endpoint=wss%3A%2F%2Ftestnet-passet-hub.polkadot.io&data=0x1f03050c000401000003008c86471301000003008c8647000d010101000000010100368e8759910dab756d344995f1d3c79374ca8f70066d3a709e48029f6bf0ee7e0750c61e2901daad0600){target=\_blank} to examine the complete extrinsic structure for this operation. + +3. On Remix, click on the **Transact** button to execute the XCM message: + + ![](/images/smart-contracts/precompiles/xcm/xcm-06.webp) + + If successful, you will see the following output in the Remix terminal: + + ![](/images/smart-contracts/precompiles/xcm/xcm-07.webp) + +Additionally, you can verify that the execution of this specific message was successful by checking that the beneficiary account associated with the XCM message has received the funds accordingly. + +### Send a Message + +While most cross-chain operations can be performed via `execute`, `send` is sometimes necessary, for example, when opening HRMP channels. + +To send a message: + +1. Prepare your destination location encoded in XCM format. +2. Prepare your XCM message (similar to the execute example). +3. Call `send` with both parameters. + +The destination parameter must be encoded according to XCM's location format, specifying the target parachain or consensus system. The message parameter contains the XCM instructions to be executed on the destination chain. + +Unlike `execute`, the `send` function doesn't require a weight parameter since the destination chain will handle execution costs according to its fee structure. + +## Cross Contract Calls + +Beyond direct interaction and wrapper contracts, you can integrate XCM functionality directly into your existing smart contracts by inheriting from or importing the `IXcm` interface. This approach enables you to embed cross-chain capabilities into your application logic seamlessly. + +Whether you're building DeFi protocols, governance systems, or any application requiring cross-chain coordination, you can incorporate XCM calls directly within your contract's functions. + +## Conclusion + +The XCM precompile provides a simple yet powerful interface for cross-chain interactions within the Polkadot ecosystem and beyond. +By building and executing XCM programs, developers can build cross-chain applications that leverage the full potential of Polkadot's interoperability features. + +## Next Steps + +Head to the Polkadot Hub TestNet and start playing around with the precompile using [Hardhat](/smart-contracts/dev-environments/hardhat/get-started/){target=\_blank} or [Foundry](/smart-contracts/dev-environments/foundry/get-started/){target=\_blank}. + +You can use PAPI to build XCM programs and test them with Chopsticks. + + +--- + +Page Title: Interoperability + +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-interoperability.md +- Canonical (HTML): https://docs.polkadot.com/reference/parachains/interoperability/ +- Summary: Explore the importance of interoperability in the Polkadot ecosystem, covering XCM, bridges, and cross-chain communication. + +# Interoperability + +## Introduction + +Interoperability lies at the heart of the Polkadot ecosystem, enabling communication and collaboration across a diverse range of blockchains. By bridging the gaps between parachains, relay chains, and even external networks, Polkadot unlocks the potential for truly decentralized applications, efficient resource sharing, and scalable solutions. + +Polkadot’s design ensures that blockchains can transcend their individual limitations by working together as part of a unified system. This cooperative architecture is what sets Polkadot apart in the blockchain landscape. + +## Why Interoperability Matters + +The blockchain ecosystem is inherently fragmented. Different blockchains excel in specialized domains such as finance, gaming, or supply chain management, but these chains function in isolation without interoperability. This lack of connectivity stifles the broader utility of blockchain technology. + +Interoperability solves this problem by enabling blockchains to: + +- **Collaborate across networks**: Chains can interact to share assets, functionality, and data, creating synergies that amplify their individual strengths. +- **Achieve greater scalability**: Specialized chains can offload tasks to others, optimizing performance and resource utilization. +- **Expand use-case potential**: Cross-chain applications can leverage features from multiple blockchains, unlocking novel user experiences and solutions. + +In the Polkadot ecosystem, interoperability transforms a collection of isolated chains into a cohesive, efficient network, pushing the boundaries of what blockchains can achieve together. + +## Key Mechanisms for Interoperability + +At the core of Polkadot's cross-chain collaboration are foundational technologies designed to break down barriers between networks. These mechanisms empower blockchains to communicate, share resources, and operate as a cohesive ecosystem. + +### Cross-Consensus Messaging (XCM): The Backbone of Communication + +Polkadot's Cross-Consensus Messaging (XCM) is the standard framework for interaction between parachains, relay chains, and, eventually, external blockchains. XCM provides a trustless, secure messaging format for exchanging assets, sharing data, and executing cross-chain operations. + +Through XCM, decentralized applications can: + +- Transfer tokens and other assets across chains. +- Coordinate complex workflows that span multiple blockchains. +- Enable seamless user experiences where underlying blockchain differences are invisible. +- XCM exemplifies Polkadot’s commitment to creating a robust and interoperable ecosystem. + +For further information about XCM, check the [Introduction to XCM](/parachains/interoperability/get-started/){target=\_blank} article. + +### Bridges: Connecting External Networks + +While XCM enables interoperability within the Polkadot ecosystem, bridges extend this functionality to external blockchains such as Ethereum and Bitcoin. By connecting these networks, bridges allow Polkadot-based chains to access external liquidity, additional functionalities, and broader user bases. + +With bridges, developers and users gain the ability to: + +- Integrate external assets into Polkadot-based applications. +- Combine the strengths of Polkadot’s scalability with the liquidity of other networks. +- Facilitate accurate multi-chain applications that transcend ecosystem boundaries. + +For more information about bridges in the Polkadot ecosystem, see the [Bridge Hub](/reference/polkadot-hub/bridging/){target=\_blank} guide. + +## The Polkadot Advantage + +Polkadot was purpose-built for interoperability. Unlike networks that add interoperability as an afterthought, Polkadot integrates it as a fundamental design principle. This approach offers several distinct advantages: + +- **Developer empowerment**: Polkadot’s interoperability tools allow developers to build applications that leverage multiple chains’ capabilities without added complexity. +- **Enhanced ecosystem collaboration**: Chains in Polkadot can focus on their unique strengths while contributing to the ecosystem’s overall growth. +- **Future-proofing blockchain**: By enabling seamless communication, Polkadot ensures its ecosystem can adapt to evolving demands and technologies. + +## Looking Ahead + +Polkadot’s vision of interoperability extends beyond technical functionality, representing a shift towards a more collaborative blockchain landscape. By enabling chains to work together, Polkadot fosters innovation, efficiency, and accessibility, paving the way for a decentralized future where blockchains are not isolated competitors but interconnected collaborators. + + +--- + +Page Title: Introduction to XCM + +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-interoperability-get-started.md +- Canonical (HTML): https://docs.polkadot.com/parachains/interoperability/get-started/ +- Summary: Unlock blockchain interoperability with XCM — Polkadot's Cross-Consensus Messaging format for cross-chain interactions. + +# Introduction to XCM + +## Introduction + +Polkadot’s unique value lies in its ability to enable interoperability between parachains and other blockchain systems. At the core of this capability is XCM (Cross-Consensus Messaging)—a flexible messaging format that facilitates communication and collaboration between independent consensus systems. + +With XCM, one chain can send intents to another one, fostering a more interconnected ecosystem. Although it was developed specifically for Polkadot, XCM is a universal format, usable in any blockchain environment. This guide provides an overview of XCM’s core principles, design, and functionality, alongside practical examples of its implementation. + +## Messaging Format + +XCM is not a protocol but a standardized [messaging format](https://github.com/polkadot-fellows/xcm-format){target=\_blank}. It defines the structure and behavior of messages but does not handle their delivery. This separation allows developers to focus on crafting instructions for target systems without worrying about transmission mechanics. + +XCM messages are intent-driven, outlining desired actions for the receiving blockchain to consider and potentially alter its state. These messages do not directly execute changes; instead, they rely on the host chain's environment to interpret and implement them. By utilizing asynchronous composability, XCM facilitates efficient execution where messages can be processed independently of their original order, similar to how RESTful services handle HTTP requests without requiring sequential processing. + +## The Four Principles of XCM + +XCM adheres to four guiding principles that ensure robust and reliable communication across consensus systems: + +- **Asynchronous**: XCM messages operate independently of sender acknowledgment, avoiding delays due to blocked processes. +- **Absolute**: XCM messages are guaranteed to be delivered and interpreted accurately, in order, and timely. Once a message is sent, one can be sure it will be processed as intended. +- **Asymmetric**: XCM messages follow the 'fire and forget' paradigm meaning no automatic feedback is provided to the sender. Any results must be communicated separately to the sender with an additional message back to the origin. +- **Agnostic**: XCM operates independently of the specific consensus mechanisms, making it compatible across diverse systems. + +These principles guarantee that XCM provides a reliable framework for cross-chain communication, even in complex environments. + +## The XCM Tech Stack + +![Diagram of the XCM tech stack](/images/parachains/interoperability/get-started/intro-to-xcm-01.webp) + +The XCM tech stack is designed to facilitate seamless interoperable communication between chains that reside within the Polkadot ecosystem. XCM can be used to express the meaning of the messages over each of the communication channels. + +## Core Functionalities of XCM + +XCM enhances cross-consensus communication by introducing several powerful features: + +- **Programmability**: Supports dynamic message handling, allowing for more comprehensive use cases. Includes branching logic, safe dispatches for version checks, and asset operations like NFT management. +- **Functional Multichain Decomposition**: Enables mechanisms such as remote asset locking, asset namespacing, and inter-chain state referencing, with contextual message identification. +- **Bridging**: Establishes a universal reference framework for multi-hop setups, connecting disparate systems like Ethereum and Bitcoin with the Polkadot relay chain acting as a universal location. + +The standardized format for messages allows parachains to handle tasks like user balances, governance, and staking, freeing the Polkadot relay chain to focus on shared security. These features make XCM indispensable for implementing scalable and interoperable blockchain applications. + +## XCM Example + +The following is a simplified XCM message demonstrating a token transfer from Alice to Bob on the same chain (ParaA). -For further information, check the [`precompiles/IXCM.sol`](https://github.com/paritytech/polkadot-sdk/blob/cb629d46ebf00aa65624013a61f9c69ebf02b0b4/polkadot/xcm/pallet-xcm/src/precompiles/IXcm.sol){target=\_blank} file present in `pallet-xcm`. +```rust +let message = Xcm(vec![ + WithdrawAsset((Here, amount).into()), + BuyExecution { + fees: (Here, amount).into(), + weight_limit: WeightLimit::Unlimited + }, + DepositAsset { + assets: All.into(), + beneficiary: MultiLocation { + parents: 0, + interior: Junction::AccountId32 { + network: None, + id: BOB.clone().into() + }.into(), + }.into() + } +]); +``` -## Interact with the XCM Precompile +The message consists of three instructions described as follows: -To interact with the XCM precompile, you can use the precompile interface directly in [Remix IDE](/smart-contracts/dev-environments/remix/get-started/){target=\_blank}: +- **[WithdrawAsset](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#withdrawasset){target=\_blank}**: Transfers a specified number of tokens from Alice's account to a holding register. -1. Create a new file called `IXcm.sol` in Remix. -2. Copy and paste the `IXcm` interface code into the file. -3. Compile the interface by selecting the button or using **Ctrl +S** keys: + ```rust + WithdrawAsset((Here, amount).into()), + ``` - ![](/images/smart-contracts/precompiles/xcm/xcm-01.webp) + - **`Here`**: The native parachain token. + - **`amount`**: The number of tokens that are transferred. -4. In the **Deploy & Run Transactions** tab, select the `IXcm` interface from the contract dropdown. -5. Enter the precompile address `0x00000000000000000000000000000000000a0000` in the **At Address** input field. -6. Select the **At Address** button to connect to the precompile. + The first instruction takes as an input the MultiAsset that should be withdrawn. The MultiAsset describes the native parachain token with the `Here` keyword. The `amount` parameter is the number of tokens that are transferred. The withdrawal account depends on the origin of the message. In this example the origin of the message is Alice. The `WithdrawAsset` instruction moves `amount` number of native tokens from Alice's account into the holding register. - ![](/images/smart-contracts/precompiles/xcm/xcm-02.webp) +- **[BuyExecution](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#buyexecution){target=\_blank}**: Allocates fees to cover the execution [weight](/reference/glossary/#weight){target=\_blank} of the XCM instructions. -7. Once connected, you can use the Remix interface to interact with the XCM precompile's `execute`, `send`, and `weighMessage` functions. + ```rust + BuyExecution { + fees: (Here, amount).into(), + weight_limit: WeightLimit::Unlimited + }, + ``` - ![](/images/smart-contracts/precompiles/xcm/xcm-03.webp) + - **`fees`**: Describes the asset in the holding register that should be used to pay for the weight. + - **`weight_limit`**: Defines the maximum fees that can be used to buy weight. -The main entrypoint of the precompile is the `execute` function. However, it's necessary to first call `weighMessage` to fill in the required parameters. +- **[DepositAsset](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#depositasset){target=\_blank}**: Moves the remaining tokens from the holding register to Bob’s account. -### Weigh a Message + ```rust + DepositAsset { + assets: All.into(), + beneficiary: MultiLocation { + parents: 0, + interior: Junction::AccountId32 { + network: None, + id: BOB.clone().into() + }.into(), + }.into() + } + ``` -The `weighMessage` function estimates the computational cost required to execute an XCM message. This estimate is crucial for understanding the resources needed before actually executing or sending a message. + - **`All`**: The wildcard for the asset(s) to be deposited. In this case, all assets in the holding register should be deposited. + +This step-by-step process showcases how XCM enables precise state changes within a blockchain system. You can find a complete XCM message example in the [XCM repository](https://github.com/paritytech/xcm-docs/blob/main/examples/src/0_first_look/mod.rs){target=\_blank}. -To test this functionality in Remix, you can call `callWeighMessage` with a SCALE-encoded XCM message. For example, for testing, you can use the following encoded XCM message: +## Overview -```text title="encoded-xcm-message-example" -0x050c000401000003008c86471301000003008c8647000d010101000000010100368e8759910dab756d344995f1d3c79374ca8f70066d3a709e48029f6bf0ee7e -``` +XCM revolutionizes cross-chain communication by enabling use cases such as: -![](/images/smart-contracts/precompiles/xcm/xcm-04.webp) +- Token transfers between blockchains. +- Asset locking for cross-chain smart contract interactions. +- Remote execution of functions on other blockchains. -This encoded message represents a sequence of XCM instructions: +These functionalities empower developers to build innovative, multi-chain applications, leveraging the strengths of various blockchain networks. To stay updated on XCM’s evolving format or contribute, visit the [XCM repository](https://github.com/paritytech/xcm-docs/blob/main/examples/src/0_first_look/mod.rs){target=\_blank}. -- **[Withdraw Asset](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#withdrawasset){target=\_blank}**: This instruction removes assets from the local chain's sovereign account or the caller's account, making them available for use in subsequent XCM instructions. -- **[Buy Execution](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#buyexecution){target=\_blank}**: This instruction purchases execution time on the destination chain using the withdrawn assets, ensuring the message can be processed. -- **[Deposit Asset](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#depositasset){target=\_blank}**: This instruction deposits the remaining assets into a specified account on the destination chain after execution costs have been deducted. -This encoded message is provided as an example. You can craft your own XCM message tailored to your specific use case as needed. +--- -The function returns a `Weight` struct containing `refTime` and `proofSize` values, which indicate the estimated computational cost of executing this message. If successful, after calling the `callWeighMessage` function, you should see the `refTime` and `proofSize` of the message: +Page Title: JavaScript with Ethers.js -![](/images/smart-contracts/precompiles/xcm/xcm-05.webp) +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-ethers-js.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract/deploy-basic-ethers-js/ +- Summary: Learn how to deploy a basic smart contract to Polkadot Hub using Ethers.js, best for lightweight, programmatic deployments and application integration. -!!!note - You can find many more examples of XCMs in this [gist](https://gist.github.com/franciscoaguirre/a6dea0c55e81faba65bedf700033a1a2){target=\_blank}, which connects to the Polkadot Hub TestNet. +[Ethers.js](https://docs.ethers.org/v6/){target=\_blank} provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications. -### Execute a Message +**Prerequisites:** -The `execute` function runs an XCM message locally using the caller's origin. -This function is the main entrypoint to cross-chain interactions. +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. -Follow these steps to execute a message: +### Setup -1. Call `weighMessage` with your message to get the required weight. -2. Pass the same message bytes and the weight obtained from the previous step to `execute`. -For example, using the same message from the weighing example, you would call `execute` with: +First, initialize your project and install dependencies: - - **`message`**: The encoded XCM message bytes. - - **`weight`**: The `Weight` struct returned from `weighMessage`. +```bash +mkdir ethers-deployment +cd ethers-deployment +npm init -y +npm install ethers@6.15.0 solc@0.8.30 +``` - You can use the [papi console](https://dev.papi.how/extrinsics#networkId=localhost&endpoint=wss%3A%2F%2Ftestnet-passet-hub.polkadot.io&data=0x1f03050c000401000003008c86471301000003008c8647000d010101000000010100368e8759910dab756d344995f1d3c79374ca8f70066d3a709e48029f6bf0ee7e0750c61e2901daad0600){target=\_blank} to examine the complete extrinsic structure for this operation. +### Create and Compile Your Contract -3. On Remix, click on the **Transact** button to execute the XCM message: - - ![](/images/smart-contracts/precompiles/xcm/xcm-06.webp) +Create a simple storage contract in `contracts/Storage.sol`: - If successful, you will see the following output in the Remix terminal: +```solidity title="contracts/Storage.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; - ![](/images/smart-contracts/precompiles/xcm/xcm-07.webp) +contract Storage { + uint256 private storedNumber; -Additionally, you can verify that the execution of this specific message was successful by checking that the beneficiary account associated with the XCM message has received the funds accordingly. + function store(uint256 num) public { + storedNumber = num; + } -### Send a Message + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` -While most cross-chain operations can be performed via `execute`, `send` is sometimes necessary, for example, when opening HRMP channels. +Create a compilation script `compile.js`: -To send a message: +```javascript title="compile.js" +const solc = require('solc'); +const { readFileSync, writeFileSync } = require('fs'); +const { basename, join } = require('path'); -1. Prepare your destination location encoded in XCM format. -2. Prepare your XCM message (similar to the execute example). -3. Call `send` with both parameters. +const compileContract = async (solidityFilePath, outputDir) => { + try { + // Read the Solidity file + const source = readFileSync(solidityFilePath, 'utf8'); -The destination parameter must be encoded according to XCM's location format, specifying the target parachain or consensus system. The message parameter contains the XCM instructions to be executed on the destination chain. + // Construct the input object for the compiler + const input = { + language: 'Solidity', + sources: { + [basename(solidityFilePath)]: { content: source }, + }, + settings: { + outputSelection: { + '*': { + '*': ['*'], + }, + }, + }, + }; -Unlike `execute`, the `send` function doesn't require a weight parameter since the destination chain will handle execution costs according to its fee structure. + console.log(`Compiling contract: ${basename(solidityFilePath)}...`); -## Cross Contract Calls + // Compile the contract + const output = JSON.parse(solc.compile(JSON.stringify(input))); -Beyond direct interaction and wrapper contracts, you can integrate XCM functionality directly into your existing smart contracts by inheriting from or importing the `IXcm` interface. This approach enables you to embed cross-chain capabilities into your application logic seamlessly. + if (output.errors) { + output.errors.forEach(error => { + console.error('Compilation error:', error.message); + }); + return; + } -Whether you're building DeFi protocols, governance systems, or any application requiring cross-chain coordination, you can incorporate XCM calls directly within your contract's functions. + for (const contracts of Object.values(output.contracts)) { + for (const [name, contract] of Object.entries(contracts)) { + console.log(`Compiled contract: ${name}`); -## Conclusion + // Write the ABI + const abiPath = join(outputDir, `${name}.json`); + writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2)); + console.log(`ABI saved to ${abiPath}`); -The XCM precompile provides a simple yet powerful interface for cross-chain interactions within the Polkadot ecosystem and beyond. -By building and executing XCM programs, developers can build cross-chain applications that leverage the full potential of Polkadot's interoperability features. + // Write the bytecode + const bytecodePath = join(outputDir, `${name}.bin`); + writeFileSync(bytecodePath, + Buffer.from( + contract.evm.bytecode.object, + 'hex' + )); + console.log(`Bytecode saved to ${bytecodePath}`); + } + } + } catch (error) { + console.error('Error compiling contracts:', error); + } +}; -## Next Steps +const solidityFilePath = join(__dirname, 'contracts/Storage.sol'); +const outputDir = join(__dirname, 'contracts'); -Head to the Polkadot Hub TestNet and start playing around with the precompile using [Hardhat](/smart-contracts/dev-environments/hardhat/get-started/){target=\_blank} or [Foundry](/smart-contracts/dev-environments/foundry/get-started/){target=\_blank}. +compileContract(solidityFilePath, outputDir); +``` -You can use PAPI to build XCM programs and test them with Chopsticks. +Run the compilation: +```bash +node compile.js +``` ---- +### Deploy the Contract -Page Title: Interoperability +Create a deployment script `deploy.js`: -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/reference-parachains-interoperability.md -- Canonical (HTML): https://docs.polkadot.com/reference/parachains/interoperability/ -- Summary: Explore the importance of interoperability in the Polkadot ecosystem, covering XCM, bridges, and cross-chain communication. +```javascript title="deploy.js" +const { writeFileSync, existsSync, readFileSync } = require('fs'); +const { join } = require('path'); +const { ethers, JsonRpcProvider } = require('ethers'); -# Interoperability +const codegenDir = join(__dirname); -## Introduction +// Creates a provider with specified RPC URL and chain details +const createProvider = (rpcUrl, chainId, chainName) => { + const provider = new JsonRpcProvider(rpcUrl, { + chainId: chainId, + name: chainName, + }); + return provider; +}; -Interoperability lies at the heart of the Polkadot ecosystem, enabling communication and collaboration across a diverse range of blockchains. By bridging the gaps between parachains, relay chains, and even external networks, Polkadot unlocks the potential for truly decentralized applications, efficient resource sharing, and scalable solutions. +// Reads and parses the ABI file for a given contract +const getAbi = (contractName) => { + try { + return JSON.parse( + readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'), + ); + } catch (error) { + console.error( + `Could not find ABI for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; -Polkadot’s design ensures that blockchains can transcend their individual limitations by working together as part of a unified system. This cooperative architecture is what sets Polkadot apart in the blockchain landscape. +// Reads the compiled bytecode for a given contract +const getByteCode = (contractName) => { + try { + const bytecodePath = join( + codegenDir, + 'contracts', + `${contractName}.bin`, + ); + return `0x${readFileSync(bytecodePath).toString('hex')}`; + } catch (error) { + console.error( + `Could not find bytecode for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; -## Why Interoperability Matters +const deployContract = async (contractName, mnemonic, providerConfig) => { + console.log(`Deploying ${contractName}...`); -The blockchain ecosystem is inherently fragmented. Different blockchains excel in specialized domains such as finance, gaming, or supply chain management, but these chains function in isolation without interoperability. This lack of connectivity stifles the broader utility of blockchain technology. + try { + // Step 1: Set up provider and wallet + const provider = createProvider( + providerConfig.rpc, + providerConfig.chainId, + providerConfig.name, + ); + const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic); + const wallet = walletMnemonic.connect(provider); + + // Step 2: Create and deploy the contract + const factory = new ethers.ContractFactory( + getAbi(contractName), + getByteCode(contractName), + wallet, + ); + const contract = await factory.deploy(); + await contract.waitForDeployment(); -Interoperability solves this problem by enabling blockchains to: + // Step 3: Save deployment information + const address = await contract.getAddress(); + console.log(`Contract ${contractName} deployed at: ${address}`); -- **Collaborate across networks**: Chains can interact to share assets, functionality, and data, creating synergies that amplify their individual strengths. -- **Achieve greater scalability**: Specialized chains can offload tasks to others, optimizing performance and resource utilization. -- **Expand use-case potential**: Cross-chain applications can leverage features from multiple blockchains, unlocking novel user experiences and solutions. + const addressesFile = join(codegenDir, 'contract-address.json'); + const addresses = existsSync(addressesFile) + ? JSON.parse(readFileSync(addressesFile, 'utf8')) + : {}; + addresses[contractName] = address; + writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8'); + } catch (error) { + console.error(`Failed to deploy contract ${contractName}:`, error); + } +}; -In the Polkadot ecosystem, interoperability transforms a collection of isolated chains into a cohesive, efficient network, pushing the boundaries of what blockchains can achieve together. +const providerConfig = { + rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + name: 'polkadot-hub-testnet', +}; -## Key Mechanisms for Interoperability +const mnemonic = 'INSERT_MNEMONIC'; -At the core of Polkadot's cross-chain collaboration are foundational technologies designed to break down barriers between networks. These mechanisms empower blockchains to communicate, share resources, and operate as a cohesive ecosystem. +deployContract('Storage', mnemonic, providerConfig); +``` -### Cross-Consensus Messaging (XCM): The Backbone of Communication +Replace the `INSERT_MNEMONIC` placeholder with your actual mnemonic. -Polkadot's Cross-Consensus Messaging (XCM) is the standard framework for interaction between parachains, relay chains, and, eventually, external blockchains. XCM provides a trustless, secure messaging format for exchanging assets, sharing data, and executing cross-chain operations. +Execute the deployment: -Through XCM, decentralized applications can: +```bash +node deploy.js +``` -- Transfer tokens and other assets across chains. -- Coordinate complex workflows that span multiple blockchains. -- Enable seamless user experiences where underlying blockchain differences are invisible. -- XCM exemplifies Polkadot’s commitment to creating a robust and interoperable ecosystem. +After running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions. -For further information about XCM, check the [Introduction to XCM](/parachains/interoperability/get-started/){target=\_blank} article. +### Next Steps -### Bridges: Connecting External Networks +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). -While XCM enables interoperability within the Polkadot ecosystem, bridges extend this functionality to external blockchains such as Ethereum and Bitcoin. By connecting these networks, bridges allow Polkadot-based chains to access external liquidity, additional functionalities, and broader user bases. -With bridges, developers and users gain the ability to: +--- + +Page Title: JavaScript with Ethers.js -- Integrate external assets into Polkadot-based applications. -- Combine the strengths of Polkadot’s scalability with the liquidity of other networks. -- Facilitate accurate multi-chain applications that transcend ecosystem boundaries. +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-ethers-js.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract-evm/deploy-basic-ethers-js/ +- Summary: Learn how to deploy a basic smart contract to Polkadot Hub using Ethers.js, best for lightweight, programmatic deployments and application integration. -For more information about bridges in the Polkadot ecosystem, see the [Bridge Hub](/reference/polkadot-hub/bridging/){target=\_blank} guide. +[Ethers.js](https://docs.ethers.org/v6/){target=\_blank} provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications. -## The Polkadot Advantage +**Prerequisites:** -Polkadot was purpose-built for interoperability. Unlike networks that add interoperability as an afterthought, Polkadot integrates it as a fundamental design principle. This approach offers several distinct advantages: +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. -- **Developer empowerment**: Polkadot’s interoperability tools allow developers to build applications that leverage multiple chains’ capabilities without added complexity. -- **Enhanced ecosystem collaboration**: Chains in Polkadot can focus on their unique strengths while contributing to the ecosystem’s overall growth. -- **Future-proofing blockchain**: By enabling seamless communication, Polkadot ensures its ecosystem can adapt to evolving demands and technologies. +### Setup -## Looking Ahead +First, initialize your project and install dependencies: -Polkadot’s vision of interoperability extends beyond technical functionality, representing a shift towards a more collaborative blockchain landscape. By enabling chains to work together, Polkadot fosters innovation, efficiency, and accessibility, paving the way for a decentralized future where blockchains are not isolated competitors but interconnected collaborators. +```bash +mkdir ethers-deployment +cd ethers-deployment +npm init -y +npm install ethers@6.15.0 solc@0.8.30 +``` +### Create and Compile Your Contract ---- +Create a simple storage contract in `contracts/Storage.sol`: -Page Title: Introduction to XCM +```solidity title="contracts/Storage.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; -- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/parachains-interoperability-get-started.md -- Canonical (HTML): https://docs.polkadot.com/parachains/interoperability/get-started/ -- Summary: Unlock blockchain interoperability with XCM — Polkadot's Cross-Consensus Messaging format for cross-chain interactions. +contract Storage { + uint256 private storedNumber; -# Introduction to XCM + function store(uint256 num) public { + storedNumber = num; + } -## Introduction + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` -Polkadot’s unique value lies in its ability to enable interoperability between parachains and other blockchain systems. At the core of this capability is XCM (Cross-Consensus Messaging)—a flexible messaging format that facilitates communication and collaboration between independent consensus systems. +Create a compilation script `compile.js`: -With XCM, one chain can send intents to another one, fostering a more interconnected ecosystem. Although it was developed specifically for Polkadot, XCM is a universal format, usable in any blockchain environment. This guide provides an overview of XCM’s core principles, design, and functionality, alongside practical examples of its implementation. +```javascript title="compile.js" +const solc = require('solc'); +const { readFileSync, writeFileSync } = require('fs'); +const { basename, join } = require('path'); -## Messaging Format +const compileContract = async (solidityFilePath, outputDir) => { + try { + // Read the Solidity file + const source = readFileSync(solidityFilePath, 'utf8'); -XCM is not a protocol but a standardized [messaging format](https://github.com/polkadot-fellows/xcm-format){target=\_blank}. It defines the structure and behavior of messages but does not handle their delivery. This separation allows developers to focus on crafting instructions for target systems without worrying about transmission mechanics. + // Construct the input object for the compiler + const input = { + language: 'Solidity', + sources: { + [basename(solidityFilePath)]: { content: source }, + }, + settings: { + outputSelection: { + '*': { + '*': ['*'], + }, + }, + }, + }; -XCM messages are intent-driven, outlining desired actions for the receiving blockchain to consider and potentially alter its state. These messages do not directly execute changes; instead, they rely on the host chain's environment to interpret and implement them. By utilizing asynchronous composability, XCM facilitates efficient execution where messages can be processed independently of their original order, similar to how RESTful services handle HTTP requests without requiring sequential processing. + console.log(`Compiling contract: ${basename(solidityFilePath)}...`); -## The Four Principles of XCM + // Compile the contract + const output = JSON.parse(solc.compile(JSON.stringify(input))); -XCM adheres to four guiding principles that ensure robust and reliable communication across consensus systems: + if (output.errors) { + output.errors.forEach(error => { + console.error('Compilation error:', error.message); + }); + return; + } -- **Asynchronous**: XCM messages operate independently of sender acknowledgment, avoiding delays due to blocked processes. -- **Absolute**: XCM messages are guaranteed to be delivered and interpreted accurately, in order, and timely. Once a message is sent, one can be sure it will be processed as intended. -- **Asymmetric**: XCM messages follow the 'fire and forget' paradigm meaning no automatic feedback is provided to the sender. Any results must be communicated separately to the sender with an additional message back to the origin. -- **Agnostic**: XCM operates independently of the specific consensus mechanisms, making it compatible across diverse systems. + for (const contracts of Object.values(output.contracts)) { + for (const [name, contract] of Object.entries(contracts)) { + console.log(`Compiled contract: ${name}`); -These principles guarantee that XCM provides a reliable framework for cross-chain communication, even in complex environments. + // Write the ABI + const abiPath = join(outputDir, `${name}.json`); + writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2)); + console.log(`ABI saved to ${abiPath}`); -## The XCM Tech Stack + // Write the bytecode + const bytecodePath = join(outputDir, `${name}.bin`); + writeFileSync(bytecodePath, + Buffer.from( + contract.evm.bytecode.object, + 'hex' + )); + console.log(`Bytecode saved to ${bytecodePath}`); + } + } + } catch (error) { + console.error('Error compiling contracts:', error); + } +}; -![Diagram of the XCM tech stack](/images/parachains/interoperability/get-started/intro-to-xcm-01.webp) +const solidityFilePath = join(__dirname, 'contracts/Storage.sol'); +const outputDir = join(__dirname, 'contracts'); -The XCM tech stack is designed to facilitate seamless interoperable communication between chains that reside within the Polkadot ecosystem. XCM can be used to express the meaning of the messages over each of the communication channels. +compileContract(solidityFilePath, outputDir); +``` -## Core Functionalities of XCM +Run the compilation: -XCM enhances cross-consensus communication by introducing several powerful features: +```bash +node compile.js +``` -- **Programmability**: Supports dynamic message handling, allowing for more comprehensive use cases. Includes branching logic, safe dispatches for version checks, and asset operations like NFT management. -- **Functional Multichain Decomposition**: Enables mechanisms such as remote asset locking, asset namespacing, and inter-chain state referencing, with contextual message identification. -- **Bridging**: Establishes a universal reference framework for multi-hop setups, connecting disparate systems like Ethereum and Bitcoin with the Polkadot relay chain acting as a universal location. +### Deploy the Contract -The standardized format for messages allows parachains to handle tasks like user balances, governance, and staking, freeing the Polkadot relay chain to focus on shared security. These features make XCM indispensable for implementing scalable and interoperable blockchain applications. +Create a deployment script `deploy.js`: -## XCM Example +```javascript title="deploy.js" +const { writeFileSync, existsSync, readFileSync } = require('fs'); +const { join } = require('path'); +const { ethers, JsonRpcProvider } = require('ethers'); -The following is a simplified XCM message demonstrating a token transfer from Alice to Bob on the same chain (ParaA). +const codegenDir = join(__dirname); -```rust -let message = Xcm(vec![ - WithdrawAsset((Here, amount).into()), - BuyExecution { - fees: (Here, amount).into(), - weight_limit: WeightLimit::Unlimited - }, - DepositAsset { - assets: All.into(), - beneficiary: MultiLocation { - parents: 0, - interior: Junction::AccountId32 { - network: None, - id: BOB.clone().into() - }.into(), - }.into() - } -]); -``` +// Creates a provider with specified RPC URL and chain details +const createProvider = (rpcUrl, chainId, chainName) => { + const provider = new JsonRpcProvider(rpcUrl, { + chainId: chainId, + name: chainName, + }); + return provider; +}; -The message consists of three instructions described as follows: +// Reads and parses the ABI file for a given contract +const getAbi = (contractName) => { + try { + return JSON.parse( + readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'), + ); + } catch (error) { + console.error( + `Could not find ABI for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; -- **[WithdrawAsset](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#withdrawasset){target=\_blank}**: Transfers a specified number of tokens from Alice's account to a holding register. +// Reads the compiled bytecode for a given contract +const getByteCode = (contractName) => { + try { + const bytecodePath = join( + codegenDir, + 'contracts', + `${contractName}.bin`, + ); + return `0x${readFileSync(bytecodePath).toString('hex')}`; + } catch (error) { + console.error( + `Could not find bytecode for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; - ```rust - WithdrawAsset((Here, amount).into()), - ``` +const deployContract = async (contractName, mnemonic, providerConfig) => { + console.log(`Deploying ${contractName}...`); - - **`Here`**: The native parachain token. - - **`amount`**: The number of tokens that are transferred. + try { + // Step 1: Set up provider and wallet + const provider = createProvider( + providerConfig.rpc, + providerConfig.chainId, + providerConfig.name, + ); + const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic); + const wallet = walletMnemonic.connect(provider); + + // Step 2: Create and deploy the contract + const factory = new ethers.ContractFactory( + getAbi(contractName), + getByteCode(contractName), + wallet, + ); + const contract = await factory.deploy(); + await contract.waitForDeployment(); - The first instruction takes as an input the MultiAsset that should be withdrawn. The MultiAsset describes the native parachain token with the `Here` keyword. The `amount` parameter is the number of tokens that are transferred. The withdrawal account depends on the origin of the message. In this example the origin of the message is Alice. The `WithdrawAsset` instruction moves `amount` number of native tokens from Alice's account into the holding register. + // Step 3: Save deployment information + const address = await contract.getAddress(); + console.log(`Contract ${contractName} deployed at: ${address}`); -- **[BuyExecution](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#buyexecution){target=\_blank}**: Allocates fees to cover the execution [weight](/reference/glossary/#weight){target=\_blank} of the XCM instructions. + const addressesFile = join(codegenDir, 'contract-address.json'); + const addresses = existsSync(addressesFile) + ? JSON.parse(readFileSync(addressesFile, 'utf8')) + : {}; + addresses[contractName] = address; + writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8'); + } catch (error) { + console.error(`Failed to deploy contract ${contractName}:`, error); + } +}; - ```rust - BuyExecution { - fees: (Here, amount).into(), - weight_limit: WeightLimit::Unlimited - }, - ``` +const providerConfig = { + rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + name: 'polkadot-hub-testnet', +}; - - **`fees`**: Describes the asset in the holding register that should be used to pay for the weight. - - **`weight_limit`**: Defines the maximum fees that can be used to buy weight. +const mnemonic = 'INSERT_MNEMONIC'; -- **[DepositAsset](https://github.com/polkadot-fellows/xcm-format?tab=readme-ov-file#depositasset){target=\_blank}**: Moves the remaining tokens from the holding register to Bob’s account. +deployContract('Storage', mnemonic, providerConfig); +``` - ```rust - DepositAsset { - assets: All.into(), - beneficiary: MultiLocation { - parents: 0, - interior: Junction::AccountId32 { - network: None, - id: BOB.clone().into() - }.into(), - }.into() - } - ``` +Replace the `INSERT_MNEMONIC` placeholder with your actual mnemonic. - - **`All`**: The wildcard for the asset(s) to be deposited. In this case, all assets in the holding register should be deposited. - -This step-by-step process showcases how XCM enables precise state changes within a blockchain system. You can find a complete XCM message example in the [XCM repository](https://github.com/paritytech/xcm-docs/blob/main/examples/src/0_first_look/mod.rs){target=\_blank}. +Execute the deployment: -## Overview +```bash +node deploy.js +``` -XCM revolutionizes cross-chain communication by enabling use cases such as: +After running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions. -- Token transfers between blockchains. -- Asset locking for cross-chain smart contract interactions. -- Remote execution of functions on other blockchains. +### Next Steps -These functionalities empower developers to build innovative, multi-chain applications, leveraging the strengths of various blockchain networks. To stay updated on XCM’s evolving format or contribute, visit the [XCM repository](https://github.com/paritytech/xcm-docs/blob/main/examples/src/0_first_look/mod.rs){target=\_blank}. +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). --- @@ -9764,6 +12800,110 @@ The above command will spawn a lazy fork of Polkadot Asset Hub with the latest b An Asset Hub instance is now running locally, and you can proceed with the asset registration process. Note that the local registration process does not differ from the live network process. Once you have a successful TestNet transaction, you can use the same steps to register the asset on MainNet. +--- + +Page Title: Remix IDE + +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-remix.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract/deploy-basic-remix/ +- Summary: Learn how to deploy a basic smart contract to Polkadot Hub using Remix IDE Ideal for rapid prototyping, learning, and visual development. + +[Remix IDE](https://remix.live/){target=\_blank} offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +### Access Remix + +Navigate to [https://remix.polkadot.io/](https://remix.polkadot.io/){target=\_blank} in your web browser. + +The interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file: + +![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-01.webp) + +### Compile + +1. To compile your contract: + 1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar. + 2. Click **Compile Storage.sol** or press `Ctrl+S`. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-02.webp) + +Compilation errors and warnings appear in the terminal panel at the bottom of the screen. + +### Deploy + +1. Navigate to the **Deploy & Run Transactions** tab. +2. Click the **Environment** dropdown and select **Injected Provider - MetaMask** (ensure your MetaMask wallet is connected to Polkadot Hub TestNet). +3. Click **Deploy**. +4. Approve the transaction in your MetaMask wallet. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-03.webp) + +Your deployed contract will appear in the **Deployed Contracts** section, ready for interaction. + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). + + +--- + +Page Title: Remix IDE + +- Source (raw): https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-remix.md +- Canonical (HTML): https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract-evm/deploy-basic-remix/ +- Summary: Learn how to deploy a basic smart contract to Polkadot Hub using Remix IDE Ideal for rapid prototyping, learning, and visual development. + +[Remix IDE](https://remix.live/){target=\_blank} offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +### Access Remix + +Navigate to [https://remix.polkadot.io/](https://remix.polkadot.io/){target=\_blank} in your web browser. + +The interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file: + +![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-01.webp) + +### Compile + +1. To compile your contract: + 1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar. + 2. Click **Compile Storage.sol** or press `Ctrl+S`. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-02.webp) + +Compilation errors and warnings appear in the terminal panel at the bottom of the screen. + +### Deploy + +1. Navigate to the **Deploy & Run Transactions** tab. +2. Click the **Environment** dropdown and select **Injected Provider - MetaMask** (ensure your MetaMask wallet is connected to Polkadot Hub TestNet). +3. Click **Deploy**. +4. Approve the transaction in your MetaMask wallet. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-03.webp) + +Your deployed contract will appear in the **Deployed Contracts** section, ready for interaction. + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). + + --- Page Title: Send XCM Messages diff --git a/.ai/pages/smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm.md b/.ai/pages/smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm.md new file mode 100644 index 000000000..add2dc4a4 --- /dev/null +++ b/.ai/pages/smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm.md @@ -0,0 +1,472 @@ +--- +title: Deploy a Basic Contract to Polkadot Hub +description: Learn how to deploy a basic smart contract to Polkadot Hub using the PolkaVM. +categories: Smart Contracts +url: https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/.deploy-basic-pvm/ +--- + +# Deploy a Basic Contract + +## Introduction + +Deploying smart contracts to [Polkadot Hub](/smart-contracts/overview/#smart-contract-development){target=\_blank} can be accomplished through various tools and environments, each suited to different development workflows. This guide demonstrates how to deploy a basic PolkaVM (PVM) smart contract using four popular approaches: JavaScript with [Ethers.js](https://docs.ethers.org/v6/){target=\_blank}, [Remix IDE](https://remix.live/){target=\_blank}, [Hardhat](https://hardhat.org/){target=\_blank}, and [Foundry](https://getfoundry.sh/){target=\_blank}. + +All these tools leverage the `revive` compiler to transform Solidity smart contracts into PolkaVM bytecode, making them compatible with Polkadot Hub's native smart contract environment. Whether you prefer working with lightweight JavaScript libraries, visual browser-based IDEs, comprehensive development frameworks, or fast command-line toolkits, this guide covers the deployment process for each approach. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later (for JavaScript/Hardhat approaches). +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +## JavaScript with Ethers.js + +Ethers.js provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications. + +### Setup + +First, initialize your project and install dependencies: + +```bash +mkdir ethers-deployment +cd ethers-deployment +npm init -y +npm install ethers @parity/resolc +``` + +### Create and Compile Your Contract + +Create a simple storage contract in `contracts/Storage.sol`: + +```solidity title="contracts/Storage.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +Create a compilation script `compile.js`: + +```javascript title="compile.js" +const { compile } = require('@parity/resolc'); +const { readFileSync, writeFileSync } = require('fs'); +const { basename, join } = require('path'); + +const compileContract = async (solidityFilePath, outputDir) => { + try { + // Read the Solidity file + const source = readFileSync(solidityFilePath, 'utf8'); + + // Construct the input object for the compiler + const input = { + [basename(solidityFilePath)]: { content: source }, + }; + + console.log(`Compiling contract: ${basename(solidityFilePath)}...`); + + // Compile the contract + const out = await compile(input); + + for (const contracts of Object.values(out.contracts)) { + for (const [name, contract] of Object.entries(contracts)) { + console.log(`Compiled contract: ${name}`); + + // Write the ABI + const abiPath = join(outputDir, `${name}.json`); + writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2)); + console.log(`ABI saved to ${abiPath}`); + + // Write the bytecode + const bytecodePath = join(outputDir, `${name}.polkavm`); + writeFileSync( + bytecodePath, + Buffer.from(contract.evm.bytecode.object, 'hex'), + ); + console.log(`Bytecode saved to ${bytecodePath}`); + } + } + } catch (error) { + console.error('Error compiling contracts:', error); + } +}; + +const solidityFilePath = join(__dirname, 'contracts/Storage.sol'); +const outputDir = join(__dirname, 'contracts'); + +compileContract(solidityFilePath, outputDir); +``` + +Run the compilation: + +```bash +node compile.js +``` + +### Deploy the Contract + +Create a deployment script `deploy.js`: + +```javascript title="deploy.js" +const { writeFileSync, existsSync, readFileSync } = require('fs'); +const { join } = require('path'); +const { ethers, JsonRpcProvider } = require('ethers'); + +const codegenDir = join(__dirname); + +// Creates a provider with specified RPC URL and chain details +const createProvider = (rpcUrl, chainId, chainName) => { + const provider = new JsonRpcProvider(rpcUrl, { + chainId: chainId, + name: chainName, + }); + return provider; +}; + +// Reads and parses the ABI file for a given contract +const getAbi = (contractName) => { + try { + return JSON.parse( + readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'), + ); + } catch (error) { + console.error( + `Could not find ABI for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +// Reads the compiled bytecode for a given contract +const getByteCode = (contractName) => { + try { + const bytecodePath = join( + codegenDir, + 'contracts', + `${contractName}.polkavm`, + ); + return `0x${readFileSync(bytecodePath).toString('hex')}`; + } catch (error) { + console.error( + `Could not find bytecode for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +const deployContract = async (contractName, mnemonic, providerConfig) => { + console.log(`Deploying ${contractName}...`); + + try { + // Step 1: Set up provider and wallet + const provider = createProvider( + providerConfig.rpc, + providerConfig.chainId, + providerConfig.name, + ); + const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic); + const wallet = walletMnemonic.connect(provider); + + // Step 2: Create and deploy the contract + const factory = new ethers.ContractFactory( + getAbi(contractName), + getByteCode(contractName), + wallet, + ); + const contract = await factory.deploy(); + await contract.waitForDeployment(); + + // Step 3: Save deployment information + const address = await contract.getAddress(); + console.log(`Contract ${contractName} deployed at: ${address}`); + + const addressesFile = join(codegenDir, 'contract-address.json'); + const addresses = existsSync(addressesFile) + ? JSON.parse(readFileSync(addressesFile, 'utf8')) + : {}; + addresses[contractName] = address; + writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8'); + } catch (error) { + console.error(`Failed to deploy contract ${contractName}:`, error); + } +}; + +const providerConfig = { + rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + name: 'polkadot-hub-testnet', +}; + +const mnemonic = 'INSERT_MNEMONIC'; + +deployContract('Storage', mnemonic, providerConfig); +``` + +Replace the `INSERT_MNEMONIC` placeholder with your actual mnemonic. + +Execute the deployment: + +```bash +node deploy.js +``` + +After running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions. + +## Remix IDE + +Remix IDE offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development. + +### Access Remix + +Navigate to [https://remix.polkadot.io/](https://remix.polkadot.io/){target=\_blank} in your web browser. + +The interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file: + +![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-01.webp) + +### Compile + +1. To compile your contract: + 1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar. + 2. Click **Compile Storage.sol** or press `Ctrl+S`. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-02.webp) + +Compilation errors and warnings appear in the terminal panel at the bottom of the screen. + +### Deploy + +1. Navigate to the **Deploy & Run Transactions** tab. +2. Click the **Environment** dropdown and select **Injected Provider - MetaMask** (ensure your MetaMask wallet is connected to Polkadot Hub TestNet). +3. Click **Deploy**. +4. Approve the transaction in your MetaMask wallet. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-03.webp) + +Your deployed contract will appear in the **Deployed Contracts** section, ready for interaction. + +## Hardhat + +Hardhat provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects. + +### Setup + +Initialize your Hardhat project: + +```bash +mkdir hardhat-deployment +cd hardhat-deployment +npm init -y +npm install --save-dev @parity/hardhat-polkadot@0.1.9 +npx hardhat-polkadot init +``` + +Select **Create a JavaScript project** when prompted. + +Complete the setup: + +```bash +echo '/ignition/deployments/' >> .gitignore +npm install +``` + +### Configure Hardhat + +Edit `hardhat.config.js`: + +```javascript title="hardhat.config.js" hl_lines="21-26" +require("@nomicfoundation/hardhat-toolbox") +require("@parity/hardhat-polkadot") + +/** @type import('hardhat/config').HardhatUserConfig */ +module.exports = { + solidity: "0.8.28", + resolc: { + compilerSource: "npm", + }, + networks: { + hardhat: { + polkavm: true, + forking: { + url: "https://testnet-passet-hub.polkadot.io", + }, + adapterConfig: { + adapterBinaryPath: "../bin/eth-rpc", + dev: true, + }, + }, + polkadotHubTestnet: { + polkavm: true, + url: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + accounts: [vars.get('PRIVATE_KEY')], + }, + }, +} +``` + +Run the following command to set the private key: + +```bash +npx hardhat vars set PRIVATE_KEY "INSERT_PRIVATE_KEY" +``` + +Replace `INSERT_PRIVATE_KEY` with your actual private key. + +### Create Your Contract + +Replace the default contract in `contracts/Storage.sol`: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +### Compile + +```bash +npx hardhat compile +``` + +### Set Up Deployment + +Create a deployment module in `ignition/modules/Storage.js`: + +```javascript +const { buildModule } = require('@nomicfoundation/hardhat-ignition/modules'); + +module.exports = buildModule('StorageModule', (m) => { + const storage = m.contract('Storage'); + return { storage }; +}); +``` + +### Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +npx hardhat ignition deploy ./ignition/modules/Storage.js --network polkadotHubTestnet +``` + +## Foundry + +Foundry offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment. + +### Setup + +Install Foundry for Polkadot: + +```bash +curl -L https://raw.githubusercontent.com/paritytech/foundry-polkadot/refs/heads/master/foundryup/install | bash +foundryup-polkadot +``` + +Initialize your project: + +```bash +forge init foundry-deployment +cd foundry-deployment +``` + +### Configure Foundry + +Edit `foundry.toml`: + +```toml +[profile.default] +src = "src" +out = "out" +libs = ["lib"] + +[profile.default.resolc] +resolc_compile = true + +[rpc_endpoints] +polkadot_hub_testnet = "https://testnet-passet-hub-eth-rpc.polkadot.io" +``` + +### Create Your Contract + +Replace the default contract in `src/Storage.sol`: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +### Compile + +```bash +forge build --resolc +``` + +Verify the compilation by inspecting the bytecode (should start with `0x505`): + +```bash +forge inspect Storage bytecode --resolc +``` + +### Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +forge create Storage \ + --rpc-url polkadot_hub_testnet \ + --private-key YOUR_PRIVATE_KEY \ + --resolc --broadcast +``` + +## Conclusion + +This guide has demonstrated four different approaches to deploying smart contracts on Polkadot Hub. Each method offers distinct advantages: + +- **Ethers.js**: Best for lightweight, programmatic deployments and application integration +- **Remix IDE**: Ideal for rapid prototyping, learning, and visual development +- **Hardhat**: Perfect for professional workflows requiring comprehensive testing and debugging +- **Foundry**: Excellent for developers who prefer fast, command-line driven development + +All approaches use the `resolc` compiler to generate PolkaVM-compatible bytecode, ensuring your contracts run natively on Polkadot Hub. Choose the tool that best fits your workflow and project requirements. + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). diff --git a/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-ethers-js.md b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-ethers-js.md new file mode 100644 index 000000000..fdf24f49c --- /dev/null +++ b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-ethers-js.md @@ -0,0 +1,239 @@ +--- +title: JavaScript with Ethers.js +description: Learn how to deploy a basic smart contract to Polkadot Hub using Ethers.js, best for lightweight, programmatic deployments and application integration. +categories: Smart Contracts +url: https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract/deploy-basic-ethers-js/ +--- + +[Ethers.js](https://docs.ethers.org/v6/){target=\_blank} provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +### Setup + +First, initialize your project and install dependencies: + +```bash +mkdir ethers-deployment +cd ethers-deployment +npm init -y +npm install ethers@6.15.0 solc@0.8.30 +``` + +### Create and Compile Your Contract + +Create a simple storage contract in `contracts/Storage.sol`: + +```solidity title="contracts/Storage.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +Create a compilation script `compile.js`: + +```javascript title="compile.js" +const solc = require('solc'); +const { readFileSync, writeFileSync } = require('fs'); +const { basename, join } = require('path'); + +const compileContract = async (solidityFilePath, outputDir) => { + try { + // Read the Solidity file + const source = readFileSync(solidityFilePath, 'utf8'); + + // Construct the input object for the compiler + const input = { + language: 'Solidity', + sources: { + [basename(solidityFilePath)]: { content: source }, + }, + settings: { + outputSelection: { + '*': { + '*': ['*'], + }, + }, + }, + }; + + console.log(`Compiling contract: ${basename(solidityFilePath)}...`); + + // Compile the contract + const output = JSON.parse(solc.compile(JSON.stringify(input))); + + if (output.errors) { + output.errors.forEach(error => { + console.error('Compilation error:', error.message); + }); + return; + } + + for (const contracts of Object.values(output.contracts)) { + for (const [name, contract] of Object.entries(contracts)) { + console.log(`Compiled contract: ${name}`); + + // Write the ABI + const abiPath = join(outputDir, `${name}.json`); + writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2)); + console.log(`ABI saved to ${abiPath}`); + + // Write the bytecode + const bytecodePath = join(outputDir, `${name}.bin`); + writeFileSync(bytecodePath, + Buffer.from( + contract.evm.bytecode.object, + 'hex' + )); + console.log(`Bytecode saved to ${bytecodePath}`); + } + } + } catch (error) { + console.error('Error compiling contracts:', error); + } +}; + +const solidityFilePath = join(__dirname, 'contracts/Storage.sol'); +const outputDir = join(__dirname, 'contracts'); + +compileContract(solidityFilePath, outputDir); +``` + +Run the compilation: + +```bash +node compile.js +``` + +### Deploy the Contract + +Create a deployment script `deploy.js`: + +```javascript title="deploy.js" +const { writeFileSync, existsSync, readFileSync } = require('fs'); +const { join } = require('path'); +const { ethers, JsonRpcProvider } = require('ethers'); + +const codegenDir = join(__dirname); + +// Creates a provider with specified RPC URL and chain details +const createProvider = (rpcUrl, chainId, chainName) => { + const provider = new JsonRpcProvider(rpcUrl, { + chainId: chainId, + name: chainName, + }); + return provider; +}; + +// Reads and parses the ABI file for a given contract +const getAbi = (contractName) => { + try { + return JSON.parse( + readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'), + ); + } catch (error) { + console.error( + `Could not find ABI for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +// Reads the compiled bytecode for a given contract +const getByteCode = (contractName) => { + try { + const bytecodePath = join( + codegenDir, + 'contracts', + `${contractName}.bin`, + ); + return `0x${readFileSync(bytecodePath).toString('hex')}`; + } catch (error) { + console.error( + `Could not find bytecode for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +const deployContract = async (contractName, mnemonic, providerConfig) => { + console.log(`Deploying ${contractName}...`); + + try { + // Step 1: Set up provider and wallet + const provider = createProvider( + providerConfig.rpc, + providerConfig.chainId, + providerConfig.name, + ); + const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic); + const wallet = walletMnemonic.connect(provider); + + // Step 2: Create and deploy the contract + const factory = new ethers.ContractFactory( + getAbi(contractName), + getByteCode(contractName), + wallet, + ); + const contract = await factory.deploy(); + await contract.waitForDeployment(); + + // Step 3: Save deployment information + const address = await contract.getAddress(); + console.log(`Contract ${contractName} deployed at: ${address}`); + + const addressesFile = join(codegenDir, 'contract-address.json'); + const addresses = existsSync(addressesFile) + ? JSON.parse(readFileSync(addressesFile, 'utf8')) + : {}; + addresses[contractName] = address; + writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8'); + } catch (error) { + console.error(`Failed to deploy contract ${contractName}:`, error); + } +}; + +const providerConfig = { + rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + name: 'polkadot-hub-testnet', +}; + +const mnemonic = 'INSERT_MNEMONIC'; + +deployContract('Storage', mnemonic, providerConfig); +``` + +Replace the `INSERT_MNEMONIC` placeholder with your actual mnemonic. + +Execute the deployment: + +```bash +node deploy.js +``` + +After running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions. + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). diff --git a/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-foundry.md b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-foundry.md new file mode 100644 index 000000000..446091ec8 --- /dev/null +++ b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-foundry.md @@ -0,0 +1,94 @@ +--- +title: Foundry +description: Learn how to deploy a basic smart contract to Polkadot Hub using Foundry, excellent for developers who prefer fast, command-line driven development. +categories: Smart Contracts +url: https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract/deploy-basic-foundry/ +--- + +[Foundry](https://getfoundry.sh/){target=\_blank} offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +### Setup + +Install Foundry: + +```bash +curl -L https://foundry.paradigm.xyz | bash +foundryup +``` + +Initialize your project: + +```bash +forge init foundry-deployment +cd foundry-deployment +``` + +### Configure Foundry + +Edit `foundry.toml`: + +```toml +[profile.default] +src = "src" +out = "out" +libs = ["lib"] + +[rpc_endpoints] +polkadot_hub_testnet = "https://testnet-passet-hub-eth-rpc.polkadot.io" +``` + +### Create Your Contract + +Replace the default contract in `src/Storage.sol`: + +```solidity title="src/Storage.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +### Compile + +```bash +forge build +``` + +Verify the compilation by inspecting the bytecode: + +```bash +forge inspect Storage bytecode +``` + +### Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +forge create Storage \ + --rpc-url polkadot_hub_testnet \ + --private-key YOUR_PRIVATE_KEY \ + --broadcast +``` + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). diff --git a/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-hardhat.md b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-hardhat.md new file mode 100644 index 000000000..16b01c943 --- /dev/null +++ b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-hardhat.md @@ -0,0 +1,134 @@ +--- +title: hardhat +description: Learn how to deploy a basic smart contract to Polkadot Hub using Hardhat, Perfect for professional workflows requiring comprehensive testing and debugging. +categories: Smart Contracts +url: https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract/deploy-basic-hardhat/ +--- + +[Hardhat](https://hardhat.org/){target=\_blank} provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +### Setup + +Initialize your Hardhat project: + +```bash +mkdir hardhat-deployment +cd hardhat-deployment +npx hardhat --init +``` + +### Configure Hardhat + +Edit `hardhat.config.js`: + +```javascript title="hardhat.config.js" hl_lines="39-43" +import type { HardhatUserConfig } from "hardhat/config"; + +import hardhatToolboxViemPlugin from "@nomicfoundation/hardhat-toolbox-viem"; +import { configVariable } from "hardhat/config"; + +const config: HardhatUserConfig = { + plugins: [hardhatToolboxViemPlugin], + solidity: { + profiles: { + default: { + version: "0.8.28", + }, + production: { + version: "0.8.28", + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, + }, + }, + }, + networks: { + hardhatMainnet: { + type: "edr-simulated", + chainType: "l1", + }, + hardhatOp: { + type: "edr-simulated", + chainType: "op", + }, + sepolia: { + type: "http", + chainType: "l1", + url: configVariable("SEPOLIA_RPC_URL"), + accounts: [configVariable("SEPOLIA_PRIVATE_KEY")], + }, + polkadotHubTestnet: { + url: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + accounts: [configVariable("PRIVATE_KEY")], + }, + }, +}; + +export default config; + +``` + +### Create Your Contract + +Replace the default contract in `contracts/Storage.sol`: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +### Compile + +```bash +npx hardhat build +``` + +### Set Up Deployment + +Create a deployment module in `ignition/modules/Storage.ts`: + +```typescript title="ignition/modules/Storage.ts" +import { buildModule } from '@nomicfoundation/hardhat-ignition/modules'; + +export default buildModule('StorageModule', (m) => { + const storage = m.contract('Storage'); + return { storage }; +}); +``` + +### Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +npx hardhat ignition deploy ignition/modules/Storage.ts --network polkadotHubTestnet +``` + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). diff --git a/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-remix.md b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-remix.md new file mode 100644 index 000000000..b389f19f1 --- /dev/null +++ b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-remix.md @@ -0,0 +1,49 @@ +--- +title: Remix IDE +description: Learn how to deploy a basic smart contract to Polkadot Hub using Remix IDE Ideal for rapid prototyping, learning, and visual development. +categories: Smart Contracts +url: https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract/deploy-basic-remix/ +--- + +[Remix IDE](https://remix.live/){target=\_blank} offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +### Access Remix + +Navigate to [https://remix.polkadot.io/](https://remix.polkadot.io/){target=\_blank} in your web browser. + +The interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file: + +![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-01.webp) + +### Compile + +1. To compile your contract: + 1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar. + 2. Click **Compile Storage.sol** or press `Ctrl+S`. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-02.webp) + +Compilation errors and warnings appear in the terminal panel at the bottom of the screen. + +### Deploy + +1. Navigate to the **Deploy & Run Transactions** tab. +2. Click the **Environment** dropdown and select **Injected Provider - MetaMask** (ensure your MetaMask wallet is connected to Polkadot Hub TestNet). +3. Click **Deploy**. +4. Approve the transaction in your MetaMask wallet. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-03.webp) + +Your deployed contract will appear in the **Deployed Contracts** section, ready for interaction. + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). diff --git a/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-ethers-js.md b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-ethers-js.md new file mode 100644 index 000000000..240626ef0 --- /dev/null +++ b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-ethers-js.md @@ -0,0 +1,239 @@ +--- +title: JavaScript with Ethers.js +description: Learn how to deploy a basic smart contract to Polkadot Hub using Ethers.js, best for lightweight, programmatic deployments and application integration. +categories: Smart Contracts +url: https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract-evm/deploy-basic-ethers-js/ +--- + +[Ethers.js](https://docs.ethers.org/v6/){target=\_blank} provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +### Setup + +First, initialize your project and install dependencies: + +```bash +mkdir ethers-deployment +cd ethers-deployment +npm init -y +npm install ethers@6.15.0 solc@0.8.30 +``` + +### Create and Compile Your Contract + +Create a simple storage contract in `contracts/Storage.sol`: + +```solidity title="contracts/Storage.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +Create a compilation script `compile.js`: + +```javascript title="compile.js" +const solc = require('solc'); +const { readFileSync, writeFileSync } = require('fs'); +const { basename, join } = require('path'); + +const compileContract = async (solidityFilePath, outputDir) => { + try { + // Read the Solidity file + const source = readFileSync(solidityFilePath, 'utf8'); + + // Construct the input object for the compiler + const input = { + language: 'Solidity', + sources: { + [basename(solidityFilePath)]: { content: source }, + }, + settings: { + outputSelection: { + '*': { + '*': ['*'], + }, + }, + }, + }; + + console.log(`Compiling contract: ${basename(solidityFilePath)}...`); + + // Compile the contract + const output = JSON.parse(solc.compile(JSON.stringify(input))); + + if (output.errors) { + output.errors.forEach(error => { + console.error('Compilation error:', error.message); + }); + return; + } + + for (const contracts of Object.values(output.contracts)) { + for (const [name, contract] of Object.entries(contracts)) { + console.log(`Compiled contract: ${name}`); + + // Write the ABI + const abiPath = join(outputDir, `${name}.json`); + writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2)); + console.log(`ABI saved to ${abiPath}`); + + // Write the bytecode + const bytecodePath = join(outputDir, `${name}.bin`); + writeFileSync(bytecodePath, + Buffer.from( + contract.evm.bytecode.object, + 'hex' + )); + console.log(`Bytecode saved to ${bytecodePath}`); + } + } + } catch (error) { + console.error('Error compiling contracts:', error); + } +}; + +const solidityFilePath = join(__dirname, 'contracts/Storage.sol'); +const outputDir = join(__dirname, 'contracts'); + +compileContract(solidityFilePath, outputDir); +``` + +Run the compilation: + +```bash +node compile.js +``` + +### Deploy the Contract + +Create a deployment script `deploy.js`: + +```javascript title="deploy.js" +const { writeFileSync, existsSync, readFileSync } = require('fs'); +const { join } = require('path'); +const { ethers, JsonRpcProvider } = require('ethers'); + +const codegenDir = join(__dirname); + +// Creates a provider with specified RPC URL and chain details +const createProvider = (rpcUrl, chainId, chainName) => { + const provider = new JsonRpcProvider(rpcUrl, { + chainId: chainId, + name: chainName, + }); + return provider; +}; + +// Reads and parses the ABI file for a given contract +const getAbi = (contractName) => { + try { + return JSON.parse( + readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'), + ); + } catch (error) { + console.error( + `Could not find ABI for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +// Reads the compiled bytecode for a given contract +const getByteCode = (contractName) => { + try { + const bytecodePath = join( + codegenDir, + 'contracts', + `${contractName}.bin`, + ); + return `0x${readFileSync(bytecodePath).toString('hex')}`; + } catch (error) { + console.error( + `Could not find bytecode for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +const deployContract = async (contractName, mnemonic, providerConfig) => { + console.log(`Deploying ${contractName}...`); + + try { + // Step 1: Set up provider and wallet + const provider = createProvider( + providerConfig.rpc, + providerConfig.chainId, + providerConfig.name, + ); + const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic); + const wallet = walletMnemonic.connect(provider); + + // Step 2: Create and deploy the contract + const factory = new ethers.ContractFactory( + getAbi(contractName), + getByteCode(contractName), + wallet, + ); + const contract = await factory.deploy(); + await contract.waitForDeployment(); + + // Step 3: Save deployment information + const address = await contract.getAddress(); + console.log(`Contract ${contractName} deployed at: ${address}`); + + const addressesFile = join(codegenDir, 'contract-address.json'); + const addresses = existsSync(addressesFile) + ? JSON.parse(readFileSync(addressesFile, 'utf8')) + : {}; + addresses[contractName] = address; + writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8'); + } catch (error) { + console.error(`Failed to deploy contract ${contractName}:`, error); + } +}; + +const providerConfig = { + rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + name: 'polkadot-hub-testnet', +}; + +const mnemonic = 'INSERT_MNEMONIC'; + +deployContract('Storage', mnemonic, providerConfig); +``` + +Replace the `INSERT_MNEMONIC` placeholder with your actual mnemonic. + +Execute the deployment: + +```bash +node deploy.js +``` + +After running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions. + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). diff --git a/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-foundry.md b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-foundry.md new file mode 100644 index 000000000..440ca585d --- /dev/null +++ b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-foundry.md @@ -0,0 +1,94 @@ +--- +title: Foundry +description: Learn how to deploy a basic smart contract to Polkadot Hub using Foundry, excellent for developers who prefer fast, command-line driven development. +categories: Smart Contracts +url: https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract-evm/deploy-basic-foundry/ +--- + +[Foundry](https://getfoundry.sh/){target=\_blank} offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +### Setup + +Install Foundry: + +```bash +curl -L https://foundry.paradigm.xyz | bash +foundryup +``` + +Initialize your project: + +```bash +forge init foundry-deployment +cd foundry-deployment +``` + +### Configure Foundry + +Edit `foundry.toml`: + +```toml +[profile.default] +src = "src" +out = "out" +libs = ["lib"] + +[rpc_endpoints] +polkadot_hub_testnet = "https://testnet-passet-hub-eth-rpc.polkadot.io" +``` + +### Create Your Contract + +Replace the default contract in `src/Storage.sol`: + +```solidity title="src/Storage.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +### Compile + +```bash +forge build +``` + +Verify the compilation by inspecting the bytecode: + +```bash +forge inspect Storage bytecode +``` + +### Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +forge create Storage \ + --rpc-url polkadot_hub_testnet \ + --private-key YOUR_PRIVATE_KEY \ + --broadcast +``` + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). diff --git a/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-hardhat.md b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-hardhat.md new file mode 100644 index 000000000..2e2c6cdde --- /dev/null +++ b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-hardhat.md @@ -0,0 +1,134 @@ +--- +title: hardhat +description: Learn how to deploy a basic smart contract to Polkadot Hub using Hardhat, Perfect for professional workflows requiring comprehensive testing and debugging. +categories: Smart Contracts +url: https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract-evm/deploy-basic-hardhat/ +--- + +[Hardhat](https://hardhat.org/){target=\_blank} provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +### Setup + +Initialize your Hardhat project: + +```bash +mkdir hardhat-deployment +cd hardhat-deployment +npx hardhat --init +``` + +### Configure Hardhat + +Edit `hardhat.config.js`: + +```javascript title="hardhat.config.js" hl_lines="39-43" +import type { HardhatUserConfig } from "hardhat/config"; + +import hardhatToolboxViemPlugin from "@nomicfoundation/hardhat-toolbox-viem"; +import { configVariable } from "hardhat/config"; + +const config: HardhatUserConfig = { + plugins: [hardhatToolboxViemPlugin], + solidity: { + profiles: { + default: { + version: "0.8.28", + }, + production: { + version: "0.8.28", + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, + }, + }, + }, + networks: { + hardhatMainnet: { + type: "edr-simulated", + chainType: "l1", + }, + hardhatOp: { + type: "edr-simulated", + chainType: "op", + }, + sepolia: { + type: "http", + chainType: "l1", + url: configVariable("SEPOLIA_RPC_URL"), + accounts: [configVariable("SEPOLIA_PRIVATE_KEY")], + }, + polkadotHubTestnet: { + url: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + accounts: [configVariable("PRIVATE_KEY")], + }, + }, +}; + +export default config; + +``` + +### Create Your Contract + +Replace the default contract in `contracts/Storage.sol`: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +### Compile + +```bash +npx hardhat build +``` + +### Set Up Deployment + +Create a deployment module in `ignition/modules/Storage.ts`: + +```typescript title="ignition/modules/Storage.ts" +import { buildModule } from '@nomicfoundation/hardhat-ignition/modules'; + +export default buildModule('StorageModule', (m) => { + const storage = m.contract('Storage'); + return { storage }; +}); +``` + +### Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +npx hardhat ignition deploy ignition/modules/Storage.ts --network polkadotHubTestnet +``` + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). diff --git a/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-remix.md b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-remix.md new file mode 100644 index 000000000..55727b34f --- /dev/null +++ b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-remix.md @@ -0,0 +1,49 @@ +--- +title: Remix IDE +description: Learn how to deploy a basic smart contract to Polkadot Hub using Remix IDE Ideal for rapid prototyping, learning, and visual development. +categories: Smart Contracts +url: https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract-evm/deploy-basic-remix/ +--- + +[Remix IDE](https://remix.live/){target=\_blank} offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +### Access Remix + +Navigate to [https://remix.polkadot.io/](https://remix.polkadot.io/){target=\_blank} in your web browser. + +The interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file: + +![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-01.webp) + +### Compile + +1. To compile your contract: + 1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar. + 2. Click **Compile Storage.sol** or press `Ctrl+S`. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-02.webp) + +Compilation errors and warnings appear in the terminal panel at the bottom of the screen. + +### Deploy + +1. Navigate to the **Deploy & Run Transactions** tab. +2. Click the **Environment** dropdown and select **Injected Provider - MetaMask** (ensure your MetaMask wallet is connected to Polkadot Hub TestNet). +3. Click **Deploy**. +4. Approve the transaction in your MetaMask wallet. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-03.webp) + +Your deployed contract will appear in the **Deployed Contracts** section, ready for interaction. + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). diff --git a/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-ethers.md b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-ethers.md new file mode 100644 index 000000000..fb7221528 --- /dev/null +++ b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-ethers.md @@ -0,0 +1,264 @@ +--- +title: Deploy a Basic Contract with Ethers.js +description: Learn how to deploy a basic smart contract to Polkadot Hub using Ethers.js, best for lightweight, programmatic deployments and application integration. +categories: Smart Contracts +url: https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic/ethers/ +--- + +# Deploy a Basic Contract with Ethers.js + +## Introduction + +This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Ethers.js](https://docs.ethers.org/v6/){target=\_blank}, which provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications. + +## Prerequisites + +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). See the [step-by-step instructions](/smart-contracts/faucet/#get-test-tokens){target=\_blank}. +- A wallet with a private key for signing transactions. + +## Set Up Your Project + +First, initialize your project and install dependencies: + +```bash +mkdir ethers-deployment +cd ethers-deployment +npm init -y +npm install ethers@6.15.0 solc@0.8.30 +``` + +## Create Your Contract + +Create a simple storage contract in `contracts/Storage.sol`: + +```solidity title="contracts/Storage.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +## Compile + +Create a compilation script `compile.js`: + +```javascript title="compile.js" +const solc = require('solc'); +const { readFileSync, writeFileSync } = require('fs'); +const { basename, join } = require('path'); + +const compileContract = async (solidityFilePath, outputDir) => { + try { + // Read the Solidity file + const source = readFileSync(solidityFilePath, 'utf8'); + + // Construct the input object for the compiler + const input = { + language: 'Solidity', + sources: { + [basename(solidityFilePath)]: { content: source }, + }, + settings: { + outputSelection: { + '*': { + '*': ['*'], + }, + }, + }, + }; + + console.log(`Compiling contract: ${basename(solidityFilePath)}...`); + + // Compile the contract + const output = JSON.parse(solc.compile(JSON.stringify(input))); + + if (output.errors) { + output.errors.forEach(error => { + console.error('Compilation error:', error.message); + }); + return; + } + + for (const contracts of Object.values(output.contracts)) { + for (const [name, contract] of Object.entries(contracts)) { + console.log(`Compiled contract: ${name}`); + + // Write the ABI + const abiPath = join(outputDir, `${name}.json`); + writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2)); + console.log(`ABI saved to ${abiPath}`); + + // Write the bytecode + const bytecodePath = join(outputDir, `${name}.bin`); + writeFileSync(bytecodePath, + Buffer.from( + contract.evm.bytecode.object, + 'hex' + )); + console.log(`Bytecode saved to ${bytecodePath}`); + } + } + } catch (error) { + console.error('Error compiling contracts:', error); + } +}; + +const solidityFilePath = join(__dirname, 'contracts/Storage.sol'); +const outputDir = join(__dirname, 'contracts'); + +compileContract(solidityFilePath, outputDir); +``` + +Run the compilation: + +```bash +node compile.js +``` + +## Deploy + +Create a deployment script `deploy.js`: + +```javascript title="deploy.js" +const { writeFileSync, existsSync, readFileSync } = require('fs'); +const { join } = require('path'); +const { ethers, JsonRpcProvider } = require('ethers'); + +const codegenDir = join(__dirname); + +// Creates a provider with specified RPC URL and chain details +const createProvider = (rpcUrl, chainId, chainName) => { + const provider = new JsonRpcProvider(rpcUrl, { + chainId: chainId, + name: chainName, + }); + return provider; +}; + +// Reads and parses the ABI file for a given contract +const getAbi = (contractName) => { + try { + return JSON.parse( + readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'), + ); + } catch (error) { + console.error( + `Could not find ABI for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +// Reads the compiled bytecode for a given contract +const getByteCode = (contractName) => { + try { + const bytecodePath = join( + codegenDir, + 'contracts', + `${contractName}.bin`, + ); + return `0x${readFileSync(bytecodePath).toString('hex')}`; + } catch (error) { + console.error( + `Could not find bytecode for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +const deployContract = async (contractName, mnemonic, providerConfig) => { + console.log(`Deploying ${contractName}...`); + + try { + // Step 1: Set up provider and wallet + const provider = createProvider( + providerConfig.rpc, + providerConfig.chainId, + providerConfig.name, + ); + const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic); + const wallet = walletMnemonic.connect(provider); + + // Step 2: Create and deploy the contract + const factory = new ethers.ContractFactory( + getAbi(contractName), + getByteCode(contractName), + wallet, + ); + const contract = await factory.deploy(); + await contract.waitForDeployment(); + + // Step 3: Save deployment information + const address = await contract.getAddress(); + console.log(`Contract ${contractName} deployed at: ${address}`); + + const addressesFile = join(codegenDir, 'contract-address.json'); + const addresses = existsSync(addressesFile) + ? JSON.parse(readFileSync(addressesFile, 'utf8')) + : {}; + addresses[contractName] = address; + writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8'); + } catch (error) { + console.error(`Failed to deploy contract ${contractName}:`, error); + } +}; + +const providerConfig = { + rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + name: 'polkadot-hub-testnet', +}; + +const mnemonic = 'INSERT_MNEMONIC'; + +deployContract('Storage', mnemonic, providerConfig); +``` + +Replace the `INSERT_MNEMONIC` placeholder with your actual mnemonic. + +!!! warning + Never embed private keys, mnemonic phrases, or security-sensitive credentials directly into your JavaScript, TypeScript, or any front-end/client-side files. + +Execute the deployment: + +```bash +node deploy.js +``` + +After running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions. + +## Where to Go Next + +
+ +- Guide __Deploy an ERC-20__ + + --- + + Walk through deploying a fully-functional ERC-20 to the Polkadot Hub using Ethers.js. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-erc20/ethers/) + +- Guide __Deploy an NFT__ + + --- + + Walk through deploying a NFT to the Polkadot Hub using Ethers.js. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-nft/ethers/) + +
diff --git a/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-evm.md b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-evm.md new file mode 100644 index 000000000..3b8434590 --- /dev/null +++ b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-evm.md @@ -0,0 +1,492 @@ +--- +title: Deploy a Basic Contract to EVM +description: Learn how to deploy a basic smart contract to Polkadot Hub using standard EVM tools and toolchains. +categories: Smart Contracts +url: https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-evm/ +--- + +# Deploy a Basic Contract (EVM) + +## Introduction + +Deploying smart contracts to the [Polkadot Hub](/smart-contracts/overview/#smart-contract-development){target=\_blank} can be accomplished using standard EVM development tools and workflows. This guide demonstrates how to deploy a basic smart contract using four popular EVM approaches: JavaScript with [Ethers.js](https://docs.ethers.org/v6/){target=\_blank}, [Remix IDE](https://remix.live/){target=\_blank}, [Hardhat](https://hardhat.org/){target=\_blank}, and [Foundry](https://getfoundry.sh/){target=\_blank}. + +All these tools use standard Solidity compilation to generate EVM bytecode, making them compatible with Polkadot Hub's EVM environment. Whether you prefer working with lightweight JavaScript libraries, visual browser-based IDEs, comprehensive development frameworks, or fast command-line toolkits, this guide covers the deployment process for each approach. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later (for JavaScript/Hardhat approaches). +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +## Deployment options + +=== "JavaScript with Ethers.js" + Ethers.js provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications. + + ### Setup + + First, initialize your project and install dependencies: + + ```bash + mkdir ethers-deployment + cd ethers-deployment + npm init -y + npm install ethers@6.15.0 solc@0.8.30 + ``` + + ### Create and Compile Your Contract + + Create a simple storage contract in `contracts/Storage.sol`: + + ```solidity title="contracts/Storage.sol" + // SPDX-License-Identifier: MIT + pragma solidity ^0.8.9; + + contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } + } + ``` + + Create a compilation script `compile.js`: + + ```javascript title="compile.js" + const solc = require('solc'); + const { readFileSync, writeFileSync } = require('fs'); + const { basename, join } = require('path'); + + const compileContract = async (solidityFilePath, outputDir) => { + try { + // Read the Solidity file + const source = readFileSync(solidityFilePath, 'utf8'); + + // Construct the input object for the compiler + const input = { + language: 'Solidity', + sources: { + [basename(solidityFilePath)]: { content: source }, + }, + settings: { + outputSelection: { + '*': { + '*': ['*'], + }, + }, + }, + }; + + console.log(`Compiling contract: ${basename(solidityFilePath)}...`); + + // Compile the contract + const output = JSON.parse(solc.compile(JSON.stringify(input))); + + if (output.errors) { + output.errors.forEach(error => { + console.error('Compilation error:', error.message); + }); + return; + } + + for (const contracts of Object.values(output.contracts)) { + for (const [name, contract] of Object.entries(contracts)) { + console.log(`Compiled contract: ${name}`); + + // Write the ABI + const abiPath = join(outputDir, `${name}.json`); + writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2)); + console.log(`ABI saved to ${abiPath}`); + + // Write the bytecode + const bytecodePath = join(outputDir, `${name}.bin`); + writeFileSync(bytecodePath, + Buffer.from( + contract.evm.bytecode.object, + 'hex' + )); + console.log(`Bytecode saved to ${bytecodePath}`); + } + } + } catch (error) { + console.error('Error compiling contracts:', error); + } + }; + + const solidityFilePath = join(__dirname, 'contracts/Storage.sol'); + const outputDir = join(__dirname, 'contracts'); + + compileContract(solidityFilePath, outputDir); + ``` + + Run the compilation: + + ```bash + node compile.js + ``` + + ### Deploy the Contract + + Create a deployment script `deploy.js`: + + ```javascript title="deploy.js" + const { writeFileSync, existsSync, readFileSync } = require('fs'); + const { join } = require('path'); + const { ethers, JsonRpcProvider } = require('ethers'); + + const codegenDir = join(__dirname); + + // Creates a provider with specified RPC URL and chain details + const createProvider = (rpcUrl, chainId, chainName) => { + const provider = new JsonRpcProvider(rpcUrl, { + chainId: chainId, + name: chainName, + }); + return provider; + }; + + // Reads and parses the ABI file for a given contract + const getAbi = (contractName) => { + try { + return JSON.parse( + readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'), + ); + } catch (error) { + console.error( + `Could not find ABI for contract ${contractName}:`, + error.message, + ); + throw error; + } + }; + + // Reads the compiled bytecode for a given contract + const getByteCode = (contractName) => { + try { + const bytecodePath = join( + codegenDir, + 'contracts', + `${contractName}.bin`, + ); + return `0x${readFileSync(bytecodePath).toString('hex')}`; + } catch (error) { + console.error( + `Could not find bytecode for contract ${contractName}:`, + error.message, + ); + throw error; + } + }; + + const deployContract = async (contractName, mnemonic, providerConfig) => { + console.log(`Deploying ${contractName}...`); + + try { + // Step 1: Set up provider and wallet + const provider = createProvider( + providerConfig.rpc, + providerConfig.chainId, + providerConfig.name, + ); + const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic); + const wallet = walletMnemonic.connect(provider); + + // Step 2: Create and deploy the contract + const factory = new ethers.ContractFactory( + getAbi(contractName), + getByteCode(contractName), + wallet, + ); + const contract = await factory.deploy(); + await contract.waitForDeployment(); + + // Step 3: Save deployment information + const address = await contract.getAddress(); + console.log(`Contract ${contractName} deployed at: ${address}`); + + const addressesFile = join(codegenDir, 'contract-address.json'); + const addresses = existsSync(addressesFile) + ? JSON.parse(readFileSync(addressesFile, 'utf8')) + : {}; + addresses[contractName] = address; + writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8'); + } catch (error) { + console.error(`Failed to deploy contract ${contractName}:`, error); + } + }; + + const providerConfig = { + rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + name: 'polkadot-hub-testnet', + }; + + const mnemonic = 'INSERT_MNEMONIC'; + + deployContract('Storage', mnemonic, providerConfig); + ``` + + Replace the `INSERT_MNEMONIC` placeholder with your actual mnemonic. + + Execute the deployment: + + ```bash + node deploy.js + ``` + + After running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions. + +=== "Remix IDE" + Remix IDE offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development. + + ### Access Remix + + Navigate to [https://remix.ethereum.org/](https://remix.ethereum.org/){target=\_blank} in your web browser. + + The interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-evm/deploy-basic-evm-01.webp) + + ### Compile + + 1. To compile your contract: + 1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar. + 2. Click **Compile Storage.sol** or press `Ctrl+S`. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-evm/deploy-basic-evm-02.webp) + + Compilation errors and warnings appear in the terminal panel at the bottom of the screen. + + ### Deploy + + 1. Navigate to the **Deploy & Run Transactions** tab. + 2. Click the **Environment** dropdown and select **Browser extension**. + 3. Select **Injected Provider - MetaMask** (make sure you are logged in to MetaMask). + 4. In MetaMask, add a custom network with the following details: + - **Network Name**: Polkadot Hub TestNet + - **RPC URL**: `https://testnet-passet-hub-eth-rpc.polkadot.io` + - **Chain ID**: `420420422` + - **Currency Symbol**: `DOT` + 4. Return to Remix click on **Deploy**. + 6. Approve the transaction in your MetaMask wallet. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-evm/deploy-basic-evm-03.webp) + + Your deployed contract will appear in the **Deployed Contracts** section, ready for interaction. + +=== "Hardhat" + Hardhat provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects. + + ### Setup + + Initialize your Hardhat project: + + ```bash + mkdir hardhat-deployment + cd hardhat-deployment + npx hardhat --init + ``` + + ### Configure Hardhat + + Edit `hardhat.config.js`: + + ```javascript title="hardhat.config.js" hl_lines="39-43" + import type { HardhatUserConfig } from "hardhat/config"; + + import hardhatToolboxViemPlugin from "@nomicfoundation/hardhat-toolbox-viem"; + import { configVariable } from "hardhat/config"; + + const config: HardhatUserConfig = { + plugins: [hardhatToolboxViemPlugin], + solidity: { + profiles: { + default: { + version: "0.8.28", + }, + production: { + version: "0.8.28", + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, + }, + }, + }, + networks: { + hardhatMainnet: { + type: "edr-simulated", + chainType: "l1", + }, + hardhatOp: { + type: "edr-simulated", + chainType: "op", + }, + sepolia: { + type: "http", + chainType: "l1", + url: configVariable("SEPOLIA_RPC_URL"), + accounts: [configVariable("SEPOLIA_PRIVATE_KEY")], + }, + polkadotHubTestnet: { + url: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + accounts: [configVariable("PRIVATE_KEY")], + }, + }, + }; + + export default config; + + ``` + + ### Create Your Contract + + Replace the default contract in `contracts/Storage.sol`: + + ```solidity + // SPDX-License-Identifier: MIT + pragma solidity ^0.8.9; + + contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } + } + ``` + + ### Compile + + ```bash + npx hardhat build + ``` + + ### Set Up Deployment + + Create a deployment module in `ignition/modules/Storage.ts`: + + ```typescript title="ignition/modules/Storage.ts" + import { buildModule } from '@nomicfoundation/hardhat-ignition/modules'; + + export default buildModule('StorageModule', (m) => { + const storage = m.contract('Storage'); + return { storage }; + }); + ``` + + ### Deploy + + Deploy to Polkadot Hub TestNet: + + ```bash + npx hardhat ignition deploy ignition/modules/Storage.ts --network polkadotHubTestnet + ``` + +=== "Foundry" + Foundry offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment. + + ### Setup + + Install Foundry: + + ```bash + curl -L https://foundry.paradigm.xyz | bash + foundryup + ``` + + Initialize your project: + + ```bash + forge init foundry-deployment + cd foundry-deployment + ``` + + ### Configure Foundry + + Edit `foundry.toml`: + + ```toml + [profile.default] + src = "src" + out = "out" + libs = ["lib"] + + [rpc_endpoints] + polkadot_hub_testnet = "https://testnet-passet-hub-eth-rpc.polkadot.io" + ``` + + ### Create Your Contract + + Replace the default contract in `src/Storage.sol`: + + ```solidity title="src/Storage.sol" + // SPDX-License-Identifier: MIT + pragma solidity ^0.8.9; + + contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } + } + ``` + + ### Compile + + ```bash + forge build + ``` + + Verify the compilation by inspecting the bytecode: + + ```bash + forge inspect Storage bytecode + ``` + + ### Deploy + + Deploy to Polkadot Hub TestNet: + + ```bash + forge create Storage \ + --rpc-url polkadot_hub_testnet \ + --private-key YOUR_PRIVATE_KEY \ + --broadcast + ``` + +## Conclusion + +This guide has demonstrated four different approaches to deploying smart contracts on Polkadot Hub using standard EVM tools. Each method offers distinct advantages: + +- **Ethers.js**: Best for lightweight, programmatic deployments and application integration +- **Remix IDE**: Ideal for rapid prototyping, learning, and visual development +- **Hardhat**: Perfect for professional workflows requiring comprehensive testing and debugging +- **Foundry**: Excellent for developers who prefer fast, command-line driven development + +All approaches use standard Solidity compilation to generate EVM bytecode, ensuring your contracts run on Polkadot Hub's EVM environment. Choose the tool that best fits your workflow and project requirements. + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). diff --git a/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-foundry.md b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-foundry.md new file mode 100644 index 000000000..1afec2f18 --- /dev/null +++ b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-foundry.md @@ -0,0 +1,122 @@ +--- +title: Deploy a Basic Contract with Foundry +description: Learn how to deploy a basic smart contract to Polkadot Hub using Foundry, excellent for developers who prefer fast, command-line driven development. +categories: Smart Contracts +url: https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic/foundry/ +--- + +# Deploy a Basic Contract with Foundry + +This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Foundry](https://getfoundry.sh/){target=\_blank}, which offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment. + +## Prerequisites + +- Basic understanding of Solidity programming. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). See the [step-by-step instructions](/smart-contracts/faucet/#get-test-tokens){target=\_blank}. +- A wallet with a private key for signing transactions. + +## Set Up Your Project + +Install Foundry: + +```bash +curl -L https://foundry.paradigm.xyz | bash +foundryup +``` + +Initialize your project: + +```bash +forge init foundry-deployment +cd foundry-deployment +``` + +## Configure Foundry + +Edit `foundry.toml`: + +```toml +[profile.default] +src = "src" +out = "out" +libs = ["lib"] + +[rpc_endpoints] +polkadot_hub_testnet = "https://testnet-passet-hub-eth-rpc.polkadot.io" +``` + +## Create Your Contract + +Replace the default contract in `src/Storage.sol`: + +```solidity title="src/Storage.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +## Compile + +```bash +forge build +``` + +Verify the compilation by inspecting the bytecode: + +```bash +forge inspect Storage bytecode +``` + +## Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +forge create Storage \ + --rpc-url polkadot_hub_testnet \ + --private-key YOUR_PRIVATE_KEY \ + --broadcast +``` + +Replace the `YOUR_PRIVATE_KEY` placeholder with your actual private key. + +## Where to Go Next + +
+ +- Guide __Verify Your Contract__ + + --- + + Now that you've deployed a basic contract, learn how to verify it with Foundry. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/dev-environments/foundry/verify-a-contract/) + +- Guide __Deploy an ERC-20__ + + --- + + Walk through deploying a fully-functional ERC-20 to the Polkadot Hub using Foundry. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-erc20/foundry/) + +- Guide __Deploy an NFT__ + + --- + + Walk through deploying a NFT to the Polkadot Hub using Foundry. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-nft/foundry/) + +
diff --git a/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat.md b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat.md new file mode 100644 index 000000000..93246a62d --- /dev/null +++ b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat.md @@ -0,0 +1,165 @@ +--- +title: Deploy a Basic Contract with Hardhat +description: Learn how to deploy a basic smart contract to Polkadot Hub using Hardhat, Perfect for professional workflows requiring comprehensive testing and debugging. +categories: Smart Contracts +url: https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic/hardhat/ +--- + +# Deploy a Basic Contract with + +## Introduction + +This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Hardhat](https://hardhat.org/){target=\_blank}, which provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects. + +## Prerequisites + +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). See the [step-by-step instructions](/smart-contracts/faucet/#get-test-tokens){target=\_blank}. +- A wallet with a private key for signing transactions. + +## Set Up Your Project + +Initialize your Hardhat project: + +```bash +mkdir hardhat-deployment +cd hardhat-deployment +npx hardhat --init +``` + +## Configure Hardhat + +Edit `hardhat.config.js`: + +```javascript title='hardhat.config.js' hl_lines='39-43' +import type { HardhatUserConfig } from 'hardhat/config'; + +import hardhatToolboxViemPlugin from '@nomicfoundation/hardhat-toolbox-viem'; +import { configVariable } from 'hardhat/config'; + +const config: HardhatUserConfig = { + plugins: [hardhatToolboxViemPlugin], + solidity: { + profiles: { + default: { + version: '0.8.28', + }, + production: { + version: '0.8.28', + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, + }, + }, + }, + networks: { + hardhatMainnet: { + type: 'edr-simulated', + chainType: 'l1', + }, + hardhatOp: { + type: 'edr-simulated', + chainType: 'op', + }, + sepolia: { + type: 'http', + chainType: 'l1', + url: configVariable('SEPOLIA_RPC_URL'), + accounts: [configVariable('SEPOLIA_PRIVATE_KEY')], + }, + polkadotHubTestnet: { + url: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + accounts: [configVariable('PRIVATE_KEY')], + }, + }, +}; + +export default config; + +``` + +!!! tip + Learn how to use Hardhat's [Config Variables](https://hardhat.org/docs/learn-more/configuration-variables){target=\_blank} to handle your private keys in a secure way. + +## Create Your Contract + +Replace the default contract in `contracts/Storage.sol`: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +## Compile + +```bash +npx hardhat build +``` + +## Set Up Deployment + +Create a deployment module in `ignition/modules/Storage.ts`: + +```typescript title="ignition/modules/Storage.ts" +import { buildModule } from '@nomicfoundation/hardhat-ignition/modules'; + +export default buildModule('StorageModule', (m) => { + const storage = m.contract('Storage'); + return { storage }; +}); +``` + +## Deploy the Contract + +Deploy to Polkadot Hub TestNet: + +```bash +npx hardhat ignition deploy ignition/modules/Storage.ts --network polkadotHubTestnet +``` + +## Where to Go Next + +
+ +- Guide __Verify Your Contract__ + + --- + + Now that you've deployed a basic contract, learn how to verify it with Hardhat. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/dev-environments/hardhat/verify-a-contract/) + +- Guide __Deploy an ERC-20__ + + --- + + Walk through deploying a fully-functional ERC-20 to the Polkadot Hub using Hardhat. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-erc20/hardhat/) + +- Guide __Deploy an NFT__ + + --- + + Walk through deploying a NFT to the Polkadot Hub using Hardhat. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-nft/hardhat/) + +
diff --git a/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-pvm.md b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-pvm.md new file mode 100644 index 000000000..662c8908b --- /dev/null +++ b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-pvm.md @@ -0,0 +1,472 @@ +--- +title: Deploy a Basic Contract to Polkadot Hub +description: Learn how to deploy a basic smart contract to Polkadot Hub using the PolkaVM. +categories: Smart Contracts +url: https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-pvm/ +--- + +# Deploy a Basic Contract + +## Introduction + +Deploying smart contracts to [Polkadot Hub](/smart-contracts/overview/#smart-contract-development){target=\_blank} can be accomplished through various tools and environments, each suited to different development workflows. This guide demonstrates how to deploy a basic PolkaVM (PVM) smart contract using four popular approaches: JavaScript with [Ethers.js](https://docs.ethers.org/v6/){target=\_blank}, [Remix IDE](https://remix.live/){target=\_blank}, [Hardhat](https://hardhat.org/){target=\_blank}, and [Foundry](https://getfoundry.sh/){target=\_blank}. + +All these tools leverage the `revive` compiler to transform Solidity smart contracts into PolkaVM bytecode, making them compatible with Polkadot Hub's native smart contract environment. Whether you prefer working with lightweight JavaScript libraries, visual browser-based IDEs, comprehensive development frameworks, or fast command-line toolkits, this guide covers the deployment process for each approach. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later (for JavaScript/Hardhat approaches). +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +## JavaScript with Ethers.js + +Ethers.js provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications. + +### Setup + +First, initialize your project and install dependencies: + +```bash +mkdir ethers-deployment +cd ethers-deployment +npm init -y +npm install ethers @parity/resolc +``` + +### Create and Compile Your Contract + +Create a simple storage contract in `contracts/Storage.sol`: + +```solidity title="contracts/Storage.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +Create a compilation script `compile.js`: + +```javascript title="compile.js" +const { compile } = require('@parity/resolc'); +const { readFileSync, writeFileSync } = require('fs'); +const { basename, join } = require('path'); + +const compileContract = async (solidityFilePath, outputDir) => { + try { + // Read the Solidity file + const source = readFileSync(solidityFilePath, 'utf8'); + + // Construct the input object for the compiler + const input = { + [basename(solidityFilePath)]: { content: source }, + }; + + console.log(`Compiling contract: ${basename(solidityFilePath)}...`); + + // Compile the contract + const out = await compile(input); + + for (const contracts of Object.values(out.contracts)) { + for (const [name, contract] of Object.entries(contracts)) { + console.log(`Compiled contract: ${name}`); + + // Write the ABI + const abiPath = join(outputDir, `${name}.json`); + writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2)); + console.log(`ABI saved to ${abiPath}`); + + // Write the bytecode + const bytecodePath = join(outputDir, `${name}.polkavm`); + writeFileSync( + bytecodePath, + Buffer.from(contract.evm.bytecode.object, 'hex'), + ); + console.log(`Bytecode saved to ${bytecodePath}`); + } + } + } catch (error) { + console.error('Error compiling contracts:', error); + } +}; + +const solidityFilePath = join(__dirname, 'contracts/Storage.sol'); +const outputDir = join(__dirname, 'contracts'); + +compileContract(solidityFilePath, outputDir); +``` + +Run the compilation: + +```bash +node compile.js +``` + +### Deploy the Contract + +Create a deployment script `deploy.js`: + +```javascript title="deploy.js" +const { writeFileSync, existsSync, readFileSync } = require('fs'); +const { join } = require('path'); +const { ethers, JsonRpcProvider } = require('ethers'); + +const codegenDir = join(__dirname); + +// Creates a provider with specified RPC URL and chain details +const createProvider = (rpcUrl, chainId, chainName) => { + const provider = new JsonRpcProvider(rpcUrl, { + chainId: chainId, + name: chainName, + }); + return provider; +}; + +// Reads and parses the ABI file for a given contract +const getAbi = (contractName) => { + try { + return JSON.parse( + readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'), + ); + } catch (error) { + console.error( + `Could not find ABI for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +// Reads the compiled bytecode for a given contract +const getByteCode = (contractName) => { + try { + const bytecodePath = join( + codegenDir, + 'contracts', + `${contractName}.polkavm`, + ); + return `0x${readFileSync(bytecodePath).toString('hex')}`; + } catch (error) { + console.error( + `Could not find bytecode for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +const deployContract = async (contractName, mnemonic, providerConfig) => { + console.log(`Deploying ${contractName}...`); + + try { + // Step 1: Set up provider and wallet + const provider = createProvider( + providerConfig.rpc, + providerConfig.chainId, + providerConfig.name, + ); + const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic); + const wallet = walletMnemonic.connect(provider); + + // Step 2: Create and deploy the contract + const factory = new ethers.ContractFactory( + getAbi(contractName), + getByteCode(contractName), + wallet, + ); + const contract = await factory.deploy(); + await contract.waitForDeployment(); + + // Step 3: Save deployment information + const address = await contract.getAddress(); + console.log(`Contract ${contractName} deployed at: ${address}`); + + const addressesFile = join(codegenDir, 'contract-address.json'); + const addresses = existsSync(addressesFile) + ? JSON.parse(readFileSync(addressesFile, 'utf8')) + : {}; + addresses[contractName] = address; + writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8'); + } catch (error) { + console.error(`Failed to deploy contract ${contractName}:`, error); + } +}; + +const providerConfig = { + rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + name: 'polkadot-hub-testnet', +}; + +const mnemonic = 'INSERT_MNEMONIC'; + +deployContract('Storage', mnemonic, providerConfig); +``` + +Replace the `INSERT_MNEMONIC` placeholder with your actual mnemonic. + +Execute the deployment: + +```bash +node deploy.js +``` + +After running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions. + +## Remix IDE + +Remix IDE offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development. + +### Access Remix + +Navigate to [https://remix.polkadot.io/](https://remix.polkadot.io/){target=\_blank} in your web browser. + +The interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file: + +![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-01.webp) + +### Compile + +1. To compile your contract: + 1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar. + 2. Click **Compile Storage.sol** or press `Ctrl+S`. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-02.webp) + +Compilation errors and warnings appear in the terminal panel at the bottom of the screen. + +### Deploy + +1. Navigate to the **Deploy & Run Transactions** tab. +2. Click the **Environment** dropdown and select **Injected Provider - MetaMask** (ensure your MetaMask wallet is connected to Polkadot Hub TestNet). +3. Click **Deploy**. +4. Approve the transaction in your MetaMask wallet. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-03.webp) + +Your deployed contract will appear in the **Deployed Contracts** section, ready for interaction. + +## Hardhat + +Hardhat provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects. + +### Setup + +Initialize your Hardhat project: + +```bash +mkdir hardhat-deployment +cd hardhat-deployment +npm init -y +npm install --save-dev @parity/hardhat-polkadot@0.1.9 +npx hardhat-polkadot init +``` + +Select **Create a JavaScript project** when prompted. + +Complete the setup: + +```bash +echo '/ignition/deployments/' >> .gitignore +npm install +``` + +### Configure Hardhat + +Edit `hardhat.config.js`: + +```javascript title="hardhat.config.js" hl_lines="21-26" +require("@nomicfoundation/hardhat-toolbox") +require("@parity/hardhat-polkadot") + +/** @type import('hardhat/config').HardhatUserConfig */ +module.exports = { + solidity: "0.8.28", + resolc: { + compilerSource: "npm", + }, + networks: { + hardhat: { + polkavm: true, + forking: { + url: "https://testnet-passet-hub.polkadot.io", + }, + adapterConfig: { + adapterBinaryPath: "../bin/eth-rpc", + dev: true, + }, + }, + polkadotHubTestnet: { + polkavm: true, + url: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + accounts: [vars.get('PRIVATE_KEY')], + }, + }, +} +``` + +Run the following command to set the private key: + +```bash +npx hardhat vars set PRIVATE_KEY "INSERT_PRIVATE_KEY" +``` + +Replace `INSERT_PRIVATE_KEY` with your actual private key. + +### Create Your Contract + +Replace the default contract in `contracts/Storage.sol`: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +### Compile + +```bash +npx hardhat compile +``` + +### Set Up Deployment + +Create a deployment module in `ignition/modules/Storage.js`: + +```javascript +const { buildModule } = require('@nomicfoundation/hardhat-ignition/modules'); + +module.exports = buildModule('StorageModule', (m) => { + const storage = m.contract('Storage'); + return { storage }; +}); +``` + +### Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +npx hardhat ignition deploy ./ignition/modules/Storage.js --network polkadotHubTestnet +``` + +## Foundry + +Foundry offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment. + +### Setup + +Install Foundry for Polkadot: + +```bash +curl -L https://raw.githubusercontent.com/paritytech/foundry-polkadot/refs/heads/master/foundryup/install | bash +foundryup-polkadot +``` + +Initialize your project: + +```bash +forge init foundry-deployment +cd foundry-deployment +``` + +### Configure Foundry + +Edit `foundry.toml`: + +```toml +[profile.default] +src = "src" +out = "out" +libs = ["lib"] + +[profile.default.resolc] +resolc_compile = true + +[rpc_endpoints] +polkadot_hub_testnet = "https://testnet-passet-hub-eth-rpc.polkadot.io" +``` + +### Create Your Contract + +Replace the default contract in `src/Storage.sol`: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +### Compile + +```bash +forge build --resolc +``` + +Verify the compilation by inspecting the bytecode (should start with `0x505`): + +```bash +forge inspect Storage bytecode --resolc +``` + +### Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +forge create Storage \ + --rpc-url polkadot_hub_testnet \ + --private-key YOUR_PRIVATE_KEY \ + --resolc --broadcast +``` + +## Conclusion + +This guide has demonstrated four different approaches to deploying smart contracts on Polkadot Hub. Each method offers distinct advantages: + +- **Ethers.js**: Best for lightweight, programmatic deployments and application integration +- **Remix IDE**: Ideal for rapid prototyping, learning, and visual development +- **Hardhat**: Perfect for professional workflows requiring comprehensive testing and debugging +- **Foundry**: Excellent for developers who prefer fast, command-line driven development + +All approaches use the `resolc` compiler to generate PolkaVM-compatible bytecode, ensuring your contracts run natively on Polkadot Hub. Choose the tool that best fits your workflow and project requirements. + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). diff --git a/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-remix.md b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-remix.md new file mode 100644 index 000000000..5683417c1 --- /dev/null +++ b/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-remix.md @@ -0,0 +1,76 @@ +--- +title: Deploy a Basic Contract with Remix IDE +description: Learn how to deploy a basic smart contract to Polkadot Hub using Remix IDE Ideal for rapid prototyping, learning, and visual development. +categories: Smart Contracts +url: https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic/remix/ +--- + +# Deploy a Basic Contract with Remix IDE + +## Introduction + +This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Remix IDE](https://remix.ethereum.org/){target=\_blank}, which offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development. + +## Prerequisites + +- Basic understanding of Solidity programming. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). See the [step-by-step instructions](/smart-contracts/faucet/#get-test-tokens){target=\_blank}. +- A wallet with a private key for signing transactions. + +## Access Remix + +Navigate to [Remix](https://remix.ethereum.org/){target=\_blank} in your web browser. + +The interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file, which will be used as the example contract throughout this guide. + +![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-01.webp) + +## Compile + +1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar. +2. Click **Compile Storage.sol** or press `Ctrl+S`. + +![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-02.webp) + +Compilation errors and warnings appear in the terminal panel at the bottom of the screen. + +## Deploy + +1. Navigate to the **Deploy & Run Transactions** tab. +2. Click the **Environment** dropdown and select **Injected Provider - MetaMask** (ensure your MetaMask wallet is connected to Polkadot Hub TestNet). +3. Click **Deploy**. +4. Approve the transaction in your MetaMask wallet. + +![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-03.webp) + +Your deployed contract will appear in the **Deployed Contracts** section, ready for interaction. + +## Where to Go Next + +
+ +- Guide __Verify Your Contract__ + + --- + + Now that you've deployed a basic contract, learn how to verify it with Remix. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/dev-environments/remix/verify-a-contract/) + +- Guide __Deploy an ERC-20__ + + --- + + Walk through deploying a fully-functional ERC-20 to the Polkadot Hub using Remix. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-erc20/remix/) + +- Guide __Deploy an NFT__ + + --- + + Walk through deploying a NFT to the Polkadot Hub using Remix. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-nft/remix/) + +
diff --git a/.ai/site-index.json b/.ai/site-index.json index 78ce55171..64440897c 100644 --- a/.ai/site-index.json +++ b/.ai/site-index.json @@ -9780,6 +9780,936 @@ "hash": "sha256:2a42198668c759f63aa602115bf2d290ec7d03bbc3a3df20e30e85027e1b1cc3", "token_estimator": "heuristic-v1" }, + { + "id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", + "title": "Deploy a Basic Contract to Polkadot Hub", + "slug": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/.deploy-basic-pvm/", + "preview": "Deploying smart contracts to [Polkadot Hub](/smart-contracts/overview/#smart-contract-development){target=\\_blank} can be accomplished through various tools and environments, each suited to different development workflows. This guide demonstrates how to deploy a basic PolkaVM (PVM) smart contract using four popular approaches: JavaScript with [Ethers.js](https://docs.ethers.org/v6/){target=\\_blank}, [Remix IDE](https://remix.live/){target=\\_blank}, [Hardhat](https://hardhat.org/){target=\\_blank}", + "outline": [ + { + "depth": 2, + "title": "Introduction", + "anchor": "introduction" + }, + { + "depth": 2, + "title": "JavaScript with Ethers.js", + "anchor": "javascript-with-ethersjs" + }, + { + "depth": 3, + "title": "Setup", + "anchor": "setup" + }, + { + "depth": 3, + "title": "Create and Compile Your Contract", + "anchor": "create-and-compile-your-contract" + }, + { + "depth": 3, + "title": "Deploy the Contract", + "anchor": "deploy-the-contract" + }, + { + "depth": 2, + "title": "Remix IDE", + "anchor": "remix-ide" + }, + { + "depth": 3, + "title": "Access Remix", + "anchor": "access-remix" + }, + { + "depth": 3, + "title": "Compile", + "anchor": "compile" + }, + { + "depth": 3, + "title": "Deploy", + "anchor": "deploy" + }, + { + "depth": 2, + "title": "Hardhat", + "anchor": "hardhat" + }, + { + "depth": 3, + "title": "Setup", + "anchor": "setup-2" + }, + { + "depth": 3, + "title": "Configure Hardhat", + "anchor": "configure-hardhat" + }, + { + "depth": 3, + "title": "Create Your Contract", + "anchor": "create-your-contract" + }, + { + "depth": 3, + "title": "Compile", + "anchor": "compile-2" + }, + { + "depth": 3, + "title": "Set Up Deployment", + "anchor": "set-up-deployment" + }, + { + "depth": 3, + "title": "Deploy", + "anchor": "deploy-2" + }, + { + "depth": 2, + "title": "Foundry", + "anchor": "foundry" + }, + { + "depth": 3, + "title": "Setup", + "anchor": "setup-3" + }, + { + "depth": 3, + "title": "Configure Foundry", + "anchor": "configure-foundry" + }, + { + "depth": 3, + "title": "Create Your Contract", + "anchor": "create-your-contract-2" + }, + { + "depth": 3, + "title": "Compile", + "anchor": "compile-3" + }, + { + "depth": 3, + "title": "Deploy", + "anchor": "deploy-3" + }, + { + "depth": 2, + "title": "Conclusion", + "anchor": "conclusion" + }, + { + "depth": 3, + "title": "Next Steps", + "anchor": "next-steps" + } + ], + "stats": { + "chars": 13872, + "words": 1640, + "headings": 24, + "estimated_token_count_total": 3228 + }, + "hash": "sha256:8f29b0f0b56f8c136206211a858cdc5bc27bcd9119eab179a6cd306182d910cb", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-ethers-js", + "title": "JavaScript with Ethers.js", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-ethers-js", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-ethers-js.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract/deploy-basic-ethers-js/", + "preview": "[Ethers.js](https://docs.ethers.org/v6/){target=\\_blank} provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications.", + "outline": [ + { + "depth": 3, + "title": "Setup", + "anchor": "setup" + }, + { + "depth": 3, + "title": "Create and Compile Your Contract", + "anchor": "create-and-compile-your-contract" + }, + { + "depth": 3, + "title": "Deploy the Contract", + "anchor": "deploy-the-contract" + }, + { + "depth": 3, + "title": "Next Steps", + "anchor": "next-steps" + } + ], + "stats": { + "chars": 6935, + "words": 767, + "headings": 4, + "estimated_token_count_total": 1490 + }, + "hash": "sha256:b0af34b460192f665ca70e7d7985e87b9f59a1a359888f6d14d651daedbcd711", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-foundry", + "title": "Foundry", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-foundry", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-foundry.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract/deploy-basic-foundry/", + "preview": "[Foundry](https://getfoundry.sh/){target=\\_blank} offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment.", + "outline": [ + { + "depth": 3, + "title": "Setup", + "anchor": "setup" + }, + { + "depth": 3, + "title": "Configure Foundry", + "anchor": "configure-foundry" + }, + { + "depth": 3, + "title": "Create Your Contract", + "anchor": "create-your-contract" + }, + { + "depth": 3, + "title": "Compile", + "anchor": "compile" + }, + { + "depth": 3, + "title": "Deploy", + "anchor": "deploy" + }, + { + "depth": 3, + "title": "Next Steps", + "anchor": "next-steps" + } + ], + "stats": { + "chars": 2125, + "words": 276, + "headings": 6, + "estimated_token_count_total": 429 + }, + "hash": "sha256:f7687b9a1e80ab381cf4fb24f37cccfb98ddf139bf687e8832af99364ef0a8a9", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-hardhat", + "title": "hardhat", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-hardhat", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-hardhat.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract/deploy-basic-hardhat/", + "preview": "[Hardhat](https://hardhat.org/){target=\\_blank} provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects.", + "outline": [ + { + "depth": 3, + "title": "Setup", + "anchor": "setup" + }, + { + "depth": 3, + "title": "Configure Hardhat", + "anchor": "configure-hardhat" + }, + { + "depth": 3, + "title": "Create Your Contract", + "anchor": "create-your-contract" + }, + { + "depth": 3, + "title": "Compile", + "anchor": "compile" + }, + { + "depth": 3, + "title": "Set Up Deployment", + "anchor": "set-up-deployment" + }, + { + "depth": 3, + "title": "Deploy", + "anchor": "deploy" + }, + { + "depth": 3, + "title": "Next Steps", + "anchor": "next-steps" + } + ], + "stats": { + "chars": 3336, + "words": 375, + "headings": 7, + "estimated_token_count_total": 672 + }, + "hash": "sha256:93ca24da15095dd0bb03657f53d27771934aee055c11af529445a50e161f79a3", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-remix", + "title": "Remix IDE", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-remix", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-remix.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract/deploy-basic-remix/", + "preview": "[Remix IDE](https://remix.live/){target=\\_blank} offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development.", + "outline": [ + { + "depth": 3, + "title": "Access Remix", + "anchor": "access-remix" + }, + { + "depth": 3, + "title": "Compile", + "anchor": "compile" + }, + { + "depth": 3, + "title": "Deploy", + "anchor": "deploy" + }, + { + "depth": 3, + "title": "Next Steps", + "anchor": "next-steps" + } + ], + "stats": { + "chars": 2473, + "words": 363, + "headings": 4, + "estimated_token_count_total": 527 + }, + "hash": "sha256:56d730c8a6d2ccf0324caf1c3f30929a93904f80e482cfcb457541e04482dbad", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-ethers-js", + "title": "JavaScript with Ethers.js", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-ethers-js", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-ethers-js.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract-evm/deploy-basic-ethers-js/", + "preview": "[Ethers.js](https://docs.ethers.org/v6/){target=\\_blank} provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications.", + "outline": [ + { + "depth": 3, + "title": "Setup", + "anchor": "setup" + }, + { + "depth": 3, + "title": "Create and Compile Your Contract", + "anchor": "create-and-compile-your-contract" + }, + { + "depth": 3, + "title": "Deploy the Contract", + "anchor": "deploy-the-contract" + }, + { + "depth": 3, + "title": "Next Steps", + "anchor": "next-steps" + } + ], + "stats": { + "chars": 6935, + "words": 767, + "headings": 4, + "estimated_token_count_total": 1490 + }, + "hash": "sha256:b0af34b460192f665ca70e7d7985e87b9f59a1a359888f6d14d651daedbcd711", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-foundry", + "title": "Foundry", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-foundry", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-foundry.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract-evm/deploy-basic-foundry/", + "preview": "[Foundry](https://getfoundry.sh/){target=\\_blank} offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment.", + "outline": [ + { + "depth": 3, + "title": "Setup", + "anchor": "setup" + }, + { + "depth": 3, + "title": "Configure Foundry", + "anchor": "configure-foundry" + }, + { + "depth": 3, + "title": "Create Your Contract", + "anchor": "create-your-contract" + }, + { + "depth": 3, + "title": "Compile", + "anchor": "compile" + }, + { + "depth": 3, + "title": "Deploy", + "anchor": "deploy" + }, + { + "depth": 3, + "title": "Next Steps", + "anchor": "next-steps" + } + ], + "stats": { + "chars": 2125, + "words": 276, + "headings": 6, + "estimated_token_count_total": 429 + }, + "hash": "sha256:f7687b9a1e80ab381cf4fb24f37cccfb98ddf139bf687e8832af99364ef0a8a9", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-hardhat", + "title": "hardhat", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-hardhat", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-hardhat.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract-evm/deploy-basic-hardhat/", + "preview": "[Hardhat](https://hardhat.org/){target=\\_blank} provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects.", + "outline": [ + { + "depth": 3, + "title": "Setup", + "anchor": "setup" + }, + { + "depth": 3, + "title": "Configure Hardhat", + "anchor": "configure-hardhat" + }, + { + "depth": 3, + "title": "Create Your Contract", + "anchor": "create-your-contract" + }, + { + "depth": 3, + "title": "Compile", + "anchor": "compile" + }, + { + "depth": 3, + "title": "Set Up Deployment", + "anchor": "set-up-deployment" + }, + { + "depth": 3, + "title": "Deploy", + "anchor": "deploy" + }, + { + "depth": 3, + "title": "Next Steps", + "anchor": "next-steps" + } + ], + "stats": { + "chars": 3336, + "words": 375, + "headings": 7, + "estimated_token_count_total": 672 + }, + "hash": "sha256:93ca24da15095dd0bb03657f53d27771934aee055c11af529445a50e161f79a3", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-remix", + "title": "Remix IDE", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-remix", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-remix.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-contract-evm/deploy-basic-remix/", + "preview": "[Remix IDE](https://remix.live/){target=\\_blank} offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development.", + "outline": [ + { + "depth": 3, + "title": "Access Remix", + "anchor": "access-remix" + }, + { + "depth": 3, + "title": "Compile", + "anchor": "compile" + }, + { + "depth": 3, + "title": "Deploy", + "anchor": "deploy" + }, + { + "depth": 3, + "title": "Next Steps", + "anchor": "next-steps" + } + ], + "stats": { + "chars": 2473, + "words": 363, + "headings": 4, + "estimated_token_count_total": 527 + }, + "hash": "sha256:56d730c8a6d2ccf0324caf1c3f30929a93904f80e482cfcb457541e04482dbad", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-ethers", + "title": "Deploy a Basic Contract with Ethers.js", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-ethers", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-ethers.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic/ethers/", + "preview": "This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Ethers.js](https://docs.ethers.org/v6/){target=\\_blank}, which provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications.", + "outline": [ + { + "depth": 2, + "title": "Introduction", + "anchor": "introduction" + }, + { + "depth": 2, + "title": "Prerequisites", + "anchor": "prerequisites" + }, + { + "depth": 2, + "title": "Set Up Your Project", + "anchor": "set-up-your-project" + }, + { + "depth": 2, + "title": "Create Your Contract", + "anchor": "create-your-contract" + }, + { + "depth": 2, + "title": "Compile", + "anchor": "compile" + }, + { + "depth": 2, + "title": "Deploy", + "anchor": "deploy" + }, + { + "depth": 2, + "title": "Where to Go Next", + "anchor": "where-to-go-next" + } + ], + "stats": { + "chars": 7370, + "words": 823, + "headings": 7, + "estimated_token_count_total": 1729 + }, + "hash": "sha256:ff8975b44870613c3aef0907df365f1ac981de74ec83019df232fe4bda6d9dbe", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-evm", + "title": "Deploy a Basic Contract to EVM", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-evm", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-evm.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-evm/", + "preview": "Deploying smart contracts to the [Polkadot Hub](/smart-contracts/overview/#smart-contract-development){target=\\_blank} can be accomplished using standard EVM development tools and workflows. This guide demonstrates how to deploy a basic smart contract using four popular EVM approaches: JavaScript with [Ethers.js](https://docs.ethers.org/v6/){target=\\_blank}, [Remix IDE](https://remix.live/){target=\\_blank}, [Hardhat](https://hardhat.org/){target=\\_blank}, and [Foundry](https://getfoundry.sh/){ta", + "outline": [ + { + "depth": 2, + "title": "Introduction", + "anchor": "introduction" + }, + { + "depth": 2, + "title": "Deployment options", + "anchor": "deployment-options" + }, + { + "depth": 2, + "title": "Conclusion", + "anchor": "conclusion" + }, + { + "depth": 3, + "title": "Next Steps", + "anchor": "next-steps" + } + ], + "stats": { + "chars": 15629, + "words": 1659, + "headings": 4, + "estimated_token_count_total": 3341 + }, + "hash": "sha256:a4fd853afb897985602e0356551edacbce77db60bbc6556de3b6ae5af3fbc9e5", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-foundry", + "title": "Deploy a Basic Contract with Foundry", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-foundry", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-foundry.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic/foundry/", + "preview": "This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Foundry](https://getfoundry.sh/){target=\\_blank}, which offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment.", + "outline": [ + { + "depth": 2, + "title": "Prerequisites", + "anchor": "prerequisites" + }, + { + "depth": 2, + "title": "Set Up Your Project", + "anchor": "set-up-your-project" + }, + { + "depth": 2, + "title": "Configure Foundry", + "anchor": "configure-foundry" + }, + { + "depth": 2, + "title": "Create Your Contract", + "anchor": "create-your-contract" + }, + { + "depth": 2, + "title": "Compile", + "anchor": "compile" + }, + { + "depth": 2, + "title": "Deploy", + "anchor": "deploy" + }, + { + "depth": 2, + "title": "Where to Go Next", + "anchor": "where-to-go-next" + } + ], + "stats": { + "chars": 2731, + "words": 355, + "headings": 7, + "estimated_token_count_total": 598 + }, + "hash": "sha256:63defd84f302f0778c90129abbe69ecd2a5d9d83c622f2b7e5c2ffc9bcb3312f", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat", + "title": "Deploy a Basic Contract with Hardhat", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic/hardhat/", + "preview": "This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Hardhat](https://hardhat.org/){target=\\_blank}, which provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects.", + "outline": [ + { + "depth": 2, + "title": "Introduction", + "anchor": "introduction" + }, + { + "depth": 2, + "title": "Prerequisites", + "anchor": "prerequisites" + }, + { + "depth": 2, + "title": "Set Up Your Project", + "anchor": "set-up-your-project" + }, + { + "depth": 2, + "title": "Configure Hardhat", + "anchor": "configure-hardhat" + }, + { + "depth": 2, + "title": "Create Your Contract", + "anchor": "create-your-contract" + }, + { + "depth": 2, + "title": "Compile", + "anchor": "compile" + }, + { + "depth": 2, + "title": "Set Up Deployment", + "anchor": "set-up-deployment" + }, + { + "depth": 2, + "title": "Deploy the Contract", + "anchor": "deploy-the-contract" + }, + { + "depth": 2, + "title": "Where to Go Next", + "anchor": "where-to-go-next" + } + ], + "stats": { + "chars": 4051, + "words": 475, + "headings": 9, + "estimated_token_count_total": 981 + }, + "hash": "sha256:98f5c5c1a26db913e1c4c435062d214ca8c4b5f2dbed5b64d2e54c3435f06452", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", + "title": "Deploy a Basic Contract to Polkadot Hub", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-pvm.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic-pvm/", + "preview": "Deploying smart contracts to [Polkadot Hub](/smart-contracts/overview/#smart-contract-development){target=\\_blank} can be accomplished through various tools and environments, each suited to different development workflows. This guide demonstrates how to deploy a basic PolkaVM (PVM) smart contract using four popular approaches: JavaScript with [Ethers.js](https://docs.ethers.org/v6/){target=\\_blank}, [Remix IDE](https://remix.live/){target=\\_blank}, [Hardhat](https://hardhat.org/){target=\\_blank}", + "outline": [ + { + "depth": 2, + "title": "Introduction", + "anchor": "introduction" + }, + { + "depth": 2, + "title": "JavaScript with Ethers.js", + "anchor": "javascript-with-ethersjs" + }, + { + "depth": 3, + "title": "Setup", + "anchor": "setup" + }, + { + "depth": 3, + "title": "Create and Compile Your Contract", + "anchor": "create-and-compile-your-contract" + }, + { + "depth": 3, + "title": "Deploy the Contract", + "anchor": "deploy-the-contract" + }, + { + "depth": 2, + "title": "Remix IDE", + "anchor": "remix-ide" + }, + { + "depth": 3, + "title": "Access Remix", + "anchor": "access-remix" + }, + { + "depth": 3, + "title": "Compile", + "anchor": "compile" + }, + { + "depth": 3, + "title": "Deploy", + "anchor": "deploy" + }, + { + "depth": 2, + "title": "Hardhat", + "anchor": "hardhat" + }, + { + "depth": 3, + "title": "Setup", + "anchor": "setup-2" + }, + { + "depth": 3, + "title": "Configure Hardhat", + "anchor": "configure-hardhat" + }, + { + "depth": 3, + "title": "Create Your Contract", + "anchor": "create-your-contract" + }, + { + "depth": 3, + "title": "Compile", + "anchor": "compile-2" + }, + { + "depth": 3, + "title": "Set Up Deployment", + "anchor": "set-up-deployment" + }, + { + "depth": 3, + "title": "Deploy", + "anchor": "deploy-2" + }, + { + "depth": 2, + "title": "Foundry", + "anchor": "foundry" + }, + { + "depth": 3, + "title": "Setup", + "anchor": "setup-3" + }, + { + "depth": 3, + "title": "Configure Foundry", + "anchor": "configure-foundry" + }, + { + "depth": 3, + "title": "Create Your Contract", + "anchor": "create-your-contract-2" + }, + { + "depth": 3, + "title": "Compile", + "anchor": "compile-3" + }, + { + "depth": 3, + "title": "Deploy", + "anchor": "deploy-3" + }, + { + "depth": 2, + "title": "Conclusion", + "anchor": "conclusion" + }, + { + "depth": 3, + "title": "Next Steps", + "anchor": "next-steps" + } + ], + "stats": { + "chars": 13872, + "words": 1640, + "headings": 24, + "estimated_token_count_total": 3228 + }, + "hash": "sha256:8f29b0f0b56f8c136206211a858cdc5bc27bcd9119eab179a6cd306182d910cb", + "token_estimator": "heuristic-v1" + }, + { + "id": "smart-contracts-cookbook-smart-contracts-deploy-basic-remix", + "title": "Deploy a Basic Contract with Remix IDE", + "slug": "smart-contracts-cookbook-smart-contracts-deploy-basic-remix", + "categories": [ + "Smart Contracts" + ], + "raw_md_url": "https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-remix.md", + "html_url": "https://docs.polkadot.com/smart-contracts/cookbook/smart-contracts/deploy-basic/remix/", + "preview": "This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Remix IDE](https://remix.ethereum.org/){target=\\_blank}, which offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development.", + "outline": [ + { + "depth": 2, + "title": "Introduction", + "anchor": "introduction" + }, + { + "depth": 2, + "title": "Prerequisites", + "anchor": "prerequisites" + }, + { + "depth": 2, + "title": "Access Remix", + "anchor": "access-remix" + }, + { + "depth": 2, + "title": "Compile", + "anchor": "compile" + }, + { + "depth": 2, + "title": "Deploy", + "anchor": "deploy" + }, + { + "depth": 2, + "title": "Where to Go Next", + "anchor": "where-to-go-next" + } + ], + "stats": { + "chars": 2978, + "words": 430, + "headings": 6, + "estimated_token_count_total": 738 + }, + "hash": "sha256:0c00544ba0be9c0a6fa0c54bdb38045d64e95af714785b86e57f885a03b4b17a", + "token_estimator": "heuristic-v1" + }, { "id": "smart-contracts-cookbook-smart-contracts-deploy-basic", "title": "smart-contracts-cookbook-smart-contracts-deploy-basic", diff --git a/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-01.webp b/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-01.webp new file mode 100644 index 000000000..ee0b74d9f Binary files /dev/null and b/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-01.webp differ diff --git a/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-02.webp b/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-02.webp new file mode 100644 index 000000000..68a1376cb Binary files /dev/null and b/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-02.webp differ diff --git a/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-03.webp b/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-03.webp new file mode 100644 index 000000000..b9d3ab3eb Binary files /dev/null and b/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-03.webp differ diff --git a/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-01.webp b/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-01.webp new file mode 100644 index 000000000..3220bfa7d Binary files /dev/null and b/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-01.webp differ diff --git a/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-02.webp b/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-02.webp new file mode 100644 index 000000000..faca0f328 Binary files /dev/null and b/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-02.webp differ diff --git a/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-03.webp b/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-03.webp new file mode 100644 index 000000000..5828f54e3 Binary files /dev/null and b/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-03.webp differ diff --git a/llms-full.jsonl b/llms-full.jsonl index ffacd0223..5ba5a4059 100644 --- a/llms-full.jsonl +++ b/llms-full.jsonl @@ -1207,6 +1207,129 @@ {"page_id": "smart-contracts-cookbook-eth-dapps-uniswap-v2", "page_title": "Deploying Uniswap V2 on Polkadot", "index": 4, "depth": 2, "title": "Test the Contracts", "anchor": "test-the-contracts", "start_char": 6034, "end_char": 8632, "estimated_token_count": 788, "token_estimator": "heuristic-v1", "text": "## Test the Contracts\n\nYou can run the provided test suite to ensure the contracts are working as expected. The tests cover various scenarios, including creating pairs, adding liquidity, and executing swaps.\n\nTo test it locally, you can run the following commands:\n\n1. Spawn a local node for testing:\n\n ```bash\n npx hardhat node\n ```\n\n This command will spawn a local Substrate node along with the ETH-RPC adapter. The node will be available at `ws://127.0.0.1:8000` and the ETH-RPC adapter at `http://localhost:8545`.\n\n2. In a new terminal, run the tests:\n\n ```bash\n npx hardhat test --network localNode\n ```\n\nThe result should look like this:\n\n
\n npx hardhat test --network localNode\n Compiling 12 Solidity files\n Successfully compiled 12 Solidity files\n \n UniswapV2ERC20\n ✔ name, symbol, decimals, totalSupply, balanceOf, DOMAIN_SEPARATOR, PERMIT_TYPEHASH (44ms)\n ✔ approve (5128ms)\n ✔ transfer (5133ms)\n ✔ transfer:fail\n ✔ transferFrom (6270ms)\n ✔ transferFrom:max (6306ms)\n \n UniswapV2Factory\n ✔ feeTo, feeToSetter, allPairsLength\n ✔ createPair (176ms)\n ✔ createPair:reverse (1224ms)\n ✔ setFeeTo (1138ms)\n ✔ setFeeToSetter (1125ms)\n \n UniswapV2Pair\n ✔ mint (11425ms)\n ✔ getInputPrice:0 (12590ms)\n ✔ getInputPrice:1 (17600ms)\n ✔ getInputPrice:2 (17618ms)\n ✔ getInputPrice:3 (17704ms)\n ✔ getInputPrice:4 (17649ms)\n ✔ getInputPrice:5 (17594ms)\n ✔ getInputPrice:6 (13643ms)\n ✔ optimistic:0 (17647ms)\n ✔ optimistic:1 (17946ms)\n ✔ optimistic:2 (17657ms)\n ✔ optimistic:3 (21625ms)\n ✔ swap:token0 (12665ms)\n ✔ swap:token1 (17631ms)\n ✔ burn (17690ms)\n ✔ feeTo:off (23900ms)\n ✔ feeTo:on (24991ms)\n \n 28 passing (12m)\n
"} {"page_id": "smart-contracts-cookbook-eth-dapps-uniswap-v2", "page_title": "Deploying Uniswap V2 on Polkadot", "index": 5, "depth": 2, "title": "Deploy the Contracts", "anchor": "deploy-the-contracts", "start_char": 8632, "end_char": 10375, "estimated_token_count": 379, "token_estimator": "heuristic-v1", "text": "## Deploy the Contracts\n\nAfter successfully testing the contracts, you can deploy them to the local node or Polkadot Hub. The deployment script is located in the `scripts` directory and is named `deploy.js`. This script deploys the `Factory` and `Pair` contracts to the network.\n\nTo deploy the contracts, run the following command:\n\n```bash\nnpx hardhat run scripts/deploy.js --network localNode\n```\n\nThis command deploys the contracts to your local blockchain for development and testing. If you want to deploy to Polkadot Hub, you can use the following command:\n\n```bash\nnpx hardhat run scripts/deploy.js --network passetHub\n```\n\nThe command above deploys to the actual Polkadot TestNet. It requires PAS test tokens, persists on the network, and operates under real network conditions.\n\nThe deployment script will output the addresses of the deployed contracts. Save these addresses, as you will need them to interact with the contracts. For example, the output should look like this:\n\n
\n npx hardhat run scripts/deploy.js --network localNode\n Successfully compiled 12 Solidity files\n Deploying contracts using 0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac\n Deploying UniswapV2ERC20...\n ETH deployed to : 0x7acc1aC65892CF3547b1b0590066FB93199b430D\n Deploying UniswapV2Factory...\n Factory deployed to : 0x85b108660f47caDfAB9e0503104C08C1c96e0DA9\n Deploying UniswapV2Pair with JsonRpcProvider workaround...\n Pair deployed to : 0xF0e46847c8bFD122C4b5EEE1D4494FF7C5FC5104\n
"} {"page_id": "smart-contracts-cookbook-eth-dapps-uniswap-v2", "page_title": "Deploying Uniswap V2 on Polkadot", "index": 6, "depth": 2, "title": "Conclusion", "anchor": "conclusion", "start_char": 10375, "end_char": 11280, "estimated_token_count": 152, "token_estimator": "heuristic-v1", "text": "## Conclusion\n\nThis tutorial guided you through deploying Uniswap V2 contracts to Polkadot Hub. This implementation brings the powerful AMM architecture to the Polkadot ecosystem, laying the foundation for the decentralized trading of ERC-20 token pairs.\n\nBy following this guide, you've gained practical experience with:\n\n- Setting up a Hardhat project for deploying to Polkadot Hub.\n- Understanding the Uniswap V2 architecture.\n- Testing Uniswap V2 contracts in a local environment.\n- Deploying contracts to both local and testnet environments.\n\nTo build on this foundation, you could extend this project by implementing functionality to create liquidity pools, execute token swaps, and build a user interface for interacting with your deployment.\n\nThis knowledge can be leveraged to build more complex DeFi applications or to integrate Uniswap V2 functionality into your existing projects on Polkadot."} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 27, "end_char": 1362, "estimated_token_count": 322, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nDeploying smart contracts to [Polkadot Hub](/smart-contracts/overview/#smart-contract-development){target=\\_blank} can be accomplished through various tools and environments, each suited to different development workflows. This guide demonstrates how to deploy a basic PolkaVM (PVM) smart contract using four popular approaches: JavaScript with [Ethers.js](https://docs.ethers.org/v6/){target=\\_blank}, [Remix IDE](https://remix.live/){target=\\_blank}, [Hardhat](https://hardhat.org/){target=\\_blank}, and [Foundry](https://getfoundry.sh/){target=\\_blank}.\n\nAll these tools leverage the `revive` compiler to transform Solidity smart contracts into PolkaVM bytecode, making them compatible with Polkadot Hub's native smart contract environment. Whether you prefer working with lightweight JavaScript libraries, visual browser-based IDEs, comprehensive development frameworks, or fast command-line toolkits, this guide covers the deployment process for each approach.\n\n**Prerequisites:**\n\n- Basic understanding of Solidity programming.\n- [Node.js](https://nodejs.org/en/download){target=\\_blank} v22.13.1 or later (for JavaScript/Hardhat approaches).\n- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\\_blank}).\n- A wallet with a private key for signing transactions."} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 1, "depth": 2, "title": "JavaScript with Ethers.js", "anchor": "javascript-with-ethersjs", "start_char": 1362, "end_char": 1645, "estimated_token_count": 45, "token_estimator": "heuristic-v1", "text": "## JavaScript with Ethers.js\n\nEthers.js provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications."} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 2, "depth": 3, "title": "Setup", "anchor": "setup", "start_char": 1645, "end_char": 1818, "estimated_token_count": 39, "token_estimator": "heuristic-v1", "text": "### Setup\n\nFirst, initialize your project and install dependencies:\n\n```bash\nmkdir ethers-deployment\ncd ethers-deployment\nnpm init -y\nnpm install ethers @parity/resolc\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 3, "depth": 3, "title": "Create and Compile Your Contract", "anchor": "create-and-compile-your-contract", "start_char": 1818, "end_char": 3875, "estimated_token_count": 491, "token_estimator": "heuristic-v1", "text": "### Create and Compile Your Contract\n\nCreate a simple storage contract in `contracts/Storage.sol`:\n\n```solidity title=\"contracts/Storage.sol\"\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ncontract Storage {\n uint256 private storedNumber;\n\n function store(uint256 num) public {\n storedNumber = num;\n }\n\n function retrieve() public view returns (uint256) {\n return storedNumber;\n }\n}\n```\n\nCreate a compilation script `compile.js`:\n\n```javascript title=\"compile.js\"\nconst { compile } = require('@parity/resolc');\nconst { readFileSync, writeFileSync } = require('fs');\nconst { basename, join } = require('path');\n\nconst compileContract = async (solidityFilePath, outputDir) => {\n try {\n // Read the Solidity file\n const source = readFileSync(solidityFilePath, 'utf8');\n\n // Construct the input object for the compiler\n const input = {\n [basename(solidityFilePath)]: { content: source },\n };\n\n console.log(`Compiling contract: ${basename(solidityFilePath)}...`);\n\n // Compile the contract\n const out = await compile(input);\n\n for (const contracts of Object.values(out.contracts)) {\n for (const [name, contract] of Object.entries(contracts)) {\n console.log(`Compiled contract: ${name}`);\n\n // Write the ABI\n const abiPath = join(outputDir, `${name}.json`);\n writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2));\n console.log(`ABI saved to ${abiPath}`);\n\n // Write the bytecode\n const bytecodePath = join(outputDir, `${name}.polkavm`);\n writeFileSync(\n bytecodePath,\n Buffer.from(contract.evm.bytecode.object, 'hex'),\n );\n console.log(`Bytecode saved to ${bytecodePath}`);\n }\n }\n } catch (error) {\n console.error('Error compiling contracts:', error);\n }\n};\n\nconst solidityFilePath = join(__dirname, 'contracts/Storage.sol');\nconst outputDir = join(__dirname, 'contracts');\n\ncompileContract(solidityFilePath, outputDir);\n```\n\nRun the compilation:\n\n```bash\nnode compile.js\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 4, "depth": 3, "title": "Deploy the Contract", "anchor": "deploy-the-contract", "start_char": 3875, "end_char": 7017, "estimated_token_count": 714, "token_estimator": "heuristic-v1", "text": "### Deploy the Contract\n\nCreate a deployment script `deploy.js`:\n\n```javascript title=\"deploy.js\"\nconst { writeFileSync, existsSync, readFileSync } = require('fs');\nconst { join } = require('path');\nconst { ethers, JsonRpcProvider } = require('ethers');\n\nconst codegenDir = join(__dirname);\n\n// Creates a provider with specified RPC URL and chain details\nconst createProvider = (rpcUrl, chainId, chainName) => {\n const provider = new JsonRpcProvider(rpcUrl, {\n chainId: chainId,\n name: chainName,\n });\n return provider;\n};\n\n// Reads and parses the ABI file for a given contract\nconst getAbi = (contractName) => {\n try {\n return JSON.parse(\n readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'),\n );\n } catch (error) {\n console.error(\n `Could not find ABI for contract ${contractName}:`,\n error.message,\n );\n throw error;\n }\n};\n\n// Reads the compiled bytecode for a given contract\nconst getByteCode = (contractName) => {\n try {\n const bytecodePath = join(\n codegenDir,\n 'contracts',\n `${contractName}.polkavm`,\n );\n return `0x${readFileSync(bytecodePath).toString('hex')}`;\n } catch (error) {\n console.error(\n `Could not find bytecode for contract ${contractName}:`,\n error.message,\n );\n throw error;\n }\n};\n\nconst deployContract = async (contractName, mnemonic, providerConfig) => {\n console.log(`Deploying ${contractName}...`);\n\n try {\n // Step 1: Set up provider and wallet\n const provider = createProvider(\n providerConfig.rpc,\n providerConfig.chainId,\n providerConfig.name,\n );\n const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic);\n const wallet = walletMnemonic.connect(provider);\n\n // Step 2: Create and deploy the contract\n const factory = new ethers.ContractFactory(\n getAbi(contractName),\n getByteCode(contractName),\n wallet,\n );\n const contract = await factory.deploy();\n await contract.waitForDeployment();\n\n // Step 3: Save deployment information\n const address = await contract.getAddress();\n console.log(`Contract ${contractName} deployed at: ${address}`);\n\n const addressesFile = join(codegenDir, 'contract-address.json');\n const addresses = existsSync(addressesFile)\n ? JSON.parse(readFileSync(addressesFile, 'utf8'))\n : {};\n addresses[contractName] = address;\n writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8');\n } catch (error) {\n console.error(`Failed to deploy contract ${contractName}:`, error);\n }\n};\n\nconst providerConfig = {\n rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io',\n chainId: 420420422,\n name: 'polkadot-hub-testnet',\n};\n\nconst mnemonic = 'INSERT_MNEMONIC';\n\ndeployContract('Storage', mnemonic, providerConfig);\n```\n\nReplace the `INSERT_MNEMONIC` placeholder with your actual mnemonic.\n\nExecute the deployment:\n\n```bash\nnode deploy.js\n```\n\nAfter running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions."} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 5, "depth": 2, "title": "Remix IDE", "anchor": "remix-ide", "start_char": 7017, "end_char": 7225, "estimated_token_count": 35, "token_estimator": "heuristic-v1", "text": "## Remix IDE\n\nRemix IDE offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development."} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 6, "depth": 3, "title": "Access Remix", "anchor": "access-remix", "start_char": 7225, "end_char": 7750, "estimated_token_count": 138, "token_estimator": "heuristic-v1", "text": "### Access Remix\n\nNavigate to [https://remix.polkadot.io/](https://remix.polkadot.io/){target=\\_blank} in your web browser.\n\nThe interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file:\n\n![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-01.webp)"} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 7, "depth": 3, "title": "Compile", "anchor": "compile", "start_char": 7750, "end_char": 8149, "estimated_token_count": 106, "token_estimator": "heuristic-v1", "text": "### Compile\n\n1. To compile your contract:\n 1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar.\n 2. Click **Compile Storage.sol** or press `Ctrl+S`.\n\n ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-02.webp)\n\nCompilation errors and warnings appear in the terminal panel at the bottom of the screen."} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 8, "depth": 3, "title": "Deploy", "anchor": "deploy", "start_char": 8149, "end_char": 8651, "estimated_token_count": 127, "token_estimator": "heuristic-v1", "text": "### Deploy\n\n1. Navigate to the **Deploy & Run Transactions** tab.\n2. Click the **Environment** dropdown and select **Injected Provider - MetaMask** (ensure your MetaMask wallet is connected to Polkadot Hub TestNet).\n3. Click **Deploy**.\n4. Approve the transaction in your MetaMask wallet.\n\n ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-03.webp)\n\nYour deployed contract will appear in the **Deployed Contracts** section, ready for interaction."} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 9, "depth": 2, "title": "Hardhat", "anchor": "hardhat", "start_char": 8651, "end_char": 8853, "estimated_token_count": 33, "token_estimator": "heuristic-v1", "text": "## Hardhat\n\nHardhat provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects."} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 10, "depth": 3, "title": "Setup", "anchor": "setup-2", "start_char": 8853, "end_char": 9195, "estimated_token_count": 89, "token_estimator": "heuristic-v1", "text": "### Setup\n\nInitialize your Hardhat project:\n\n```bash\nmkdir hardhat-deployment\ncd hardhat-deployment\nnpm init -y\nnpm install --save-dev @parity/hardhat-polkadot@0.1.9\nnpx hardhat-polkadot init\n```\n\nSelect **Create a JavaScript project** when prompted.\n\nComplete the setup:\n\n```bash\necho '/ignition/deployments/' >> .gitignore\nnpm install\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 11, "depth": 3, "title": "Configure Hardhat", "anchor": "configure-hardhat", "start_char": 9195, "end_char": 10240, "estimated_token_count": 245, "token_estimator": "heuristic-v1", "text": "### Configure Hardhat\n\nEdit `hardhat.config.js`:\n\n```javascript title=\"hardhat.config.js\" hl_lines=\"21-26\"\nrequire(\"@nomicfoundation/hardhat-toolbox\")\nrequire(\"@parity/hardhat-polkadot\")\n\n/** @type import('hardhat/config').HardhatUserConfig */\nmodule.exports = {\n solidity: \"0.8.28\",\n resolc: {\n compilerSource: \"npm\",\n },\n networks: {\n hardhat: {\n polkavm: true,\n forking: {\n url: \"https://testnet-passet-hub.polkadot.io\",\n },\n adapterConfig: {\n adapterBinaryPath: \"../bin/eth-rpc\",\n dev: true,\n },\n },\n polkadotHubTestnet: {\n polkavm: true,\n url: 'https://testnet-passet-hub-eth-rpc.polkadot.io',\n chainId: 420420422,\n accounts: [vars.get('PRIVATE_KEY')],\n },\n },\n}\n```\n\nRun the following command to set the private key:\n\n```bash\nnpx hardhat vars set PRIVATE_KEY \"INSERT_PRIVATE_KEY\"\n```\n\nReplace `INSERT_PRIVATE_KEY` with your actual private key."} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 12, "depth": 3, "title": "Create Your Contract", "anchor": "create-your-contract", "start_char": 10240, "end_char": 10621, "estimated_token_count": 80, "token_estimator": "heuristic-v1", "text": "### Create Your Contract\n\nReplace the default contract in `contracts/Storage.sol`:\n\n```solidity\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ncontract Storage {\n uint256 private storedNumber;\n\n function store(uint256 num) public {\n storedNumber = num;\n }\n\n function retrieve() public view returns (uint256) {\n return storedNumber;\n }\n}\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 13, "depth": 3, "title": "Compile", "anchor": "compile-2", "start_char": 10621, "end_char": 10667, "estimated_token_count": 14, "token_estimator": "heuristic-v1", "text": "### Compile\n\n```bash\nnpx hardhat compile\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 14, "depth": 3, "title": "Set Up Deployment", "anchor": "set-up-deployment", "start_char": 10667, "end_char": 10976, "estimated_token_count": 83, "token_estimator": "heuristic-v1", "text": "### Set Up Deployment\n\nCreate a deployment module in `ignition/modules/Storage.js`:\n\n```javascript\nconst { buildModule } = require('@nomicfoundation/hardhat-ignition/modules');\n\nmodule.exports = buildModule('StorageModule', (m) => {\n const storage = m.contract('Storage');\n return { storage };\n});\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 15, "depth": 3, "title": "Deploy", "anchor": "deploy-2", "start_char": 10976, "end_char": 11121, "estimated_token_count": 34, "token_estimator": "heuristic-v1", "text": "### Deploy\n\nDeploy to Polkadot Hub TestNet:\n\n```bash\nnpx hardhat ignition deploy ./ignition/modules/Storage.js --network polkadotHubTestnet\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 16, "depth": 2, "title": "Foundry", "anchor": "foundry", "start_char": 11121, "end_char": 11307, "estimated_token_count": 35, "token_estimator": "heuristic-v1", "text": "## Foundry\n\nFoundry offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment."} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 17, "depth": 3, "title": "Setup", "anchor": "setup-3", "start_char": 11307, "end_char": 11585, "estimated_token_count": 69, "token_estimator": "heuristic-v1", "text": "### Setup\n\nInstall Foundry for Polkadot:\n\n```bash\ncurl -L https://raw.githubusercontent.com/paritytech/foundry-polkadot/refs/heads/master/foundryup/install | bash\nfoundryup-polkadot\n```\n\nInitialize your project:\n\n```bash\nforge init foundry-deployment\ncd foundry-deployment\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 18, "depth": 3, "title": "Configure Foundry", "anchor": "configure-foundry", "start_char": 11585, "end_char": 11837, "estimated_token_count": 75, "token_estimator": "heuristic-v1", "text": "### Configure Foundry\n\nEdit `foundry.toml`:\n\n```toml\n[profile.default]\nsrc = \"src\"\nout = \"out\"\nlibs = [\"lib\"]\n\n[profile.default.resolc]\nresolc_compile = true\n\n[rpc_endpoints]\npolkadot_hub_testnet = \"https://testnet-passet-hub-eth-rpc.polkadot.io\"\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 19, "depth": 3, "title": "Create Your Contract", "anchor": "create-your-contract-2", "start_char": 11837, "end_char": 12212, "estimated_token_count": 80, "token_estimator": "heuristic-v1", "text": "### Create Your Contract\n\nReplace the default contract in `src/Storage.sol`:\n\n```solidity\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ncontract Storage {\n uint256 private storedNumber;\n\n function store(uint256 num) public {\n storedNumber = num;\n }\n\n function retrieve() public view returns (uint256) {\n return storedNumber;\n }\n}\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 20, "depth": 3, "title": "Compile", "anchor": "compile-3", "start_char": 12212, "end_char": 12392, "estimated_token_count": 46, "token_estimator": "heuristic-v1", "text": "### Compile\n\n```bash\nforge build --resolc\n```\n\nVerify the compilation by inspecting the bytecode (should start with `0x505`):\n\n```bash\nforge inspect Storage bytecode --resolc\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 21, "depth": 3, "title": "Deploy", "anchor": "deploy-3", "start_char": 12392, "end_char": 12573, "estimated_token_count": 41, "token_estimator": "heuristic-v1", "text": "### Deploy\n\nDeploy to Polkadot Hub TestNet:\n\n```bash\nforge create Storage \\\n --rpc-url polkadot_hub_testnet \\\n --private-key YOUR_PRIVATE_KEY \\\n --resolc --broadcast\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 22, "depth": 2, "title": "Conclusion", "anchor": "conclusion", "start_char": 12573, "end_char": 13294, "estimated_token_count": 131, "token_estimator": "heuristic-v1", "text": "## Conclusion\n\nThis guide has demonstrated four different approaches to deploying smart contracts on Polkadot Hub. Each method offers distinct advantages:\n\n- **Ethers.js**: Best for lightweight, programmatic deployments and application integration\n- **Remix IDE**: Ideal for rapid prototyping, learning, and visual development\n- **Hardhat**: Perfect for professional workflows requiring comprehensive testing and debugging\n- **Foundry**: Excellent for developers who prefer fast, command-line driven development\n\nAll approaches use the `resolc` compiler to generate PolkaVM-compatible bytecode, ensuring your contracts run natively on Polkadot Hub. Choose the tool that best fits your workflow and project requirements."} +{"page_id": "smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 23, "depth": 3, "title": "Next Steps", "anchor": "next-steps", "start_char": 13294, "end_char": 13872, "estimated_token_count": 156, "token_estimator": "heuristic-v1", "text": "### Next Steps\n\n- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide.\n- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide.\n- Check out in details each [development environment](/smart-contracts/dev-environments/)."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-ethers-js", "page_title": "JavaScript with Ethers.js", "index": 0, "depth": 3, "title": "Setup", "anchor": "setup", "start_char": 615, "end_char": 792, "estimated_token_count": 48, "token_estimator": "heuristic-v1", "text": "### Setup\n\nFirst, initialize your project and install dependencies:\n\n```bash\nmkdir ethers-deployment\ncd ethers-deployment\nnpm init -y\nnpm install ethers@6.15.0 solc@0.8.30\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-ethers-js", "page_title": "JavaScript with Ethers.js", "index": 1, "depth": 3, "title": "Create and Compile Your Contract", "anchor": "create-and-compile-your-contract", "start_char": 792, "end_char": 3219, "estimated_token_count": 572, "token_estimator": "heuristic-v1", "text": "### Create and Compile Your Contract\n\nCreate a simple storage contract in `contracts/Storage.sol`:\n\n```solidity title=\"contracts/Storage.sol\"\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ncontract Storage {\n uint256 private storedNumber;\n\n function store(uint256 num) public {\n storedNumber = num;\n }\n\n function retrieve() public view returns (uint256) {\n return storedNumber;\n }\n}\n```\n\nCreate a compilation script `compile.js`:\n\n```javascript title=\"compile.js\"\nconst solc = require('solc');\nconst { readFileSync, writeFileSync } = require('fs');\nconst { basename, join } = require('path');\n\nconst compileContract = async (solidityFilePath, outputDir) => {\n try {\n // Read the Solidity file\n const source = readFileSync(solidityFilePath, 'utf8');\n\n // Construct the input object for the compiler\n const input = {\n language: 'Solidity',\n sources: {\n [basename(solidityFilePath)]: { content: source },\n },\n settings: {\n outputSelection: {\n '*': {\n '*': ['*'],\n },\n },\n },\n };\n\n console.log(`Compiling contract: ${basename(solidityFilePath)}...`);\n\n // Compile the contract\n const output = JSON.parse(solc.compile(JSON.stringify(input)));\n\n if (output.errors) {\n output.errors.forEach(error => {\n console.error('Compilation error:', error.message);\n });\n return;\n }\n\n for (const contracts of Object.values(output.contracts)) {\n for (const [name, contract] of Object.entries(contracts)) {\n console.log(`Compiled contract: ${name}`);\n\n // Write the ABI\n const abiPath = join(outputDir, `${name}.json`);\n writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2));\n console.log(`ABI saved to ${abiPath}`);\n\n // Write the bytecode\n const bytecodePath = join(outputDir, `${name}.bin`);\n writeFileSync(bytecodePath, \n Buffer.from(\n contract.evm.bytecode.object,\n 'hex'\n ));\n console.log(`Bytecode saved to ${bytecodePath}`);\n }\n }\n } catch (error) {\n console.error('Error compiling contracts:', error);\n }\n};\n\nconst solidityFilePath = join(__dirname, 'contracts/Storage.sol');\nconst outputDir = join(__dirname, 'contracts');\n\ncompileContract(solidityFilePath, outputDir);\n```\n\nRun the compilation:\n\n```bash\nnode compile.js\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-ethers-js", "page_title": "JavaScript with Ethers.js", "index": 2, "depth": 3, "title": "Deploy the Contract", "anchor": "deploy-the-contract", "start_char": 3219, "end_char": 6357, "estimated_token_count": 714, "token_estimator": "heuristic-v1", "text": "### Deploy the Contract\n\nCreate a deployment script `deploy.js`:\n\n```javascript title=\"deploy.js\"\nconst { writeFileSync, existsSync, readFileSync } = require('fs');\nconst { join } = require('path');\nconst { ethers, JsonRpcProvider } = require('ethers');\n\nconst codegenDir = join(__dirname);\n\n// Creates a provider with specified RPC URL and chain details\nconst createProvider = (rpcUrl, chainId, chainName) => {\n const provider = new JsonRpcProvider(rpcUrl, {\n chainId: chainId,\n name: chainName,\n });\n return provider;\n};\n\n// Reads and parses the ABI file for a given contract\nconst getAbi = (contractName) => {\n try {\n return JSON.parse(\n readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'),\n );\n } catch (error) {\n console.error(\n `Could not find ABI for contract ${contractName}:`,\n error.message,\n );\n throw error;\n }\n};\n\n// Reads the compiled bytecode for a given contract\nconst getByteCode = (contractName) => {\n try {\n const bytecodePath = join(\n codegenDir,\n 'contracts',\n `${contractName}.bin`,\n );\n return `0x${readFileSync(bytecodePath).toString('hex')}`;\n } catch (error) {\n console.error(\n `Could not find bytecode for contract ${contractName}:`,\n error.message,\n );\n throw error;\n }\n};\n\nconst deployContract = async (contractName, mnemonic, providerConfig) => {\n console.log(`Deploying ${contractName}...`);\n\n try {\n // Step 1: Set up provider and wallet\n const provider = createProvider(\n providerConfig.rpc,\n providerConfig.chainId,\n providerConfig.name,\n );\n const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic);\n const wallet = walletMnemonic.connect(provider);\n\n // Step 2: Create and deploy the contract\n const factory = new ethers.ContractFactory(\n getAbi(contractName),\n getByteCode(contractName),\n wallet,\n );\n const contract = await factory.deploy();\n await contract.waitForDeployment();\n\n // Step 3: Save deployment information\n const address = await contract.getAddress();\n console.log(`Contract ${contractName} deployed at: ${address}`);\n\n const addressesFile = join(codegenDir, 'contract-address.json');\n const addresses = existsSync(addressesFile)\n ? JSON.parse(readFileSync(addressesFile, 'utf8'))\n : {};\n addresses[contractName] = address;\n writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8');\n } catch (error) {\n console.error(`Failed to deploy contract ${contractName}:`, error);\n }\n};\n\nconst providerConfig = {\n rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io',\n chainId: 420420422,\n name: 'polkadot-hub-testnet',\n};\n\nconst mnemonic = 'INSERT_MNEMONIC';\n\ndeployContract('Storage', mnemonic, providerConfig);\n```\n\nReplace the `INSERT_MNEMONIC` placeholder with your actual mnemonic.\n\nExecute the deployment:\n\n```bash\nnode deploy.js\n```\n\nAfter running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-ethers-js", "page_title": "JavaScript with Ethers.js", "index": 3, "depth": 3, "title": "Next Steps", "anchor": "next-steps", "start_char": 6357, "end_char": 6935, "estimated_token_count": 156, "token_estimator": "heuristic-v1", "text": "### Next Steps\n\n- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide.\n- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide.\n- Check out in details each [development environment](/smart-contracts/dev-environments/)."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-foundry", "page_title": "Foundry", "index": 0, "depth": 3, "title": "Setup", "anchor": "setup", "start_char": 452, "end_char": 639, "estimated_token_count": 49, "token_estimator": "heuristic-v1", "text": "### Setup\n\nInstall Foundry:\n\n```bash\ncurl -L https://foundry.paradigm.xyz | bash\nfoundryup\n```\n\nInitialize your project:\n\n```bash\nforge init foundry-deployment\ncd foundry-deployment\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-foundry", "page_title": "Foundry", "index": 1, "depth": 3, "title": "Configure Foundry", "anchor": "configure-foundry", "start_char": 639, "end_char": 843, "estimated_token_count": 65, "token_estimator": "heuristic-v1", "text": "### Configure Foundry\n\nEdit `foundry.toml`:\n\n```toml\n[profile.default]\nsrc = \"src\"\nout = \"out\"\nlibs = [\"lib\"]\n\n[rpc_endpoints]\npolkadot_hub_testnet = \"https://testnet-passet-hub-eth-rpc.polkadot.io\"\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-foundry", "page_title": "Foundry", "index": 2, "depth": 3, "title": "Create Your Contract", "anchor": "create-your-contract", "start_char": 843, "end_char": 1242, "estimated_token_count": 89, "token_estimator": "heuristic-v1", "text": "### Create Your Contract\n\nReplace the default contract in `src/Storage.sol`:\n\n```solidity title=\"src/Storage.sol\"\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ncontract Storage {\n uint256 private storedNumber;\n\n function store(uint256 num) public {\n storedNumber = num;\n }\n\n function retrieve() public view returns (uint256) {\n return storedNumber;\n }\n}\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-foundry", "page_title": "Foundry", "index": 3, "depth": 3, "title": "Compile", "anchor": "compile", "start_char": 1242, "end_char": 1376, "estimated_token_count": 32, "token_estimator": "heuristic-v1", "text": "### Compile\n\n```bash\nforge build\n```\n\nVerify the compilation by inspecting the bytecode:\n\n```bash\nforge inspect Storage bytecode\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-foundry", "page_title": "Foundry", "index": 4, "depth": 3, "title": "Deploy", "anchor": "deploy", "start_char": 1376, "end_char": 1547, "estimated_token_count": 38, "token_estimator": "heuristic-v1", "text": "### Deploy\n\nDeploy to Polkadot Hub TestNet:\n\n```bash\nforge create Storage \\\n --rpc-url polkadot_hub_testnet \\\n --private-key YOUR_PRIVATE_KEY \\\n --broadcast\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-foundry", "page_title": "Foundry", "index": 5, "depth": 3, "title": "Next Steps", "anchor": "next-steps", "start_char": 1547, "end_char": 2125, "estimated_token_count": 156, "token_estimator": "heuristic-v1", "text": "### Next Steps\n\n- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide.\n- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide.\n- Check out in details each [development environment](/smart-contracts/dev-environments/)."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-hardhat", "page_title": "hardhat", "index": 0, "depth": 3, "title": "Setup", "anchor": "setup", "start_char": 545, "end_char": 669, "estimated_token_count": 29, "token_estimator": "heuristic-v1", "text": "### Setup\n\nInitialize your Hardhat project:\n\n```bash\nmkdir hardhat-deployment\ncd hardhat-deployment\nnpx hardhat --init\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-hardhat", "page_title": "hardhat", "index": 1, "depth": 3, "title": "Configure Hardhat", "anchor": "configure-hardhat", "start_char": 669, "end_char": 1851, "estimated_token_count": 272, "token_estimator": "heuristic-v1", "text": "### Configure Hardhat\n\nEdit `hardhat.config.js`:\n\n```javascript title=\"hardhat.config.js\" hl_lines=\"39-43\"\nimport type { HardhatUserConfig } from \"hardhat/config\";\n\nimport hardhatToolboxViemPlugin from \"@nomicfoundation/hardhat-toolbox-viem\";\nimport { configVariable } from \"hardhat/config\";\n\nconst config: HardhatUserConfig = {\n plugins: [hardhatToolboxViemPlugin],\n solidity: {\n profiles: {\n default: {\n version: \"0.8.28\",\n },\n production: {\n version: \"0.8.28\",\n settings: {\n optimizer: {\n enabled: true,\n runs: 200,\n },\n },\n },\n },\n },\n networks: {\n hardhatMainnet: {\n type: \"edr-simulated\",\n chainType: \"l1\",\n },\n hardhatOp: {\n type: \"edr-simulated\",\n chainType: \"op\",\n },\n sepolia: {\n type: \"http\",\n chainType: \"l1\",\n url: configVariable(\"SEPOLIA_RPC_URL\"),\n accounts: [configVariable(\"SEPOLIA_PRIVATE_KEY\")],\n },\n polkadotHubTestnet: {\n url: 'https://testnet-passet-hub-eth-rpc.polkadot.io',\n chainId: 420420422,\n accounts: [configVariable(\"PRIVATE_KEY\")],\n },\n },\n};\n\nexport default config;\n\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-hardhat", "page_title": "hardhat", "index": 2, "depth": 3, "title": "Create Your Contract", "anchor": "create-your-contract", "start_char": 1851, "end_char": 2232, "estimated_token_count": 80, "token_estimator": "heuristic-v1", "text": "### Create Your Contract\n\nReplace the default contract in `contracts/Storage.sol`:\n\n```solidity\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ncontract Storage {\n uint256 private storedNumber;\n\n function store(uint256 num) public {\n storedNumber = num;\n }\n\n function retrieve() public view returns (uint256) {\n return storedNumber;\n }\n}\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-hardhat", "page_title": "hardhat", "index": 3, "depth": 3, "title": "Compile", "anchor": "compile", "start_char": 2232, "end_char": 2276, "estimated_token_count": 14, "token_estimator": "heuristic-v1", "text": "### Compile\n\n```bash\nnpx hardhat build\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-hardhat", "page_title": "hardhat", "index": 4, "depth": 3, "title": "Set Up Deployment", "anchor": "set-up-deployment", "start_char": 2276, "end_char": 2614, "estimated_token_count": 89, "token_estimator": "heuristic-v1", "text": "### Set Up Deployment\n\nCreate a deployment module in `ignition/modules/Storage.ts`:\n\n```typescript title=\"ignition/modules/Storage.ts\"\nimport { buildModule } from '@nomicfoundation/hardhat-ignition/modules';\n\nexport default buildModule('StorageModule', (m) => {\n const storage = m.contract('Storage');\n return { storage };\n});\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-hardhat", "page_title": "hardhat", "index": 5, "depth": 3, "title": "Deploy", "anchor": "deploy", "start_char": 2614, "end_char": 2758, "estimated_token_count": 32, "token_estimator": "heuristic-v1", "text": "### Deploy\n\nDeploy to Polkadot Hub TestNet:\n\n```bash\nnpx hardhat ignition deploy ignition/modules/Storage.ts --network polkadotHubTestnet \n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-hardhat", "page_title": "hardhat", "index": 6, "depth": 3, "title": "Next Steps", "anchor": "next-steps", "start_char": 2758, "end_char": 3336, "estimated_token_count": 156, "token_estimator": "heuristic-v1", "text": "### Next Steps\n\n- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide.\n- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide.\n- Check out in details each [development environment](/smart-contracts/dev-environments/)."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-remix", "page_title": "Remix IDE", "index": 0, "depth": 3, "title": "Access Remix", "anchor": "access-remix", "start_char": 469, "end_char": 994, "estimated_token_count": 138, "token_estimator": "heuristic-v1", "text": "### Access Remix\n\nNavigate to [https://remix.polkadot.io/](https://remix.polkadot.io/){target=\\_blank} in your web browser.\n\nThe interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file:\n\n![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-01.webp)"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-remix", "page_title": "Remix IDE", "index": 1, "depth": 3, "title": "Compile", "anchor": "compile", "start_char": 994, "end_char": 1393, "estimated_token_count": 106, "token_estimator": "heuristic-v1", "text": "### Compile\n\n1. To compile your contract:\n 1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar.\n 2. Click **Compile Storage.sol** or press `Ctrl+S`.\n\n ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-02.webp)\n\nCompilation errors and warnings appear in the terminal panel at the bottom of the screen."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-remix", "page_title": "Remix IDE", "index": 2, "depth": 3, "title": "Deploy", "anchor": "deploy", "start_char": 1393, "end_char": 1895, "estimated_token_count": 127, "token_estimator": "heuristic-v1", "text": "### Deploy\n\n1. Navigate to the **Deploy & Run Transactions** tab.\n2. Click the **Environment** dropdown and select **Injected Provider - MetaMask** (ensure your MetaMask wallet is connected to Polkadot Hub TestNet).\n3. Click **Deploy**.\n4. Approve the transaction in your MetaMask wallet.\n\n ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-03.webp)\n\nYour deployed contract will appear in the **Deployed Contracts** section, ready for interaction."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-remix", "page_title": "Remix IDE", "index": 3, "depth": 3, "title": "Next Steps", "anchor": "next-steps", "start_char": 1895, "end_char": 2473, "estimated_token_count": 156, "token_estimator": "heuristic-v1", "text": "### Next Steps\n\n- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide.\n- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide.\n- Check out in details each [development environment](/smart-contracts/dev-environments/)."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-ethers-js", "page_title": "JavaScript with Ethers.js", "index": 0, "depth": 3, "title": "Setup", "anchor": "setup", "start_char": 615, "end_char": 792, "estimated_token_count": 48, "token_estimator": "heuristic-v1", "text": "### Setup\n\nFirst, initialize your project and install dependencies:\n\n```bash\nmkdir ethers-deployment\ncd ethers-deployment\nnpm init -y\nnpm install ethers@6.15.0 solc@0.8.30\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-ethers-js", "page_title": "JavaScript with Ethers.js", "index": 1, "depth": 3, "title": "Create and Compile Your Contract", "anchor": "create-and-compile-your-contract", "start_char": 792, "end_char": 3219, "estimated_token_count": 572, "token_estimator": "heuristic-v1", "text": "### Create and Compile Your Contract\n\nCreate a simple storage contract in `contracts/Storage.sol`:\n\n```solidity title=\"contracts/Storage.sol\"\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ncontract Storage {\n uint256 private storedNumber;\n\n function store(uint256 num) public {\n storedNumber = num;\n }\n\n function retrieve() public view returns (uint256) {\n return storedNumber;\n }\n}\n```\n\nCreate a compilation script `compile.js`:\n\n```javascript title=\"compile.js\"\nconst solc = require('solc');\nconst { readFileSync, writeFileSync } = require('fs');\nconst { basename, join } = require('path');\n\nconst compileContract = async (solidityFilePath, outputDir) => {\n try {\n // Read the Solidity file\n const source = readFileSync(solidityFilePath, 'utf8');\n\n // Construct the input object for the compiler\n const input = {\n language: 'Solidity',\n sources: {\n [basename(solidityFilePath)]: { content: source },\n },\n settings: {\n outputSelection: {\n '*': {\n '*': ['*'],\n },\n },\n },\n };\n\n console.log(`Compiling contract: ${basename(solidityFilePath)}...`);\n\n // Compile the contract\n const output = JSON.parse(solc.compile(JSON.stringify(input)));\n\n if (output.errors) {\n output.errors.forEach(error => {\n console.error('Compilation error:', error.message);\n });\n return;\n }\n\n for (const contracts of Object.values(output.contracts)) {\n for (const [name, contract] of Object.entries(contracts)) {\n console.log(`Compiled contract: ${name}`);\n\n // Write the ABI\n const abiPath = join(outputDir, `${name}.json`);\n writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2));\n console.log(`ABI saved to ${abiPath}`);\n\n // Write the bytecode\n const bytecodePath = join(outputDir, `${name}.bin`);\n writeFileSync(bytecodePath, \n Buffer.from(\n contract.evm.bytecode.object,\n 'hex'\n ));\n console.log(`Bytecode saved to ${bytecodePath}`);\n }\n }\n } catch (error) {\n console.error('Error compiling contracts:', error);\n }\n};\n\nconst solidityFilePath = join(__dirname, 'contracts/Storage.sol');\nconst outputDir = join(__dirname, 'contracts');\n\ncompileContract(solidityFilePath, outputDir);\n```\n\nRun the compilation:\n\n```bash\nnode compile.js\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-ethers-js", "page_title": "JavaScript with Ethers.js", "index": 2, "depth": 3, "title": "Deploy the Contract", "anchor": "deploy-the-contract", "start_char": 3219, "end_char": 6357, "estimated_token_count": 714, "token_estimator": "heuristic-v1", "text": "### Deploy the Contract\n\nCreate a deployment script `deploy.js`:\n\n```javascript title=\"deploy.js\"\nconst { writeFileSync, existsSync, readFileSync } = require('fs');\nconst { join } = require('path');\nconst { ethers, JsonRpcProvider } = require('ethers');\n\nconst codegenDir = join(__dirname);\n\n// Creates a provider with specified RPC URL and chain details\nconst createProvider = (rpcUrl, chainId, chainName) => {\n const provider = new JsonRpcProvider(rpcUrl, {\n chainId: chainId,\n name: chainName,\n });\n return provider;\n};\n\n// Reads and parses the ABI file for a given contract\nconst getAbi = (contractName) => {\n try {\n return JSON.parse(\n readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'),\n );\n } catch (error) {\n console.error(\n `Could not find ABI for contract ${contractName}:`,\n error.message,\n );\n throw error;\n }\n};\n\n// Reads the compiled bytecode for a given contract\nconst getByteCode = (contractName) => {\n try {\n const bytecodePath = join(\n codegenDir,\n 'contracts',\n `${contractName}.bin`,\n );\n return `0x${readFileSync(bytecodePath).toString('hex')}`;\n } catch (error) {\n console.error(\n `Could not find bytecode for contract ${contractName}:`,\n error.message,\n );\n throw error;\n }\n};\n\nconst deployContract = async (contractName, mnemonic, providerConfig) => {\n console.log(`Deploying ${contractName}...`);\n\n try {\n // Step 1: Set up provider and wallet\n const provider = createProvider(\n providerConfig.rpc,\n providerConfig.chainId,\n providerConfig.name,\n );\n const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic);\n const wallet = walletMnemonic.connect(provider);\n\n // Step 2: Create and deploy the contract\n const factory = new ethers.ContractFactory(\n getAbi(contractName),\n getByteCode(contractName),\n wallet,\n );\n const contract = await factory.deploy();\n await contract.waitForDeployment();\n\n // Step 3: Save deployment information\n const address = await contract.getAddress();\n console.log(`Contract ${contractName} deployed at: ${address}`);\n\n const addressesFile = join(codegenDir, 'contract-address.json');\n const addresses = existsSync(addressesFile)\n ? JSON.parse(readFileSync(addressesFile, 'utf8'))\n : {};\n addresses[contractName] = address;\n writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8');\n } catch (error) {\n console.error(`Failed to deploy contract ${contractName}:`, error);\n }\n};\n\nconst providerConfig = {\n rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io',\n chainId: 420420422,\n name: 'polkadot-hub-testnet',\n};\n\nconst mnemonic = 'INSERT_MNEMONIC';\n\ndeployContract('Storage', mnemonic, providerConfig);\n```\n\nReplace the `INSERT_MNEMONIC` placeholder with your actual mnemonic.\n\nExecute the deployment:\n\n```bash\nnode deploy.js\n```\n\nAfter running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-ethers-js", "page_title": "JavaScript with Ethers.js", "index": 3, "depth": 3, "title": "Next Steps", "anchor": "next-steps", "start_char": 6357, "end_char": 6935, "estimated_token_count": 156, "token_estimator": "heuristic-v1", "text": "### Next Steps\n\n- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide.\n- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide.\n- Check out in details each [development environment](/smart-contracts/dev-environments/)."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-foundry", "page_title": "Foundry", "index": 0, "depth": 3, "title": "Setup", "anchor": "setup", "start_char": 452, "end_char": 639, "estimated_token_count": 49, "token_estimator": "heuristic-v1", "text": "### Setup\n\nInstall Foundry:\n\n```bash\ncurl -L https://foundry.paradigm.xyz | bash\nfoundryup\n```\n\nInitialize your project:\n\n```bash\nforge init foundry-deployment\ncd foundry-deployment\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-foundry", "page_title": "Foundry", "index": 1, "depth": 3, "title": "Configure Foundry", "anchor": "configure-foundry", "start_char": 639, "end_char": 843, "estimated_token_count": 65, "token_estimator": "heuristic-v1", "text": "### Configure Foundry\n\nEdit `foundry.toml`:\n\n```toml\n[profile.default]\nsrc = \"src\"\nout = \"out\"\nlibs = [\"lib\"]\n\n[rpc_endpoints]\npolkadot_hub_testnet = \"https://testnet-passet-hub-eth-rpc.polkadot.io\"\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-foundry", "page_title": "Foundry", "index": 2, "depth": 3, "title": "Create Your Contract", "anchor": "create-your-contract", "start_char": 843, "end_char": 1242, "estimated_token_count": 89, "token_estimator": "heuristic-v1", "text": "### Create Your Contract\n\nReplace the default contract in `src/Storage.sol`:\n\n```solidity title=\"src/Storage.sol\"\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ncontract Storage {\n uint256 private storedNumber;\n\n function store(uint256 num) public {\n storedNumber = num;\n }\n\n function retrieve() public view returns (uint256) {\n return storedNumber;\n }\n}\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-foundry", "page_title": "Foundry", "index": 3, "depth": 3, "title": "Compile", "anchor": "compile", "start_char": 1242, "end_char": 1376, "estimated_token_count": 32, "token_estimator": "heuristic-v1", "text": "### Compile\n\n```bash\nforge build\n```\n\nVerify the compilation by inspecting the bytecode:\n\n```bash\nforge inspect Storage bytecode\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-foundry", "page_title": "Foundry", "index": 4, "depth": 3, "title": "Deploy", "anchor": "deploy", "start_char": 1376, "end_char": 1547, "estimated_token_count": 38, "token_estimator": "heuristic-v1", "text": "### Deploy\n\nDeploy to Polkadot Hub TestNet:\n\n```bash\nforge create Storage \\\n --rpc-url polkadot_hub_testnet \\\n --private-key YOUR_PRIVATE_KEY \\\n --broadcast\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-foundry", "page_title": "Foundry", "index": 5, "depth": 3, "title": "Next Steps", "anchor": "next-steps", "start_char": 1547, "end_char": 2125, "estimated_token_count": 156, "token_estimator": "heuristic-v1", "text": "### Next Steps\n\n- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide.\n- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide.\n- Check out in details each [development environment](/smart-contracts/dev-environments/)."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-hardhat", "page_title": "hardhat", "index": 0, "depth": 3, "title": "Setup", "anchor": "setup", "start_char": 545, "end_char": 669, "estimated_token_count": 29, "token_estimator": "heuristic-v1", "text": "### Setup\n\nInitialize your Hardhat project:\n\n```bash\nmkdir hardhat-deployment\ncd hardhat-deployment\nnpx hardhat --init\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-hardhat", "page_title": "hardhat", "index": 1, "depth": 3, "title": "Configure Hardhat", "anchor": "configure-hardhat", "start_char": 669, "end_char": 1851, "estimated_token_count": 272, "token_estimator": "heuristic-v1", "text": "### Configure Hardhat\n\nEdit `hardhat.config.js`:\n\n```javascript title=\"hardhat.config.js\" hl_lines=\"39-43\"\nimport type { HardhatUserConfig } from \"hardhat/config\";\n\nimport hardhatToolboxViemPlugin from \"@nomicfoundation/hardhat-toolbox-viem\";\nimport { configVariable } from \"hardhat/config\";\n\nconst config: HardhatUserConfig = {\n plugins: [hardhatToolboxViemPlugin],\n solidity: {\n profiles: {\n default: {\n version: \"0.8.28\",\n },\n production: {\n version: \"0.8.28\",\n settings: {\n optimizer: {\n enabled: true,\n runs: 200,\n },\n },\n },\n },\n },\n networks: {\n hardhatMainnet: {\n type: \"edr-simulated\",\n chainType: \"l1\",\n },\n hardhatOp: {\n type: \"edr-simulated\",\n chainType: \"op\",\n },\n sepolia: {\n type: \"http\",\n chainType: \"l1\",\n url: configVariable(\"SEPOLIA_RPC_URL\"),\n accounts: [configVariable(\"SEPOLIA_PRIVATE_KEY\")],\n },\n polkadotHubTestnet: {\n url: 'https://testnet-passet-hub-eth-rpc.polkadot.io',\n chainId: 420420422,\n accounts: [configVariable(\"PRIVATE_KEY\")],\n },\n },\n};\n\nexport default config;\n\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-hardhat", "page_title": "hardhat", "index": 2, "depth": 3, "title": "Create Your Contract", "anchor": "create-your-contract", "start_char": 1851, "end_char": 2232, "estimated_token_count": 80, "token_estimator": "heuristic-v1", "text": "### Create Your Contract\n\nReplace the default contract in `contracts/Storage.sol`:\n\n```solidity\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ncontract Storage {\n uint256 private storedNumber;\n\n function store(uint256 num) public {\n storedNumber = num;\n }\n\n function retrieve() public view returns (uint256) {\n return storedNumber;\n }\n}\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-hardhat", "page_title": "hardhat", "index": 3, "depth": 3, "title": "Compile", "anchor": "compile", "start_char": 2232, "end_char": 2276, "estimated_token_count": 14, "token_estimator": "heuristic-v1", "text": "### Compile\n\n```bash\nnpx hardhat build\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-hardhat", "page_title": "hardhat", "index": 4, "depth": 3, "title": "Set Up Deployment", "anchor": "set-up-deployment", "start_char": 2276, "end_char": 2614, "estimated_token_count": 89, "token_estimator": "heuristic-v1", "text": "### Set Up Deployment\n\nCreate a deployment module in `ignition/modules/Storage.ts`:\n\n```typescript title=\"ignition/modules/Storage.ts\"\nimport { buildModule } from '@nomicfoundation/hardhat-ignition/modules';\n\nexport default buildModule('StorageModule', (m) => {\n const storage = m.contract('Storage');\n return { storage };\n});\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-hardhat", "page_title": "hardhat", "index": 5, "depth": 3, "title": "Deploy", "anchor": "deploy", "start_char": 2614, "end_char": 2758, "estimated_token_count": 32, "token_estimator": "heuristic-v1", "text": "### Deploy\n\nDeploy to Polkadot Hub TestNet:\n\n```bash\nnpx hardhat ignition deploy ignition/modules/Storage.ts --network polkadotHubTestnet \n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-hardhat", "page_title": "hardhat", "index": 6, "depth": 3, "title": "Next Steps", "anchor": "next-steps", "start_char": 2758, "end_char": 3336, "estimated_token_count": 156, "token_estimator": "heuristic-v1", "text": "### Next Steps\n\n- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide.\n- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide.\n- Check out in details each [development environment](/smart-contracts/dev-environments/)."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-remix", "page_title": "Remix IDE", "index": 0, "depth": 3, "title": "Access Remix", "anchor": "access-remix", "start_char": 469, "end_char": 994, "estimated_token_count": 138, "token_estimator": "heuristic-v1", "text": "### Access Remix\n\nNavigate to [https://remix.polkadot.io/](https://remix.polkadot.io/){target=\\_blank} in your web browser.\n\nThe interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file:\n\n![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-01.webp)"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-remix", "page_title": "Remix IDE", "index": 1, "depth": 3, "title": "Compile", "anchor": "compile", "start_char": 994, "end_char": 1393, "estimated_token_count": 106, "token_estimator": "heuristic-v1", "text": "### Compile\n\n1. To compile your contract:\n 1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar.\n 2. Click **Compile Storage.sol** or press `Ctrl+S`.\n\n ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-02.webp)\n\nCompilation errors and warnings appear in the terminal panel at the bottom of the screen."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-remix", "page_title": "Remix IDE", "index": 2, "depth": 3, "title": "Deploy", "anchor": "deploy", "start_char": 1393, "end_char": 1895, "estimated_token_count": 127, "token_estimator": "heuristic-v1", "text": "### Deploy\n\n1. Navigate to the **Deploy & Run Transactions** tab.\n2. Click the **Environment** dropdown and select **Injected Provider - MetaMask** (ensure your MetaMask wallet is connected to Polkadot Hub TestNet).\n3. Click **Deploy**.\n4. Approve the transaction in your MetaMask wallet.\n\n ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-03.webp)\n\nYour deployed contract will appear in the **Deployed Contracts** section, ready for interaction."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-remix", "page_title": "Remix IDE", "index": 3, "depth": 3, "title": "Next Steps", "anchor": "next-steps", "start_char": 1895, "end_char": 2473, "estimated_token_count": 156, "token_estimator": "heuristic-v1", "text": "### Next Steps\n\n- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide.\n- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide.\n- Check out in details each [development environment](/smart-contracts/dev-environments/)."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-ethers", "page_title": "Deploy a Basic Contract with Ethers.js", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 42, "end_char": 458, "estimated_token_count": 80, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nThis guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Ethers.js](https://docs.ethers.org/v6/){target=\\_blank}, which provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-ethers", "page_title": "Deploy a Basic Contract with Ethers.js", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 458, "end_char": 866, "estimated_token_count": 120, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\n- Basic understanding of Solidity programming.\n- [Node.js](https://nodejs.org/en/download){target=\\_blank} v22.13.1 or later.\n- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\\_blank}). See the [step-by-step instructions](/smart-contracts/faucet/#get-test-tokens){target=\\_blank}.\n- A wallet with a private key for signing transactions."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-ethers", "page_title": "Deploy a Basic Contract with Ethers.js", "index": 2, "depth": 2, "title": "Set Up Your Project", "anchor": "set-up-your-project", "start_char": 866, "end_char": 1056, "estimated_token_count": 50, "token_estimator": "heuristic-v1", "text": "## Set Up Your Project\n\nFirst, initialize your project and install dependencies:\n\n```bash\nmkdir ethers-deployment\ncd ethers-deployment\nnpm init -y\nnpm install ethers@6.15.0 solc@0.8.30\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-ethers", "page_title": "Deploy a Basic Contract with Ethers.js", "index": 3, "depth": 2, "title": "Create Your Contract", "anchor": "create-your-contract", "start_char": 1056, "end_char": 1470, "estimated_token_count": 89, "token_estimator": "heuristic-v1", "text": "## Create Your Contract\n\nCreate a simple storage contract in `contracts/Storage.sol`:\n\n```solidity title=\"contracts/Storage.sol\"\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ncontract Storage {\n uint256 private storedNumber;\n\n function store(uint256 num) public {\n storedNumber = num;\n }\n\n function retrieve() public view returns (uint256) {\n return storedNumber;\n }\n}\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-ethers", "page_title": "Deploy a Basic Contract with Ethers.js", "index": 4, "depth": 2, "title": "Compile", "anchor": "compile", "start_char": 1470, "end_char": 3482, "estimated_token_count": 483, "token_estimator": "heuristic-v1", "text": "## Compile\n\nCreate a compilation script `compile.js`:\n\n```javascript title=\"compile.js\"\nconst solc = require('solc');\nconst { readFileSync, writeFileSync } = require('fs');\nconst { basename, join } = require('path');\n\nconst compileContract = async (solidityFilePath, outputDir) => {\n try {\n // Read the Solidity file\n const source = readFileSync(solidityFilePath, 'utf8');\n\n // Construct the input object for the compiler\n const input = {\n language: 'Solidity',\n sources: {\n [basename(solidityFilePath)]: { content: source },\n },\n settings: {\n outputSelection: {\n '*': {\n '*': ['*'],\n },\n },\n },\n };\n\n console.log(`Compiling contract: ${basename(solidityFilePath)}...`);\n\n // Compile the contract\n const output = JSON.parse(solc.compile(JSON.stringify(input)));\n\n if (output.errors) {\n output.errors.forEach(error => {\n console.error('Compilation error:', error.message);\n });\n return;\n }\n\n for (const contracts of Object.values(output.contracts)) {\n for (const [name, contract] of Object.entries(contracts)) {\n console.log(`Compiled contract: ${name}`);\n\n // Write the ABI\n const abiPath = join(outputDir, `${name}.json`);\n writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2));\n console.log(`ABI saved to ${abiPath}`);\n\n // Write the bytecode\n const bytecodePath = join(outputDir, `${name}.bin`);\n writeFileSync(bytecodePath, \n Buffer.from(\n contract.evm.bytecode.object,\n 'hex'\n ));\n console.log(`Bytecode saved to ${bytecodePath}`);\n }\n }\n } catch (error) {\n console.error('Error compiling contracts:', error);\n }\n};\n\nconst solidityFilePath = join(__dirname, 'contracts/Storage.sol');\nconst outputDir = join(__dirname, 'contracts');\n\ncompileContract(solidityFilePath, outputDir);\n```\n\nRun the compilation:\n\n```bash\nnode compile.js\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-ethers", "page_title": "Deploy a Basic Contract with Ethers.js", "index": 5, "depth": 2, "title": "Deploy", "anchor": "deploy", "start_char": 3482, "end_char": 6780, "estimated_token_count": 746, "token_estimator": "heuristic-v1", "text": "## Deploy\n\nCreate a deployment script `deploy.js`:\n\n```javascript title=\"deploy.js\"\nconst { writeFileSync, existsSync, readFileSync } = require('fs');\nconst { join } = require('path');\nconst { ethers, JsonRpcProvider } = require('ethers');\n\nconst codegenDir = join(__dirname);\n\n// Creates a provider with specified RPC URL and chain details\nconst createProvider = (rpcUrl, chainId, chainName) => {\n const provider = new JsonRpcProvider(rpcUrl, {\n chainId: chainId,\n name: chainName,\n });\n return provider;\n};\n\n// Reads and parses the ABI file for a given contract\nconst getAbi = (contractName) => {\n try {\n return JSON.parse(\n readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'),\n );\n } catch (error) {\n console.error(\n `Could not find ABI for contract ${contractName}:`,\n error.message,\n );\n throw error;\n }\n};\n\n// Reads the compiled bytecode for a given contract\nconst getByteCode = (contractName) => {\n try {\n const bytecodePath = join(\n codegenDir,\n 'contracts',\n `${contractName}.bin`,\n );\n return `0x${readFileSync(bytecodePath).toString('hex')}`;\n } catch (error) {\n console.error(\n `Could not find bytecode for contract ${contractName}:`,\n error.message,\n );\n throw error;\n }\n};\n\nconst deployContract = async (contractName, mnemonic, providerConfig) => {\n console.log(`Deploying ${contractName}...`);\n\n try {\n // Step 1: Set up provider and wallet\n const provider = createProvider(\n providerConfig.rpc,\n providerConfig.chainId,\n providerConfig.name,\n );\n const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic);\n const wallet = walletMnemonic.connect(provider);\n\n // Step 2: Create and deploy the contract\n const factory = new ethers.ContractFactory(\n getAbi(contractName),\n getByteCode(contractName),\n wallet,\n );\n const contract = await factory.deploy();\n await contract.waitForDeployment();\n\n // Step 3: Save deployment information\n const address = await contract.getAddress();\n console.log(`Contract ${contractName} deployed at: ${address}`);\n\n const addressesFile = join(codegenDir, 'contract-address.json');\n const addresses = existsSync(addressesFile)\n ? JSON.parse(readFileSync(addressesFile, 'utf8'))\n : {};\n addresses[contractName] = address;\n writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8');\n } catch (error) {\n console.error(`Failed to deploy contract ${contractName}:`, error);\n }\n};\n\nconst providerConfig = {\n rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io',\n chainId: 420420422,\n name: 'polkadot-hub-testnet',\n};\n\nconst mnemonic = 'INSERT_MNEMONIC';\n\ndeployContract('Storage', mnemonic, providerConfig);\n```\n\nReplace the `INSERT_MNEMONIC` placeholder with your actual mnemonic.\n\n!!! warning\n Never embed private keys, mnemonic phrases, or security-sensitive credentials directly into your JavaScript, TypeScript, or any front-end/client-side files.\n\nExecute the deployment:\n\n```bash\nnode deploy.js\n```\n\nAfter running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-ethers", "page_title": "Deploy a Basic Contract with Ethers.js", "index": 6, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 6780, "end_char": 7370, "estimated_token_count": 161, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\n
\n\n- Guide __Deploy an ERC-20__\n\n ---\n\n Walk through deploying a fully-functional ERC-20 to the Polkadot Hub using Ethers.js.\n\n [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-erc20/ethers/)\n\n- Guide __Deploy an NFT__\n\n ---\n\n Walk through deploying a NFT to the Polkadot Hub using Ethers.js.\n\n [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-nft/ethers/)\n \n
"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-evm", "page_title": "Deploy a Basic Contract to EVM", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 33, "end_char": 1276, "estimated_token_count": 307, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nDeploying smart contracts to the [Polkadot Hub](/smart-contracts/overview/#smart-contract-development){target=\\_blank} can be accomplished using standard EVM development tools and workflows. This guide demonstrates how to deploy a basic smart contract using four popular EVM approaches: JavaScript with [Ethers.js](https://docs.ethers.org/v6/){target=\\_blank}, [Remix IDE](https://remix.live/){target=\\_blank}, [Hardhat](https://hardhat.org/){target=\\_blank}, and [Foundry](https://getfoundry.sh/){target=\\_blank}.\n\nAll these tools use standard Solidity compilation to generate EVM bytecode, making them compatible with Polkadot Hub's EVM environment. Whether you prefer working with lightweight JavaScript libraries, visual browser-based IDEs, comprehensive development frameworks, or fast command-line toolkits, this guide covers the deployment process for each approach.\n\n**Prerequisites:**\n\n- Basic understanding of Solidity programming.\n- [Node.js](https://nodejs.org/en/download){target=\\_blank} v22.13.1 or later (for JavaScript/Hardhat approaches).\n- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\\_blank}).\n- A wallet with a private key for signing transactions."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-evm", "page_title": "Deploy a Basic Contract to EVM", "index": 1, "depth": 2, "title": "Deployment options", "anchor": "deployment-options", "start_char": 1276, "end_char": 14303, "estimated_token_count": 2744, "token_estimator": "heuristic-v1", "text": "## Deployment options\n\n=== \"JavaScript with Ethers.js\"\n Ethers.js provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications.\n\n ### Setup\n\n First, initialize your project and install dependencies:\n\n ```bash\n mkdir ethers-deployment\n cd ethers-deployment\n npm init -y\n npm install ethers@6.15.0 solc@0.8.30\n ```\n\n ### Create and Compile Your Contract\n\n Create a simple storage contract in `contracts/Storage.sol`:\n\n ```solidity title=\"contracts/Storage.sol\"\n // SPDX-License-Identifier: MIT\n pragma solidity ^0.8.9;\n\n contract Storage {\n uint256 private storedNumber;\n\n function store(uint256 num) public {\n storedNumber = num;\n }\n\n function retrieve() public view returns (uint256) {\n return storedNumber;\n }\n }\n ```\n\n Create a compilation script `compile.js`:\n\n ```javascript title=\"compile.js\"\n const solc = require('solc');\n const { readFileSync, writeFileSync } = require('fs');\n const { basename, join } = require('path');\n\n const compileContract = async (solidityFilePath, outputDir) => {\n try {\n // Read the Solidity file\n const source = readFileSync(solidityFilePath, 'utf8');\n\n // Construct the input object for the compiler\n const input = {\n language: 'Solidity',\n sources: {\n [basename(solidityFilePath)]: { content: source },\n },\n settings: {\n outputSelection: {\n '*': {\n '*': ['*'],\n },\n },\n },\n };\n\n console.log(`Compiling contract: ${basename(solidityFilePath)}...`);\n\n // Compile the contract\n const output = JSON.parse(solc.compile(JSON.stringify(input)));\n\n if (output.errors) {\n output.errors.forEach(error => {\n console.error('Compilation error:', error.message);\n });\n return;\n }\n\n for (const contracts of Object.values(output.contracts)) {\n for (const [name, contract] of Object.entries(contracts)) {\n console.log(`Compiled contract: ${name}`);\n\n // Write the ABI\n const abiPath = join(outputDir, `${name}.json`);\n writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2));\n console.log(`ABI saved to ${abiPath}`);\n\n // Write the bytecode\n const bytecodePath = join(outputDir, `${name}.bin`);\n writeFileSync(bytecodePath, \n Buffer.from(\n contract.evm.bytecode.object,\n 'hex'\n ));\n console.log(`Bytecode saved to ${bytecodePath}`);\n }\n }\n } catch (error) {\n console.error('Error compiling contracts:', error);\n }\n };\n\n const solidityFilePath = join(__dirname, 'contracts/Storage.sol');\n const outputDir = join(__dirname, 'contracts');\n\n compileContract(solidityFilePath, outputDir);\n ```\n\n Run the compilation:\n\n ```bash\n node compile.js\n ```\n\n ### Deploy the Contract\n\n Create a deployment script `deploy.js`:\n\n ```javascript title=\"deploy.js\"\n const { writeFileSync, existsSync, readFileSync } = require('fs');\n const { join } = require('path');\n const { ethers, JsonRpcProvider } = require('ethers');\n\n const codegenDir = join(__dirname);\n\n // Creates a provider with specified RPC URL and chain details\n const createProvider = (rpcUrl, chainId, chainName) => {\n const provider = new JsonRpcProvider(rpcUrl, {\n chainId: chainId,\n name: chainName,\n });\n return provider;\n };\n\n // Reads and parses the ABI file for a given contract\n const getAbi = (contractName) => {\n try {\n return JSON.parse(\n readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'),\n );\n } catch (error) {\n console.error(\n `Could not find ABI for contract ${contractName}:`,\n error.message,\n );\n throw error;\n }\n };\n\n // Reads the compiled bytecode for a given contract\n const getByteCode = (contractName) => {\n try {\n const bytecodePath = join(\n codegenDir,\n 'contracts',\n `${contractName}.bin`,\n );\n return `0x${readFileSync(bytecodePath).toString('hex')}`;\n } catch (error) {\n console.error(\n `Could not find bytecode for contract ${contractName}:`,\n error.message,\n );\n throw error;\n }\n };\n\n const deployContract = async (contractName, mnemonic, providerConfig) => {\n console.log(`Deploying ${contractName}...`);\n\n try {\n // Step 1: Set up provider and wallet\n const provider = createProvider(\n providerConfig.rpc,\n providerConfig.chainId,\n providerConfig.name,\n );\n const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic);\n const wallet = walletMnemonic.connect(provider);\n\n // Step 2: Create and deploy the contract\n const factory = new ethers.ContractFactory(\n getAbi(contractName),\n getByteCode(contractName),\n wallet,\n );\n const contract = await factory.deploy();\n await contract.waitForDeployment();\n\n // Step 3: Save deployment information\n const address = await contract.getAddress();\n console.log(`Contract ${contractName} deployed at: ${address}`);\n\n const addressesFile = join(codegenDir, 'contract-address.json');\n const addresses = existsSync(addressesFile)\n ? JSON.parse(readFileSync(addressesFile, 'utf8'))\n : {};\n addresses[contractName] = address;\n writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8');\n } catch (error) {\n console.error(`Failed to deploy contract ${contractName}:`, error);\n }\n };\n\n const providerConfig = {\n rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io',\n chainId: 420420422,\n name: 'polkadot-hub-testnet',\n };\n\n const mnemonic = 'INSERT_MNEMONIC';\n\n deployContract('Storage', mnemonic, providerConfig);\n ```\n\n Replace the `INSERT_MNEMONIC` placeholder with your actual mnemonic.\n\n Execute the deployment:\n\n ```bash\n node deploy.js\n ```\n\n After running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions.\n\n=== \"Remix IDE\"\n Remix IDE offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development.\n\n ### Access Remix\n\n Navigate to [https://remix.ethereum.org/](https://remix.ethereum.org/){target=\\_blank} in your web browser.\n\n The interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file.\n\n ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-evm/deploy-basic-evm-01.webp)\n\n ### Compile\n\n 1. To compile your contract:\n 1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar.\n 2. Click **Compile Storage.sol** or press `Ctrl+S`.\n\n ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-evm/deploy-basic-evm-02.webp)\n\n Compilation errors and warnings appear in the terminal panel at the bottom of the screen.\n\n ### Deploy\n\n 1. Navigate to the **Deploy & Run Transactions** tab.\n 2. Click the **Environment** dropdown and select **Browser extension**.\n 3. Select **Injected Provider - MetaMask** (make sure you are logged in to MetaMask). \n 4. In MetaMask, add a custom network with the following details:\n - **Network Name**: Polkadot Hub TestNet\n - **RPC URL**: `https://testnet-passet-hub-eth-rpc.polkadot.io`\n - **Chain ID**: `420420422`\n - **Currency Symbol**: `DOT`\n 4. Return to Remix click on **Deploy**.\n 6. Approve the transaction in your MetaMask wallet.\n\n ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-evm/deploy-basic-evm-03.webp)\n\n Your deployed contract will appear in the **Deployed Contracts** section, ready for interaction.\n\n=== \"Hardhat\"\n Hardhat provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects.\n\n ### Setup\n\n Initialize your Hardhat project:\n\n ```bash\n mkdir hardhat-deployment\n cd hardhat-deployment\n npx hardhat --init\n ```\n\n ### Configure Hardhat\n\n Edit `hardhat.config.js`:\n\n ```javascript title=\"hardhat.config.js\" hl_lines=\"39-43\"\n import type { HardhatUserConfig } from \"hardhat/config\";\n\n import hardhatToolboxViemPlugin from \"@nomicfoundation/hardhat-toolbox-viem\";\n import { configVariable } from \"hardhat/config\";\n\n const config: HardhatUserConfig = {\n plugins: [hardhatToolboxViemPlugin],\n solidity: {\n profiles: {\n default: {\n version: \"0.8.28\",\n },\n production: {\n version: \"0.8.28\",\n settings: {\n optimizer: {\n enabled: true,\n runs: 200,\n },\n },\n },\n },\n },\n networks: {\n hardhatMainnet: {\n type: \"edr-simulated\",\n chainType: \"l1\",\n },\n hardhatOp: {\n type: \"edr-simulated\",\n chainType: \"op\",\n },\n sepolia: {\n type: \"http\",\n chainType: \"l1\",\n url: configVariable(\"SEPOLIA_RPC_URL\"),\n accounts: [configVariable(\"SEPOLIA_PRIVATE_KEY\")],\n },\n polkadotHubTestnet: {\n url: 'https://testnet-passet-hub-eth-rpc.polkadot.io',\n chainId: 420420422,\n accounts: [configVariable(\"PRIVATE_KEY\")],\n },\n },\n };\n\n export default config;\n\n ```\n\n ### Create Your Contract\n\n Replace the default contract in `contracts/Storage.sol`:\n\n ```solidity\n // SPDX-License-Identifier: MIT\n pragma solidity ^0.8.9;\n\n contract Storage {\n uint256 private storedNumber;\n\n function store(uint256 num) public {\n storedNumber = num;\n }\n\n function retrieve() public view returns (uint256) {\n return storedNumber;\n }\n }\n ```\n\n ### Compile\n\n ```bash\n npx hardhat build\n ```\n\n ### Set Up Deployment\n\n Create a deployment module in `ignition/modules/Storage.ts`:\n\n ```typescript title=\"ignition/modules/Storage.ts\"\n import { buildModule } from '@nomicfoundation/hardhat-ignition/modules';\n\n export default buildModule('StorageModule', (m) => {\n const storage = m.contract('Storage');\n return { storage };\n });\n ```\n\n ### Deploy\n\n Deploy to Polkadot Hub TestNet:\n\n ```bash\n npx hardhat ignition deploy ignition/modules/Storage.ts --network polkadotHubTestnet \n ```\n\n=== \"Foundry\"\n Foundry offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment.\n\n ### Setup\n\n Install Foundry:\n\n ```bash\n curl -L https://foundry.paradigm.xyz | bash\n foundryup\n ```\n\n Initialize your project:\n\n ```bash\n forge init foundry-deployment\n cd foundry-deployment\n ```\n\n ### Configure Foundry\n\n Edit `foundry.toml`:\n\n ```toml\n [profile.default]\n src = \"src\"\n out = \"out\"\n libs = [\"lib\"]\n\n [rpc_endpoints]\n polkadot_hub_testnet = \"https://testnet-passet-hub-eth-rpc.polkadot.io\"\n ```\n\n ### Create Your Contract\n\n Replace the default contract in `src/Storage.sol`:\n\n ```solidity title=\"src/Storage.sol\"\n // SPDX-License-Identifier: MIT\n pragma solidity ^0.8.9;\n\n contract Storage {\n uint256 private storedNumber;\n\n function store(uint256 num) public {\n storedNumber = num;\n }\n\n function retrieve() public view returns (uint256) {\n return storedNumber;\n }\n }\n ```\n\n ### Compile\n\n ```bash\n forge build\n ```\n\n Verify the compilation by inspecting the bytecode:\n\n ```bash\n forge inspect Storage bytecode\n ```\n\n ### Deploy\n\n Deploy to Polkadot Hub TestNet:\n\n ```bash\n forge create Storage \\\n --rpc-url polkadot_hub_testnet \\\n --private-key YOUR_PRIVATE_KEY \\\n --broadcast\n ```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-evm", "page_title": "Deploy a Basic Contract to EVM", "index": 2, "depth": 2, "title": "Conclusion", "anchor": "conclusion", "start_char": 14303, "end_char": 15051, "estimated_token_count": 134, "token_estimator": "heuristic-v1", "text": "## Conclusion\n\nThis guide has demonstrated four different approaches to deploying smart contracts on Polkadot Hub using standard EVM tools. Each method offers distinct advantages:\n\n- **Ethers.js**: Best for lightweight, programmatic deployments and application integration\n- **Remix IDE**: Ideal for rapid prototyping, learning, and visual development\n- **Hardhat**: Perfect for professional workflows requiring comprehensive testing and debugging\n- **Foundry**: Excellent for developers who prefer fast, command-line driven development\n\nAll approaches use standard Solidity compilation to generate EVM bytecode, ensuring your contracts run on Polkadot Hub's EVM environment. Choose the tool that best fits your workflow and project requirements."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-evm", "page_title": "Deploy a Basic Contract to EVM", "index": 3, "depth": 3, "title": "Next Steps", "anchor": "next-steps", "start_char": 15051, "end_char": 15629, "estimated_token_count": 156, "token_estimator": "heuristic-v1", "text": "### Next Steps\n\n- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide.\n- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide.\n- Check out in details each [development environment](/smart-contracts/dev-environments/)."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-foundry", "page_title": "Deploy a Basic Contract with Foundry", "index": 0, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 355, "end_char": 684, "estimated_token_count": 87, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\n- Basic understanding of Solidity programming.\n- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\\_blank}). See the [step-by-step instructions](/smart-contracts/faucet/#get-test-tokens){target=\\_blank}.\n- A wallet with a private key for signing transactions."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-foundry", "page_title": "Deploy a Basic Contract with Foundry", "index": 1, "depth": 2, "title": "Set Up Your Project", "anchor": "set-up-your-project", "start_char": 684, "end_char": 884, "estimated_token_count": 51, "token_estimator": "heuristic-v1", "text": "## Set Up Your Project\n\nInstall Foundry:\n\n```bash\ncurl -L https://foundry.paradigm.xyz | bash\nfoundryup\n```\n\nInitialize your project:\n\n```bash\nforge init foundry-deployment\ncd foundry-deployment\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-foundry", "page_title": "Deploy a Basic Contract with Foundry", "index": 2, "depth": 2, "title": "Configure Foundry", "anchor": "configure-foundry", "start_char": 884, "end_char": 1087, "estimated_token_count": 64, "token_estimator": "heuristic-v1", "text": "## Configure Foundry\n\nEdit `foundry.toml`:\n\n```toml\n[profile.default]\nsrc = \"src\"\nout = \"out\"\nlibs = [\"lib\"]\n\n[rpc_endpoints]\npolkadot_hub_testnet = \"https://testnet-passet-hub-eth-rpc.polkadot.io\"\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-foundry", "page_title": "Deploy a Basic Contract with Foundry", "index": 3, "depth": 2, "title": "Create Your Contract", "anchor": "create-your-contract", "start_char": 1087, "end_char": 1485, "estimated_token_count": 88, "token_estimator": "heuristic-v1", "text": "## Create Your Contract\n\nReplace the default contract in `src/Storage.sol`:\n\n```solidity title=\"src/Storage.sol\"\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ncontract Storage {\n uint256 private storedNumber;\n\n function store(uint256 num) public {\n storedNumber = num;\n }\n\n function retrieve() public view returns (uint256) {\n return storedNumber;\n }\n}\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-foundry", "page_title": "Deploy a Basic Contract with Foundry", "index": 4, "depth": 2, "title": "Compile", "anchor": "compile", "start_char": 1485, "end_char": 1618, "estimated_token_count": 31, "token_estimator": "heuristic-v1", "text": "## Compile\n\n```bash\nforge build\n```\n\nVerify the compilation by inspecting the bytecode:\n\n```bash\nforge inspect Storage bytecode\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-foundry", "page_title": "Deploy a Basic Contract with Foundry", "index": 5, "depth": 2, "title": "Deploy", "anchor": "deploy", "start_char": 1618, "end_char": 1862, "estimated_token_count": 49, "token_estimator": "heuristic-v1", "text": "## Deploy\n\nDeploy to Polkadot Hub TestNet:\n\n```bash\nforge create Storage \\\n --rpc-url polkadot_hub_testnet \\\n --private-key YOUR_PRIVATE_KEY \\\n --broadcast\n```\n\nReplace the `YOUR_PRIVATE_KEY` placeholder with your actual private key."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-foundry", "page_title": "Deploy a Basic Contract with Foundry", "index": 6, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 1862, "end_char": 2731, "estimated_token_count": 228, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\n
\n\n- Guide __Verify Your Contract__\n\n ---\n\n Now that you've deployed a basic contract, learn how to verify it with Foundry.\n \n [:octicons-arrow-right-24: Get Started](/smart-contracts/dev-environments/foundry/verify-a-contract/)\n\n- Guide __Deploy an ERC-20__\n \n ---\n \n Walk through deploying a fully-functional ERC-20 to the Polkadot Hub using Foundry.\n \n [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-erc20/foundry/)\n\n- Guide __Deploy an NFT__\n\n ---\n\n Walk through deploying a NFT to the Polkadot Hub using Foundry.\n\n [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-nft/foundry/)\n\n
"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat", "page_title": "Deploy a Basic Contract with Hardhat", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 32, "end_char": 378, "estimated_token_count": 68, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nThis guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Hardhat](https://hardhat.org/){target=\\_blank}, which provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat", "page_title": "Deploy a Basic Contract with Hardhat", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 378, "end_char": 786, "estimated_token_count": 120, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\n- Basic understanding of Solidity programming.\n- [Node.js](https://nodejs.org/en/download){target=\\_blank} v22.13.1 or later.\n- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\\_blank}). See the [step-by-step instructions](/smart-contracts/faucet/#get-test-tokens){target=\\_blank}.\n- A wallet with a private key for signing transactions."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat", "page_title": "Deploy a Basic Contract with Hardhat", "index": 2, "depth": 2, "title": "Set Up Your Project", "anchor": "set-up-your-project", "start_char": 786, "end_char": 923, "estimated_token_count": 31, "token_estimator": "heuristic-v1", "text": "## Set Up Your Project\n\nInitialize your Hardhat project:\n\n```bash\nmkdir hardhat-deployment\ncd hardhat-deployment\nnpx hardhat --init\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat", "page_title": "Deploy a Basic Contract with Hardhat", "index": 3, "depth": 2, "title": "Configure Hardhat", "anchor": "configure-hardhat", "start_char": 923, "end_char": 2285, "estimated_token_count": 321, "token_estimator": "heuristic-v1", "text": "## Configure Hardhat\n\nEdit `hardhat.config.js`:\n\n```javascript title='hardhat.config.js' hl_lines='39-43'\nimport type { HardhatUserConfig } from 'hardhat/config';\n\nimport hardhatToolboxViemPlugin from '@nomicfoundation/hardhat-toolbox-viem';\nimport { configVariable } from 'hardhat/config';\n\nconst config: HardhatUserConfig = {\n plugins: [hardhatToolboxViemPlugin],\n solidity: {\n profiles: {\n default: {\n version: '0.8.28',\n },\n production: {\n version: '0.8.28',\n settings: {\n optimizer: {\n enabled: true,\n runs: 200,\n },\n },\n },\n },\n },\n networks: {\n hardhatMainnet: {\n type: 'edr-simulated',\n chainType: 'l1',\n },\n hardhatOp: {\n type: 'edr-simulated',\n chainType: 'op',\n },\n sepolia: {\n type: 'http',\n chainType: 'l1',\n url: configVariable('SEPOLIA_RPC_URL'),\n accounts: [configVariable('SEPOLIA_PRIVATE_KEY')],\n },\n polkadotHubTestnet: {\n url: 'https://testnet-passet-hub-eth-rpc.polkadot.io',\n chainId: 420420422,\n accounts: [configVariable('PRIVATE_KEY')],\n },\n },\n};\n\nexport default config;\n\n```\n\n!!! tip\n Learn how to use Hardhat's [Config Variables](https://hardhat.org/docs/learn-more/configuration-variables){target=\\_blank} to handle your private keys in a secure way."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat", "page_title": "Deploy a Basic Contract with Hardhat", "index": 4, "depth": 2, "title": "Create Your Contract", "anchor": "create-your-contract", "start_char": 2285, "end_char": 2665, "estimated_token_count": 79, "token_estimator": "heuristic-v1", "text": "## Create Your Contract\n\nReplace the default contract in `contracts/Storage.sol`:\n\n```solidity\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ncontract Storage {\n uint256 private storedNumber;\n\n function store(uint256 num) public {\n storedNumber = num;\n }\n\n function retrieve() public view returns (uint256) {\n return storedNumber;\n }\n}\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat", "page_title": "Deploy a Basic Contract with Hardhat", "index": 5, "depth": 2, "title": "Compile", "anchor": "compile", "start_char": 2665, "end_char": 2708, "estimated_token_count": 13, "token_estimator": "heuristic-v1", "text": "## Compile\n\n```bash\nnpx hardhat build\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat", "page_title": "Deploy a Basic Contract with Hardhat", "index": 6, "depth": 2, "title": "Set Up Deployment", "anchor": "set-up-deployment", "start_char": 2708, "end_char": 3041, "estimated_token_count": 88, "token_estimator": "heuristic-v1", "text": "## Set Up Deployment\n\nCreate a deployment module in `ignition/modules/Storage.ts`:\n\n```typescript title=\"ignition/modules/Storage.ts\"\nimport { buildModule } from '@nomicfoundation/hardhat-ignition/modules';\n\nexport default buildModule('StorageModule', (m) => {\n const storage = m.contract('Storage');\n return { storage };\n});\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat", "page_title": "Deploy a Basic Contract with Hardhat", "index": 7, "depth": 2, "title": "Deploy the Contract", "anchor": "deploy-the-contract", "start_char": 3041, "end_char": 3197, "estimated_token_count": 33, "token_estimator": "heuristic-v1", "text": "## Deploy the Contract\n\nDeploy to Polkadot Hub TestNet:\n\n```bash\nnpx hardhat ignition deploy ignition/modules/Storage.ts --network polkadotHubTestnet \n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat", "page_title": "Deploy a Basic Contract with Hardhat", "index": 8, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 3197, "end_char": 4051, "estimated_token_count": 228, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\n
\n\n- Guide __Verify Your Contract__\n\n ---\n\n Now that you've deployed a basic contract, learn how to verify it with Hardhat.\n\n [:octicons-arrow-right-24: Get Started](/smart-contracts/dev-environments/hardhat/verify-a-contract/)\n\n- Guide __Deploy an ERC-20__\n\n ---\n\n Walk through deploying a fully-functional ERC-20 to the Polkadot Hub using Hardhat.\n\n [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-erc20/hardhat/)\n\n- Guide __Deploy an NFT__\n\n ---\n\n Walk through deploying a NFT to the Polkadot Hub using Hardhat.\n\n [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-nft/hardhat/)\n\n
"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 27, "end_char": 1362, "estimated_token_count": 322, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nDeploying smart contracts to [Polkadot Hub](/smart-contracts/overview/#smart-contract-development){target=\\_blank} can be accomplished through various tools and environments, each suited to different development workflows. This guide demonstrates how to deploy a basic PolkaVM (PVM) smart contract using four popular approaches: JavaScript with [Ethers.js](https://docs.ethers.org/v6/){target=\\_blank}, [Remix IDE](https://remix.live/){target=\\_blank}, [Hardhat](https://hardhat.org/){target=\\_blank}, and [Foundry](https://getfoundry.sh/){target=\\_blank}.\n\nAll these tools leverage the `revive` compiler to transform Solidity smart contracts into PolkaVM bytecode, making them compatible with Polkadot Hub's native smart contract environment. Whether you prefer working with lightweight JavaScript libraries, visual browser-based IDEs, comprehensive development frameworks, or fast command-line toolkits, this guide covers the deployment process for each approach.\n\n**Prerequisites:**\n\n- Basic understanding of Solidity programming.\n- [Node.js](https://nodejs.org/en/download){target=\\_blank} v22.13.1 or later (for JavaScript/Hardhat approaches).\n- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\\_blank}).\n- A wallet with a private key for signing transactions."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 1, "depth": 2, "title": "JavaScript with Ethers.js", "anchor": "javascript-with-ethersjs", "start_char": 1362, "end_char": 1645, "estimated_token_count": 45, "token_estimator": "heuristic-v1", "text": "## JavaScript with Ethers.js\n\nEthers.js provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 2, "depth": 3, "title": "Setup", "anchor": "setup", "start_char": 1645, "end_char": 1818, "estimated_token_count": 39, "token_estimator": "heuristic-v1", "text": "### Setup\n\nFirst, initialize your project and install dependencies:\n\n```bash\nmkdir ethers-deployment\ncd ethers-deployment\nnpm init -y\nnpm install ethers @parity/resolc\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 3, "depth": 3, "title": "Create and Compile Your Contract", "anchor": "create-and-compile-your-contract", "start_char": 1818, "end_char": 3875, "estimated_token_count": 491, "token_estimator": "heuristic-v1", "text": "### Create and Compile Your Contract\n\nCreate a simple storage contract in `contracts/Storage.sol`:\n\n```solidity title=\"contracts/Storage.sol\"\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ncontract Storage {\n uint256 private storedNumber;\n\n function store(uint256 num) public {\n storedNumber = num;\n }\n\n function retrieve() public view returns (uint256) {\n return storedNumber;\n }\n}\n```\n\nCreate a compilation script `compile.js`:\n\n```javascript title=\"compile.js\"\nconst { compile } = require('@parity/resolc');\nconst { readFileSync, writeFileSync } = require('fs');\nconst { basename, join } = require('path');\n\nconst compileContract = async (solidityFilePath, outputDir) => {\n try {\n // Read the Solidity file\n const source = readFileSync(solidityFilePath, 'utf8');\n\n // Construct the input object for the compiler\n const input = {\n [basename(solidityFilePath)]: { content: source },\n };\n\n console.log(`Compiling contract: ${basename(solidityFilePath)}...`);\n\n // Compile the contract\n const out = await compile(input);\n\n for (const contracts of Object.values(out.contracts)) {\n for (const [name, contract] of Object.entries(contracts)) {\n console.log(`Compiled contract: ${name}`);\n\n // Write the ABI\n const abiPath = join(outputDir, `${name}.json`);\n writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2));\n console.log(`ABI saved to ${abiPath}`);\n\n // Write the bytecode\n const bytecodePath = join(outputDir, `${name}.polkavm`);\n writeFileSync(\n bytecodePath,\n Buffer.from(contract.evm.bytecode.object, 'hex'),\n );\n console.log(`Bytecode saved to ${bytecodePath}`);\n }\n }\n } catch (error) {\n console.error('Error compiling contracts:', error);\n }\n};\n\nconst solidityFilePath = join(__dirname, 'contracts/Storage.sol');\nconst outputDir = join(__dirname, 'contracts');\n\ncompileContract(solidityFilePath, outputDir);\n```\n\nRun the compilation:\n\n```bash\nnode compile.js\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 4, "depth": 3, "title": "Deploy the Contract", "anchor": "deploy-the-contract", "start_char": 3875, "end_char": 7017, "estimated_token_count": 714, "token_estimator": "heuristic-v1", "text": "### Deploy the Contract\n\nCreate a deployment script `deploy.js`:\n\n```javascript title=\"deploy.js\"\nconst { writeFileSync, existsSync, readFileSync } = require('fs');\nconst { join } = require('path');\nconst { ethers, JsonRpcProvider } = require('ethers');\n\nconst codegenDir = join(__dirname);\n\n// Creates a provider with specified RPC URL and chain details\nconst createProvider = (rpcUrl, chainId, chainName) => {\n const provider = new JsonRpcProvider(rpcUrl, {\n chainId: chainId,\n name: chainName,\n });\n return provider;\n};\n\n// Reads and parses the ABI file for a given contract\nconst getAbi = (contractName) => {\n try {\n return JSON.parse(\n readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'),\n );\n } catch (error) {\n console.error(\n `Could not find ABI for contract ${contractName}:`,\n error.message,\n );\n throw error;\n }\n};\n\n// Reads the compiled bytecode for a given contract\nconst getByteCode = (contractName) => {\n try {\n const bytecodePath = join(\n codegenDir,\n 'contracts',\n `${contractName}.polkavm`,\n );\n return `0x${readFileSync(bytecodePath).toString('hex')}`;\n } catch (error) {\n console.error(\n `Could not find bytecode for contract ${contractName}:`,\n error.message,\n );\n throw error;\n }\n};\n\nconst deployContract = async (contractName, mnemonic, providerConfig) => {\n console.log(`Deploying ${contractName}...`);\n\n try {\n // Step 1: Set up provider and wallet\n const provider = createProvider(\n providerConfig.rpc,\n providerConfig.chainId,\n providerConfig.name,\n );\n const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic);\n const wallet = walletMnemonic.connect(provider);\n\n // Step 2: Create and deploy the contract\n const factory = new ethers.ContractFactory(\n getAbi(contractName),\n getByteCode(contractName),\n wallet,\n );\n const contract = await factory.deploy();\n await contract.waitForDeployment();\n\n // Step 3: Save deployment information\n const address = await contract.getAddress();\n console.log(`Contract ${contractName} deployed at: ${address}`);\n\n const addressesFile = join(codegenDir, 'contract-address.json');\n const addresses = existsSync(addressesFile)\n ? JSON.parse(readFileSync(addressesFile, 'utf8'))\n : {};\n addresses[contractName] = address;\n writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8');\n } catch (error) {\n console.error(`Failed to deploy contract ${contractName}:`, error);\n }\n};\n\nconst providerConfig = {\n rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io',\n chainId: 420420422,\n name: 'polkadot-hub-testnet',\n};\n\nconst mnemonic = 'INSERT_MNEMONIC';\n\ndeployContract('Storage', mnemonic, providerConfig);\n```\n\nReplace the `INSERT_MNEMONIC` placeholder with your actual mnemonic.\n\nExecute the deployment:\n\n```bash\nnode deploy.js\n```\n\nAfter running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 5, "depth": 2, "title": "Remix IDE", "anchor": "remix-ide", "start_char": 7017, "end_char": 7225, "estimated_token_count": 35, "token_estimator": "heuristic-v1", "text": "## Remix IDE\n\nRemix IDE offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 6, "depth": 3, "title": "Access Remix", "anchor": "access-remix", "start_char": 7225, "end_char": 7750, "estimated_token_count": 138, "token_estimator": "heuristic-v1", "text": "### Access Remix\n\nNavigate to [https://remix.polkadot.io/](https://remix.polkadot.io/){target=\\_blank} in your web browser.\n\nThe interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file:\n\n![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-01.webp)"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 7, "depth": 3, "title": "Compile", "anchor": "compile", "start_char": 7750, "end_char": 8149, "estimated_token_count": 106, "token_estimator": "heuristic-v1", "text": "### Compile\n\n1. To compile your contract:\n 1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar.\n 2. Click **Compile Storage.sol** or press `Ctrl+S`.\n\n ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-02.webp)\n\nCompilation errors and warnings appear in the terminal panel at the bottom of the screen."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 8, "depth": 3, "title": "Deploy", "anchor": "deploy", "start_char": 8149, "end_char": 8651, "estimated_token_count": 127, "token_estimator": "heuristic-v1", "text": "### Deploy\n\n1. Navigate to the **Deploy & Run Transactions** tab.\n2. Click the **Environment** dropdown and select **Injected Provider - MetaMask** (ensure your MetaMask wallet is connected to Polkadot Hub TestNet).\n3. Click **Deploy**.\n4. Approve the transaction in your MetaMask wallet.\n\n ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-03.webp)\n\nYour deployed contract will appear in the **Deployed Contracts** section, ready for interaction."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 9, "depth": 2, "title": "Hardhat", "anchor": "hardhat", "start_char": 8651, "end_char": 8853, "estimated_token_count": 33, "token_estimator": "heuristic-v1", "text": "## Hardhat\n\nHardhat provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 10, "depth": 3, "title": "Setup", "anchor": "setup-2", "start_char": 8853, "end_char": 9195, "estimated_token_count": 89, "token_estimator": "heuristic-v1", "text": "### Setup\n\nInitialize your Hardhat project:\n\n```bash\nmkdir hardhat-deployment\ncd hardhat-deployment\nnpm init -y\nnpm install --save-dev @parity/hardhat-polkadot@0.1.9\nnpx hardhat-polkadot init\n```\n\nSelect **Create a JavaScript project** when prompted.\n\nComplete the setup:\n\n```bash\necho '/ignition/deployments/' >> .gitignore\nnpm install\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 11, "depth": 3, "title": "Configure Hardhat", "anchor": "configure-hardhat", "start_char": 9195, "end_char": 10240, "estimated_token_count": 245, "token_estimator": "heuristic-v1", "text": "### Configure Hardhat\n\nEdit `hardhat.config.js`:\n\n```javascript title=\"hardhat.config.js\" hl_lines=\"21-26\"\nrequire(\"@nomicfoundation/hardhat-toolbox\")\nrequire(\"@parity/hardhat-polkadot\")\n\n/** @type import('hardhat/config').HardhatUserConfig */\nmodule.exports = {\n solidity: \"0.8.28\",\n resolc: {\n compilerSource: \"npm\",\n },\n networks: {\n hardhat: {\n polkavm: true,\n forking: {\n url: \"https://testnet-passet-hub.polkadot.io\",\n },\n adapterConfig: {\n adapterBinaryPath: \"../bin/eth-rpc\",\n dev: true,\n },\n },\n polkadotHubTestnet: {\n polkavm: true,\n url: 'https://testnet-passet-hub-eth-rpc.polkadot.io',\n chainId: 420420422,\n accounts: [vars.get('PRIVATE_KEY')],\n },\n },\n}\n```\n\nRun the following command to set the private key:\n\n```bash\nnpx hardhat vars set PRIVATE_KEY \"INSERT_PRIVATE_KEY\"\n```\n\nReplace `INSERT_PRIVATE_KEY` with your actual private key."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 12, "depth": 3, "title": "Create Your Contract", "anchor": "create-your-contract", "start_char": 10240, "end_char": 10621, "estimated_token_count": 80, "token_estimator": "heuristic-v1", "text": "### Create Your Contract\n\nReplace the default contract in `contracts/Storage.sol`:\n\n```solidity\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ncontract Storage {\n uint256 private storedNumber;\n\n function store(uint256 num) public {\n storedNumber = num;\n }\n\n function retrieve() public view returns (uint256) {\n return storedNumber;\n }\n}\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 13, "depth": 3, "title": "Compile", "anchor": "compile-2", "start_char": 10621, "end_char": 10667, "estimated_token_count": 14, "token_estimator": "heuristic-v1", "text": "### Compile\n\n```bash\nnpx hardhat compile\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 14, "depth": 3, "title": "Set Up Deployment", "anchor": "set-up-deployment", "start_char": 10667, "end_char": 10976, "estimated_token_count": 83, "token_estimator": "heuristic-v1", "text": "### Set Up Deployment\n\nCreate a deployment module in `ignition/modules/Storage.js`:\n\n```javascript\nconst { buildModule } = require('@nomicfoundation/hardhat-ignition/modules');\n\nmodule.exports = buildModule('StorageModule', (m) => {\n const storage = m.contract('Storage');\n return { storage };\n});\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 15, "depth": 3, "title": "Deploy", "anchor": "deploy-2", "start_char": 10976, "end_char": 11121, "estimated_token_count": 34, "token_estimator": "heuristic-v1", "text": "### Deploy\n\nDeploy to Polkadot Hub TestNet:\n\n```bash\nnpx hardhat ignition deploy ./ignition/modules/Storage.js --network polkadotHubTestnet\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 16, "depth": 2, "title": "Foundry", "anchor": "foundry", "start_char": 11121, "end_char": 11307, "estimated_token_count": 35, "token_estimator": "heuristic-v1", "text": "## Foundry\n\nFoundry offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 17, "depth": 3, "title": "Setup", "anchor": "setup-3", "start_char": 11307, "end_char": 11585, "estimated_token_count": 69, "token_estimator": "heuristic-v1", "text": "### Setup\n\nInstall Foundry for Polkadot:\n\n```bash\ncurl -L https://raw.githubusercontent.com/paritytech/foundry-polkadot/refs/heads/master/foundryup/install | bash\nfoundryup-polkadot\n```\n\nInitialize your project:\n\n```bash\nforge init foundry-deployment\ncd foundry-deployment\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 18, "depth": 3, "title": "Configure Foundry", "anchor": "configure-foundry", "start_char": 11585, "end_char": 11837, "estimated_token_count": 75, "token_estimator": "heuristic-v1", "text": "### Configure Foundry\n\nEdit `foundry.toml`:\n\n```toml\n[profile.default]\nsrc = \"src\"\nout = \"out\"\nlibs = [\"lib\"]\n\n[profile.default.resolc]\nresolc_compile = true\n\n[rpc_endpoints]\npolkadot_hub_testnet = \"https://testnet-passet-hub-eth-rpc.polkadot.io\"\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 19, "depth": 3, "title": "Create Your Contract", "anchor": "create-your-contract-2", "start_char": 11837, "end_char": 12212, "estimated_token_count": 80, "token_estimator": "heuristic-v1", "text": "### Create Your Contract\n\nReplace the default contract in `src/Storage.sol`:\n\n```solidity\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.9;\n\ncontract Storage {\n uint256 private storedNumber;\n\n function store(uint256 num) public {\n storedNumber = num;\n }\n\n function retrieve() public view returns (uint256) {\n return storedNumber;\n }\n}\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 20, "depth": 3, "title": "Compile", "anchor": "compile-3", "start_char": 12212, "end_char": 12392, "estimated_token_count": 46, "token_estimator": "heuristic-v1", "text": "### Compile\n\n```bash\nforge build --resolc\n```\n\nVerify the compilation by inspecting the bytecode (should start with `0x505`):\n\n```bash\nforge inspect Storage bytecode --resolc\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 21, "depth": 3, "title": "Deploy", "anchor": "deploy-3", "start_char": 12392, "end_char": 12573, "estimated_token_count": 41, "token_estimator": "heuristic-v1", "text": "### Deploy\n\nDeploy to Polkadot Hub TestNet:\n\n```bash\nforge create Storage \\\n --rpc-url polkadot_hub_testnet \\\n --private-key YOUR_PRIVATE_KEY \\\n --resolc --broadcast\n```"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 22, "depth": 2, "title": "Conclusion", "anchor": "conclusion", "start_char": 12573, "end_char": 13294, "estimated_token_count": 131, "token_estimator": "heuristic-v1", "text": "## Conclusion\n\nThis guide has demonstrated four different approaches to deploying smart contracts on Polkadot Hub. Each method offers distinct advantages:\n\n- **Ethers.js**: Best for lightweight, programmatic deployments and application integration\n- **Remix IDE**: Ideal for rapid prototyping, learning, and visual development\n- **Hardhat**: Perfect for professional workflows requiring comprehensive testing and debugging\n- **Foundry**: Excellent for developers who prefer fast, command-line driven development\n\nAll approaches use the `resolc` compiler to generate PolkaVM-compatible bytecode, ensuring your contracts run natively on Polkadot Hub. Choose the tool that best fits your workflow and project requirements."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-pvm", "page_title": "Deploy a Basic Contract to Polkadot Hub", "index": 23, "depth": 3, "title": "Next Steps", "anchor": "next-steps", "start_char": 13294, "end_char": 13872, "estimated_token_count": 156, "token_estimator": "heuristic-v1", "text": "### Next Steps\n\n- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide.\n- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide.\n- Check out in details each [development environment](/smart-contracts/dev-environments/)."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-remix", "page_title": "Deploy a Basic Contract with Remix IDE", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 42, "end_char": 399, "estimated_token_count": 71, "token_estimator": "heuristic-v1", "text": "## Introduction\n\nThis guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Remix IDE](https://remix.ethereum.org/){target=\\_blank}, which offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-remix", "page_title": "Deploy a Basic Contract with Remix IDE", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 399, "end_char": 728, "estimated_token_count": 87, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\n- Basic understanding of Solidity programming.\n- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\\_blank}). See the [step-by-step instructions](/smart-contracts/faucet/#get-test-tokens){target=\\_blank}.\n- A wallet with a private key for signing transactions."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-remix", "page_title": "Deploy a Basic Contract with Remix IDE", "index": 2, "depth": 2, "title": "Access Remix", "anchor": "access-remix", "start_char": 728, "end_char": 1290, "estimated_token_count": 136, "token_estimator": "heuristic-v1", "text": "## Access Remix\n\nNavigate to [Remix](https://remix.ethereum.org/){target=\\_blank} in your web browser.\n\nThe interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file, which will be used as the example contract throughout this guide.\n\n![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-01.webp)"} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-remix", "page_title": "Deploy a Basic Contract with Remix IDE", "index": 3, "depth": 2, "title": "Compile", "anchor": "compile", "start_char": 1290, "end_char": 1639, "estimated_token_count": 94, "token_estimator": "heuristic-v1", "text": "## Compile\n\n1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar.\n2. Click **Compile Storage.sol** or press `Ctrl+S`.\n\n![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-02.webp)\n\nCompilation errors and warnings appear in the terminal panel at the bottom of the screen."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-remix", "page_title": "Deploy a Basic Contract with Remix IDE", "index": 4, "depth": 2, "title": "Deploy", "anchor": "deploy", "start_char": 1639, "end_char": 2128, "estimated_token_count": 122, "token_estimator": "heuristic-v1", "text": "## Deploy\n\n1. Navigate to the **Deploy & Run Transactions** tab.\n2. Click the **Environment** dropdown and select **Injected Provider - MetaMask** (ensure your MetaMask wallet is connected to Polkadot Hub TestNet).\n3. Click **Deploy**.\n4. Approve the transaction in your MetaMask wallet.\n\n![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-03.webp)\n\nYour deployed contract will appear in the **Deployed Contracts** section, ready for interaction."} +{"page_id": "smart-contracts-cookbook-smart-contracts-deploy-basic-remix", "page_title": "Deploy a Basic Contract with Remix IDE", "index": 5, "depth": 2, "title": "Where to Go Next", "anchor": "where-to-go-next", "start_char": 2128, "end_char": 2978, "estimated_token_count": 228, "token_estimator": "heuristic-v1", "text": "## Where to Go Next\n\n
\n\n- Guide __Verify Your Contract__\n\n ---\n\n Now that you've deployed a basic contract, learn how to verify it with Remix.\n\n [:octicons-arrow-right-24: Get Started](/smart-contracts/dev-environments/remix/verify-a-contract/)\n\n- Guide __Deploy an ERC-20__\n\n ---\n\n Walk through deploying a fully-functional ERC-20 to the Polkadot Hub using Remix.\n\n [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-erc20/remix/)\n\n- Guide __Deploy an NFT__\n\n ---\n\n Walk through deploying a NFT to the Polkadot Hub using Remix.\n\n [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-nft/remix/) \n\n
"} {"page_id": "smart-contracts-cookbook-smart-contracts-deploy-erc20", "page_title": "Deploy an ERC-20 to Polkadot Hub", "index": 0, "depth": 2, "title": "Introduction", "anchor": "introduction", "start_char": 206, "end_char": 858, "estimated_token_count": 159, "token_estimator": "heuristic-v1", "text": "## Introduction\n\n[ERC-20](https://eips.ethereum.org/EIPS/eip-20){target=\\_blank} tokens are fungible tokens commonly used for creating cryptocurrencies, governance tokens, and staking mechanisms. Polkadot Hub enables easy token deployment with Ethereum-compatible smart contracts via PolkaVM.\n\nThis tutorial covers deploying an ERC-20 contract on the Polkadot Hub TestNet using [Polkadot Remix IDE](https://remix.polkadot.io){target=\\_blank}, a web-based development tool. [OpenZeppelin's ERC-20 contracts](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/v5.4.0/contracts/token/ERC20){target=\\_blank} are used for security and compliance."} {"page_id": "smart-contracts-cookbook-smart-contracts-deploy-erc20", "page_title": "Deploy an ERC-20 to Polkadot Hub", "index": 1, "depth": 2, "title": "Prerequisites", "anchor": "prerequisites", "start_char": 858, "end_char": 1455, "estimated_token_count": 155, "token_estimator": "heuristic-v1", "text": "## Prerequisites\n\nBefore starting, make sure you have:\n\n- [MetaMask](https://metamask.io/){target=\\_blank} installed and connected to Polkadot Hub. For detailed instructions, see the [Connect Your Wallet](/smart-contracts/integrations/wallets){target=\\_blank} section.\n- A funded account with some PAS tokens (you can get them from the [Polkadot Faucet](https://faucet.polkadot.io/?parachain=1111){target=\\_blank}). To learn how to get test tokens, check out the [Test Tokens](/smart-contracts/connect/#test-tokens){target=\\_blank} section.\n- Basic understanding of Solidity and fungible tokens."} {"page_id": "smart-contracts-cookbook-smart-contracts-deploy-erc20", "page_title": "Deploy an ERC-20 to Polkadot Hub", "index": 2, "depth": 2, "title": "Create the ERC-20 Contract", "anchor": "create-the-erc-20-contract", "start_char": 1455, "end_char": 4913, "estimated_token_count": 823, "token_estimator": "heuristic-v1", "text": "## Create the ERC-20 Contract\n\nTo create the ERC-20 contract, you can follow the steps below:\n\n1. Navigate to the [Polkadot Remix IDE](https://remix.polkadot.io){target=\\_blank}.\n2. Click in the **Create new file** button under the **contracts** folder, and name your contract as `MyToken.sol`.\n\n ![](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-1.webp)\n\n3. Now, paste the following ERC-20 contract code into the editor:\n\n ```solidity title=\"MyToken.sol\"\n // SPDX-License-Identifier: MIT\n // Compatible with OpenZeppelin Contracts ^5.0.0\n pragma solidity ^0.8.22;\n\n import {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n import {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\n\n contract MyToken is ERC20, Ownable {\n constructor(address initialOwner)\n ERC20(\"MyToken\", \"MTK\")\n Ownable(initialOwner)\n {}\n\n function mint(address to, uint256 amount) public onlyOwner {\n _mint(to, amount);\n }\n }\n ```\n\n The key components of the code above are:\n\n - Contract imports:\n\n - **[`ERC20.sol`](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/v5.4.0/contracts/token/ERC20/ERC20.sol){target=\\_blank}**: The base contract for fungible tokens, implementing core functionality like transfers, approvals, and balance tracking.\n - **[`Ownable.sol`](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/v5.4.0/contracts/access/Ownable.sol){target=\\_blank}**: Provides basic authorization control, ensuring only the contract owner can mint new tokens.\n \n - Constructor parameters:\n\n - **`initialOwner`**: Sets the address that will have administrative rights over the contract.\n - **`\"MyToken\"`**: The full name of your token.\n - **`\"MTK\"`**: The symbol representing your token in wallets and exchanges.\n\n - Key functions:\n\n - **`mint(address to, uint256 amount)`**: Allows the contract owner to create new tokens for any address. The amount should include 18 decimals (e.g., 1 token = 1000000000000000000).\n - Inherited [Standard ERC-20](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/){target=\\_blank} functions:\n - **`transfer(address recipient, uint256 amount)`**: Sends a specified amount of tokens to another address.\n - **`approve(address spender, uint256 amount)`**: Grants permission for another address to spend a specific number of tokens on behalf of the token owner.\n - **`transferFrom(address sender, address recipient, uint256 amount)`**: Transfers tokens from one address to another, if previously approved.\n - **`balanceOf(address account)`**: Returns the token balance of a specific address.\n - **`allowance(address owner, address spender)`**: Checks how many tokens an address is allowed to spend on behalf of another address.\n\n !!! tip\n Use the [OpenZeppelin Contracts Wizard](https://wizard.openzeppelin.com/){target=\\_blank} to quickly generate customized smart contracts. Simply configure your contract, copy the generated code, and paste it into Polkadot Remix IDE for deployment. Below is an example of an ERC-20 token contract created with it:\n\n ![Screenshot of the OpenZeppelin Contracts Wizard showing an ERC-20 contract configuration.](/images/smart-contracts/cookbook/smart-contracts/deploy-erc20/deploy-erc20-2.webp)"} diff --git a/llms.txt b/llms.txt index ca4111201..dbae43ccd 100644 --- a/llms.txt +++ b/llms.txt @@ -6,7 +6,7 @@ This directory lists URLs for raw Markdown pages that complement the rendered pages on the documentation site. Use these Markdown files to retain semantic context when prompting models while avoiding passing HTML elements. ## Metadata -- Documentation pages: 253 +- Documentation pages: 268 - Categories: 12 ## Docs @@ -63,6 +63,21 @@ Docs: Smart Contracts - [Polkadot Hub Smart Contract FAQs](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-faqs.md): Find answers to common questions about smart contract development, deployment, and compatibility in the Polkadot Hub ecosystem. - [Interact with Precompiles](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/develop-smart-contracts-precompiles-interact-with-precompiles.md): Learn how to interact with Polkadot Hub’s precompiles from Solidity to access native, low-level functions like hashing, pairing, EC ops, etc. - [Connect to Polkadot](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-connect.md): Explore how to connect to Polkadot Hub, configure your wallet, and obtain test tokens for developing and testing smart contracts. +- [Deploy a Basic Contract to Polkadot Hub](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-.deploy-basic-pvm.md): Learn how to deploy a basic smart contract to Polkadot Hub using the PolkaVM. +- [JavaScript with Ethers.js](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-ethers-js.md): Learn how to deploy a basic smart contract to Polkadot Hub using Ethers.js, best for lightweight, programmatic deployments and application integration. +- [Foundry](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-foundry.md): Learn how to deploy a basic smart contract to Polkadot Hub using Foundry, excellent for developers who prefer fast, command-line driven development. +- [hardhat](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-hardhat.md): Learn how to deploy a basic smart contract to Polkadot Hub using Hardhat, Perfect for professional workflows requiring comprehensive testing and debugging. +- [Remix IDE](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-deploy-basic-remix.md): Learn how to deploy a basic smart contract to Polkadot Hub using Remix IDE Ideal for rapid prototyping, learning, and visual development. +- [JavaScript with Ethers.js](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-ethers-js.md): Learn how to deploy a basic smart contract to Polkadot Hub using Ethers.js, best for lightweight, programmatic deployments and application integration. +- [Foundry](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-foundry.md): Learn how to deploy a basic smart contract to Polkadot Hub using Foundry, excellent for developers who prefer fast, command-line driven development. +- [hardhat](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-hardhat.md): Learn how to deploy a basic smart contract to Polkadot Hub using Hardhat, Perfect for professional workflows requiring comprehensive testing and debugging. +- [Remix IDE](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-contract-evm-deploy-basic-remix.md): Learn how to deploy a basic smart contract to Polkadot Hub using Remix IDE Ideal for rapid prototyping, learning, and visual development. +- [Deploy a Basic Contract with Ethers.js](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-ethers.md): Learn how to deploy a basic smart contract to Polkadot Hub using Ethers.js, best for lightweight, programmatic deployments and application integration. +- [Deploy a Basic Contract to EVM](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-evm.md): Learn how to deploy a basic smart contract to Polkadot Hub using standard EVM tools and toolchains. +- [Deploy a Basic Contract with Foundry](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-foundry.md): Learn how to deploy a basic smart contract to Polkadot Hub using Foundry, excellent for developers who prefer fast, command-line driven development. +- [Deploy a Basic Contract with Hardhat](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-hardhat.md): Learn how to deploy a basic smart contract to Polkadot Hub using Hardhat, Perfect for professional workflows requiring comprehensive testing and debugging. +- [Deploy a Basic Contract to Polkadot Hub](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-pvm.md): Learn how to deploy a basic smart contract to Polkadot Hub using the PolkaVM. +- [Deploy a Basic Contract with Remix IDE](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-basic-remix.md): Learn how to deploy a basic smart contract to Polkadot Hub using Remix IDE Ideal for rapid prototyping, learning, and visual development. - [Deploy an ERC-20 to Polkadot Hub](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-erc20.md): Deploy an ERC-20 token on Polkadot Hub using PolkaVM. This guide covers contract creation, compilation, deployment, and interaction via Polkadot Remix IDE. - [Deploy an NFT to Polkadot Hub with Ethers.js](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-nft-ethers.md): Learn how to deploy an ERC-721 NFT contract to Polkadot Hub using Ethers.js, giving you complete programmatic control over the deployment process. - [Deploy an NFT to Polkadot Hub with Foundry](https://raw.githubusercontent.com/polkadot-developers/polkadot-docs/master/.ai/pages/smart-contracts-cookbook-smart-contracts-deploy-nft-foundry.md): Learn how to deploy an ERC-721 NFT contract to Polkadot Hub using Foundry, a Rust toolkit with high-performance compilation. diff --git a/smart-contracts/cookbook/smart-contracts/.deploy-basic-pvm.md b/smart-contracts/cookbook/smart-contracts/.deploy-basic-pvm.md new file mode 100644 index 000000000..1ee26a5c6 --- /dev/null +++ b/smart-contracts/cookbook/smart-contracts/.deploy-basic-pvm.md @@ -0,0 +1,471 @@ +--- +title: Deploy a Basic Contract to Polkadot Hub +description: Learn how to deploy a basic smart contract to Polkadot Hub using the PolkaVM. +categories: Smart Contracts +--- + +# Deploy a Basic Contract + +## Introduction + +Deploying smart contracts to [Polkadot Hub](/smart-contracts/overview/#smart-contract-development){target=\_blank} can be accomplished through various tools and environments, each suited to different development workflows. This guide demonstrates how to deploy a basic PolkaVM (PVM) smart contract using four popular approaches: JavaScript with [Ethers.js](https://docs.ethers.org/v6/){target=\_blank}, [Remix IDE](https://remix.live/){target=\_blank}, [Hardhat](https://hardhat.org/){target=\_blank}, and [Foundry](https://getfoundry.sh/){target=\_blank}. + +All these tools leverage the `revive` compiler to transform Solidity smart contracts into PolkaVM bytecode, making them compatible with Polkadot Hub's native smart contract environment. Whether you prefer working with lightweight JavaScript libraries, visual browser-based IDEs, comprehensive development frameworks, or fast command-line toolkits, this guide covers the deployment process for each approach. + +**Prerequisites:** + +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later (for JavaScript/Hardhat approaches). +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). +- A wallet with a private key for signing transactions. + +## JavaScript with Ethers.js + +Ethers.js provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications. + +### Setup + +First, initialize your project and install dependencies: + +```bash +mkdir ethers-deployment +cd ethers-deployment +npm init -y +npm install ethers @parity/resolc +``` + +### Create and Compile Your Contract + +Create a simple storage contract in `contracts/Storage.sol`: + +```solidity title="contracts/Storage.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +Create a compilation script `compile.js`: + +```javascript title="compile.js" +const { compile } = require('@parity/resolc'); +const { readFileSync, writeFileSync } = require('fs'); +const { basename, join } = require('path'); + +const compileContract = async (solidityFilePath, outputDir) => { + try { + // Read the Solidity file + const source = readFileSync(solidityFilePath, 'utf8'); + + // Construct the input object for the compiler + const input = { + [basename(solidityFilePath)]: { content: source }, + }; + + console.log(`Compiling contract: ${basename(solidityFilePath)}...`); + + // Compile the contract + const out = await compile(input); + + for (const contracts of Object.values(out.contracts)) { + for (const [name, contract] of Object.entries(contracts)) { + console.log(`Compiled contract: ${name}`); + + // Write the ABI + const abiPath = join(outputDir, `${name}.json`); + writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2)); + console.log(`ABI saved to ${abiPath}`); + + // Write the bytecode + const bytecodePath = join(outputDir, `${name}.polkavm`); + writeFileSync( + bytecodePath, + Buffer.from(contract.evm.bytecode.object, 'hex'), + ); + console.log(`Bytecode saved to ${bytecodePath}`); + } + } + } catch (error) { + console.error('Error compiling contracts:', error); + } +}; + +const solidityFilePath = join(__dirname, 'contracts/Storage.sol'); +const outputDir = join(__dirname, 'contracts'); + +compileContract(solidityFilePath, outputDir); +``` + +Run the compilation: + +```bash +node compile.js +``` + +### Deploy the Contract + +Create a deployment script `deploy.js`: + +```javascript title="deploy.js" +const { writeFileSync, existsSync, readFileSync } = require('fs'); +const { join } = require('path'); +const { ethers, JsonRpcProvider } = require('ethers'); + +const codegenDir = join(__dirname); + +// Creates a provider with specified RPC URL and chain details +const createProvider = (rpcUrl, chainId, chainName) => { + const provider = new JsonRpcProvider(rpcUrl, { + chainId: chainId, + name: chainName, + }); + return provider; +}; + +// Reads and parses the ABI file for a given contract +const getAbi = (contractName) => { + try { + return JSON.parse( + readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'), + ); + } catch (error) { + console.error( + `Could not find ABI for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +// Reads the compiled bytecode for a given contract +const getByteCode = (contractName) => { + try { + const bytecodePath = join( + codegenDir, + 'contracts', + `${contractName}.polkavm`, + ); + return `0x${readFileSync(bytecodePath).toString('hex')}`; + } catch (error) { + console.error( + `Could not find bytecode for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +const deployContract = async (contractName, mnemonic, providerConfig) => { + console.log(`Deploying ${contractName}...`); + + try { + // Step 1: Set up provider and wallet + const provider = createProvider( + providerConfig.rpc, + providerConfig.chainId, + providerConfig.name, + ); + const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic); + const wallet = walletMnemonic.connect(provider); + + // Step 2: Create and deploy the contract + const factory = new ethers.ContractFactory( + getAbi(contractName), + getByteCode(contractName), + wallet, + ); + const contract = await factory.deploy(); + await contract.waitForDeployment(); + + // Step 3: Save deployment information + const address = await contract.getAddress(); + console.log(`Contract ${contractName} deployed at: ${address}`); + + const addressesFile = join(codegenDir, 'contract-address.json'); + const addresses = existsSync(addressesFile) + ? JSON.parse(readFileSync(addressesFile, 'utf8')) + : {}; + addresses[contractName] = address; + writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8'); + } catch (error) { + console.error(`Failed to deploy contract ${contractName}:`, error); + } +}; + +const providerConfig = { + rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + name: 'polkadot-hub-testnet', +}; + +const mnemonic = 'INSERT_MNEMONIC'; + +deployContract('Storage', mnemonic, providerConfig); +``` + +Replace the `INSERT_MNEMONIC` placeholder with your actual mnemonic. + +Execute the deployment: + +```bash +node deploy.js +``` + +After running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions. + +## Remix IDE + +Remix IDE offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development. + +### Access Remix + +Navigate to [https://remix.polkadot.io/](https://remix.polkadot.io/){target=\_blank} in your web browser. + +The interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file: + +![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-01.webp) + +### Compile + +1. To compile your contract: + 1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar. + 2. Click **Compile Storage.sol** or press `Ctrl+S`. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-02.webp) + +Compilation errors and warnings appear in the terminal panel at the bottom of the screen. + +### Deploy + +1. Navigate to the **Deploy & Run Transactions** tab. +2. Click the **Environment** dropdown and select **Injected Provider - MetaMask** (ensure your MetaMask wallet is connected to Polkadot Hub TestNet). +3. Click **Deploy**. +4. Approve the transaction in your MetaMask wallet. + + ![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic-pvm/deploy-basic-pvm-03.webp) + +Your deployed contract will appear in the **Deployed Contracts** section, ready for interaction. + +## Hardhat + +Hardhat provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects. + +### Setup + +Initialize your Hardhat project: + +```bash +mkdir hardhat-deployment +cd hardhat-deployment +npm init -y +npm install --save-dev @parity/hardhat-polkadot@0.1.9 +npx hardhat-polkadot init +``` + +Select **Create a JavaScript project** when prompted. + +Complete the setup: + +```bash +echo '/ignition/deployments/' >> .gitignore +npm install +``` + +### Configure Hardhat + +Edit `hardhat.config.js`: + +```javascript title="hardhat.config.js" hl_lines="21-26" +require("@nomicfoundation/hardhat-toolbox") +require("@parity/hardhat-polkadot") + +/** @type import('hardhat/config').HardhatUserConfig */ +module.exports = { + solidity: "0.8.28", + resolc: { + compilerSource: "npm", + }, + networks: { + hardhat: { + polkavm: true, + forking: { + url: "https://testnet-passet-hub.polkadot.io", + }, + adapterConfig: { + adapterBinaryPath: "../bin/eth-rpc", + dev: true, + }, + }, + polkadotHubTestnet: { + polkavm: true, + url: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + accounts: [vars.get('PRIVATE_KEY')], + }, + }, +} +``` + +Run the following command to set the private key: + +```bash +npx hardhat vars set PRIVATE_KEY "INSERT_PRIVATE_KEY" +``` + +Replace `INSERT_PRIVATE_KEY` with your actual private key. + +### Create Your Contract + +Replace the default contract in `contracts/Storage.sol`: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +### Compile + +```bash +npx hardhat compile +``` + +### Set Up Deployment + +Create a deployment module in `ignition/modules/Storage.js`: + +```javascript +const { buildModule } = require('@nomicfoundation/hardhat-ignition/modules'); + +module.exports = buildModule('StorageModule', (m) => { + const storage = m.contract('Storage'); + return { storage }; +}); +``` + +### Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +npx hardhat ignition deploy ./ignition/modules/Storage.js --network polkadotHubTestnet +``` + +## Foundry + +Foundry offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment. + +### Setup + +Install Foundry for Polkadot: + +```bash +curl -L https://raw.githubusercontent.com/paritytech/foundry-polkadot/refs/heads/master/foundryup/install | bash +foundryup-polkadot +``` + +Initialize your project: + +```bash +forge init foundry-deployment +cd foundry-deployment +``` + +### Configure Foundry + +Edit `foundry.toml`: + +```toml +[profile.default] +src = "src" +out = "out" +libs = ["lib"] + +[profile.default.resolc] +resolc_compile = true + +[rpc_endpoints] +polkadot_hub_testnet = "https://testnet-passet-hub-eth-rpc.polkadot.io" +``` + +### Create Your Contract + +Replace the default contract in `src/Storage.sol`: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +### Compile + +```bash +forge build --resolc +``` + +Verify the compilation by inspecting the bytecode (should start with `0x505`): + +```bash +forge inspect Storage bytecode --resolc +``` + +### Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +forge create Storage \ + --rpc-url polkadot_hub_testnet \ + --private-key YOUR_PRIVATE_KEY \ + --resolc --broadcast +``` + +## Conclusion + +This guide has demonstrated four different approaches to deploying smart contracts on Polkadot Hub. Each method offers distinct advantages: + +- **Ethers.js**: Best for lightweight, programmatic deployments and application integration +- **Remix IDE**: Ideal for rapid prototyping, learning, and visual development +- **Hardhat**: Perfect for professional workflows requiring comprehensive testing and debugging +- **Foundry**: Excellent for developers who prefer fast, command-line driven development + +All approaches use the `resolc` compiler to generate PolkaVM-compatible bytecode, ensuring your contracts run natively on Polkadot Hub. Choose the tool that best fits your workflow and project requirements. + +### Next Steps + +- Deploy an ERC-20 token on Polkadot Hub, either using the [Deploy an ERC-20](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide or the [Deploy an ERC-20 to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-erc20) guide. +- Deploy an NFT on Polkadot Hub, either using the [Deploy an NFT](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide or the [Deploy an NFT to Polkadot Hub](/smart-contracts/cookbook/smart-contracts/deploy-nft) guide. +- Check out in details each [development environment](/smart-contracts/dev-environments/). \ No newline at end of file diff --git a/smart-contracts/cookbook/smart-contracts/.nav.yml b/smart-contracts/cookbook/smart-contracts/.nav.yml index a55f054d9..1ba477d54 100644 --- a/smart-contracts/cookbook/smart-contracts/.nav.yml +++ b/smart-contracts/cookbook/smart-contracts/.nav.yml @@ -1,4 +1,4 @@ nav: -- 'Deploy a Basic Contract': deploy-basic.md +- 'Deploy a Basic Contract': deploy-basic - 'Deploy an ERC-20': deploy-erc20.md - 'Deploy an NFT': deploy-nft \ No newline at end of file diff --git a/smart-contracts/cookbook/smart-contracts/deploy-basic.md b/smart-contracts/cookbook/smart-contracts/deploy-basic.md deleted file mode 100644 index 30404ce4c..000000000 --- a/smart-contracts/cookbook/smart-contracts/deploy-basic.md +++ /dev/null @@ -1 +0,0 @@ -TODO \ No newline at end of file diff --git a/smart-contracts/cookbook/smart-contracts/deploy-basic/.nav.yml b/smart-contracts/cookbook/smart-contracts/deploy-basic/.nav.yml new file mode 100644 index 000000000..3c9f0eac9 --- /dev/null +++ b/smart-contracts/cookbook/smart-contracts/deploy-basic/.nav.yml @@ -0,0 +1,5 @@ +nav: + - 'Using Ethers.js': ethers.md + - 'Using Remix IDE': remix.md + - 'Using Hardhat': hardhat.md + - 'Using Foundry': foundry.md diff --git a/smart-contracts/cookbook/smart-contracts/deploy-basic/ethers.md b/smart-contracts/cookbook/smart-contracts/deploy-basic/ethers.md new file mode 100644 index 000000000..9f2eb8849 --- /dev/null +++ b/smart-contracts/cookbook/smart-contracts/deploy-basic/ethers.md @@ -0,0 +1,263 @@ +--- +title: Deploy a Basic Contract with Ethers.js +description: Learn how to deploy a basic smart contract to Polkadot Hub using Ethers.js, best for lightweight, programmatic deployments and application integration. +categories: Smart Contracts +--- + +# Deploy a Basic Contract with Ethers.js + +## Introduction + +This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Ethers.js](https://docs.ethers.org/v6/){target=\_blank}, which provides a lightweight approach for deploying contracts using pure JavaScript. This method is ideal for developers who want programmatic control over the deployment process or need to integrate contract deployment into existing applications. + +## Prerequisites + +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). See the [step-by-step instructions](/smart-contracts/faucet/#get-test-tokens){target=\_blank}. +- A wallet with a private key for signing transactions. + +## Set Up Your Project + +First, initialize your project and install dependencies: + +```bash +mkdir ethers-deployment +cd ethers-deployment +npm init -y +npm install ethers@6.15.0 solc@0.8.30 +``` + +## Create Your Contract + +Create a simple storage contract in `contracts/Storage.sol`: + +```solidity title="contracts/Storage.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +## Compile + +Create a compilation script `compile.js`: + +```javascript title="compile.js" +const solc = require('solc'); +const { readFileSync, writeFileSync } = require('fs'); +const { basename, join } = require('path'); + +const compileContract = async (solidityFilePath, outputDir) => { + try { + // Read the Solidity file + const source = readFileSync(solidityFilePath, 'utf8'); + + // Construct the input object for the compiler + const input = { + language: 'Solidity', + sources: { + [basename(solidityFilePath)]: { content: source }, + }, + settings: { + outputSelection: { + '*': { + '*': ['*'], + }, + }, + }, + }; + + console.log(`Compiling contract: ${basename(solidityFilePath)}...`); + + // Compile the contract + const output = JSON.parse(solc.compile(JSON.stringify(input))); + + if (output.errors) { + output.errors.forEach(error => { + console.error('Compilation error:', error.message); + }); + return; + } + + for (const contracts of Object.values(output.contracts)) { + for (const [name, contract] of Object.entries(contracts)) { + console.log(`Compiled contract: ${name}`); + + // Write the ABI + const abiPath = join(outputDir, `${name}.json`); + writeFileSync(abiPath, JSON.stringify(contract.abi, null, 2)); + console.log(`ABI saved to ${abiPath}`); + + // Write the bytecode + const bytecodePath = join(outputDir, `${name}.bin`); + writeFileSync(bytecodePath, + Buffer.from( + contract.evm.bytecode.object, + 'hex' + )); + console.log(`Bytecode saved to ${bytecodePath}`); + } + } + } catch (error) { + console.error('Error compiling contracts:', error); + } +}; + +const solidityFilePath = join(__dirname, 'contracts/Storage.sol'); +const outputDir = join(__dirname, 'contracts'); + +compileContract(solidityFilePath, outputDir); +``` + +Run the compilation: + +```bash +node compile.js +``` + +## Deploy + +Create a deployment script `deploy.js`: + +```javascript title="deploy.js" +const { writeFileSync, existsSync, readFileSync } = require('fs'); +const { join } = require('path'); +const { ethers, JsonRpcProvider } = require('ethers'); + +const codegenDir = join(__dirname); + +// Creates a provider with specified RPC URL and chain details +const createProvider = (rpcUrl, chainId, chainName) => { + const provider = new JsonRpcProvider(rpcUrl, { + chainId: chainId, + name: chainName, + }); + return provider; +}; + +// Reads and parses the ABI file for a given contract +const getAbi = (contractName) => { + try { + return JSON.parse( + readFileSync(join(codegenDir, 'contracts', `${contractName}.json`), 'utf8'), + ); + } catch (error) { + console.error( + `Could not find ABI for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +// Reads the compiled bytecode for a given contract +const getByteCode = (contractName) => { + try { + const bytecodePath = join( + codegenDir, + 'contracts', + `${contractName}.bin`, + ); + return `0x${readFileSync(bytecodePath).toString('hex')}`; + } catch (error) { + console.error( + `Could not find bytecode for contract ${contractName}:`, + error.message, + ); + throw error; + } +}; + +const deployContract = async (contractName, mnemonic, providerConfig) => { + console.log(`Deploying ${contractName}...`); + + try { + // Step 1: Set up provider and wallet + const provider = createProvider( + providerConfig.rpc, + providerConfig.chainId, + providerConfig.name, + ); + const walletMnemonic = ethers.Wallet.fromPhrase(mnemonic); + const wallet = walletMnemonic.connect(provider); + + // Step 2: Create and deploy the contract + const factory = new ethers.ContractFactory( + getAbi(contractName), + getByteCode(contractName), + wallet, + ); + const contract = await factory.deploy(); + await contract.waitForDeployment(); + + // Step 3: Save deployment information + const address = await contract.getAddress(); + console.log(`Contract ${contractName} deployed at: ${address}`); + + const addressesFile = join(codegenDir, 'contract-address.json'); + const addresses = existsSync(addressesFile) + ? JSON.parse(readFileSync(addressesFile, 'utf8')) + : {}; + addresses[contractName] = address; + writeFileSync(addressesFile, JSON.stringify(addresses, null, 2), 'utf8'); + } catch (error) { + console.error(`Failed to deploy contract ${contractName}:`, error); + } +}; + +const providerConfig = { + rpc: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + name: 'polkadot-hub-testnet', +}; + +const mnemonic = 'INSERT_MNEMONIC'; + +deployContract('Storage', mnemonic, providerConfig); +``` + +Replace the `INSERT_MNEMONIC` placeholder with your actual mnemonic. + +!!! warning + Never embed private keys, mnemonic phrases, or security-sensitive credentials directly into your JavaScript, TypeScript, or any front-end/client-side files. + +Execute the deployment: + +```bash +node deploy.js +``` + +After running this script, your contract will be deployed to Polkadot Hub, and its address will be saved in `contract-address.json` within your project directory. You can use this address for future contract interactions. + +## Where to Go Next + +
+ +- Guide __Deploy an ERC-20__ + + --- + + Walk through deploying a fully-functional ERC-20 to the Polkadot Hub using Ethers.js. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-erc20/ethers/) + +- Guide __Deploy an NFT__ + + --- + + Walk through deploying a NFT to the Polkadot Hub using Ethers.js. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-nft/ethers/) + +
\ No newline at end of file diff --git a/smart-contracts/cookbook/smart-contracts/deploy-basic/foundry.md b/smart-contracts/cookbook/smart-contracts/deploy-basic/foundry.md new file mode 100644 index 000000000..3202c9cca --- /dev/null +++ b/smart-contracts/cookbook/smart-contracts/deploy-basic/foundry.md @@ -0,0 +1,121 @@ +--- +title: Deploy a Basic Contract with Foundry +description: Learn how to deploy a basic smart contract to Polkadot Hub using Foundry, excellent for developers who prefer fast, command-line driven development. +categories: Smart Contracts +--- + +# Deploy a Basic Contract with Foundry + +This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Foundry](https://getfoundry.sh/){target=\_blank}, which offers a fast, modular toolkit written in Rust. It's perfect for developers who prefer command-line interfaces and need high-performance compilation and deployment. + +## Prerequisites + +- Basic understanding of Solidity programming. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). See the [step-by-step instructions](/smart-contracts/faucet/#get-test-tokens){target=\_blank}. +- A wallet with a private key for signing transactions. + +## Set Up Your Project + +Install Foundry: + +```bash +curl -L https://foundry.paradigm.xyz | bash +foundryup +``` + +Initialize your project: + +```bash +forge init foundry-deployment +cd foundry-deployment +``` + +## Configure Foundry + +Edit `foundry.toml`: + +```toml +[profile.default] +src = "src" +out = "out" +libs = ["lib"] + +[rpc_endpoints] +polkadot_hub_testnet = "https://testnet-passet-hub-eth-rpc.polkadot.io" +``` + +## Create Your Contract + +Replace the default contract in `src/Storage.sol`: + +```solidity title="src/Storage.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +## Compile + +```bash +forge build +``` + +Verify the compilation by inspecting the bytecode: + +```bash +forge inspect Storage bytecode +``` + +## Deploy + +Deploy to Polkadot Hub TestNet: + +```bash +forge create Storage \ + --rpc-url polkadot_hub_testnet \ + --private-key YOUR_PRIVATE_KEY \ + --broadcast +``` + +Replace the `YOUR_PRIVATE_KEY` placeholder with your actual private key. + +## Where to Go Next + +
+ +- Guide __Verify Your Contract__ + + --- + + Now that you've deployed a basic contract, learn how to verify it with Foundry. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/dev-environments/foundry/verify-a-contract/) + +- Guide __Deploy an ERC-20__ + + --- + + Walk through deploying a fully-functional ERC-20 to the Polkadot Hub using Foundry. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-erc20/foundry/) + +- Guide __Deploy an NFT__ + + --- + + Walk through deploying a NFT to the Polkadot Hub using Foundry. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-nft/foundry/) + +
\ No newline at end of file diff --git a/smart-contracts/cookbook/smart-contracts/deploy-basic/hardhat.md b/smart-contracts/cookbook/smart-contracts/deploy-basic/hardhat.md new file mode 100644 index 000000000..f9255021b --- /dev/null +++ b/smart-contracts/cookbook/smart-contracts/deploy-basic/hardhat.md @@ -0,0 +1,164 @@ +--- +title: Deploy a Basic Contract with Hardhat +description: Learn how to deploy a basic smart contract to Polkadot Hub using Hardhat, Perfect for professional workflows requiring comprehensive testing and debugging. +categories: Smart Contracts +--- + +# Deploy a Basic Contract with + +## Introduction + +This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Hardhat](https://hardhat.org/){target=\_blank}, which provides a comprehensive development environment with built-in testing, debugging, and deployment capabilities. It's ideal for professional development workflows and team projects. + +## Prerequisites + +- Basic understanding of Solidity programming. +- [Node.js](https://nodejs.org/en/download){target=\_blank} v22.13.1 or later. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). See the [step-by-step instructions](/smart-contracts/faucet/#get-test-tokens){target=\_blank}. +- A wallet with a private key for signing transactions. + +## Set Up Your Project + +Initialize your Hardhat project: + +```bash +mkdir hardhat-deployment +cd hardhat-deployment +npx hardhat --init +``` + +## Configure Hardhat + +Edit `hardhat.config.js`: + +```javascript title='hardhat.config.js' hl_lines='39-43' +import type { HardhatUserConfig } from 'hardhat/config'; + +import hardhatToolboxViemPlugin from '@nomicfoundation/hardhat-toolbox-viem'; +import { configVariable } from 'hardhat/config'; + +const config: HardhatUserConfig = { + plugins: [hardhatToolboxViemPlugin], + solidity: { + profiles: { + default: { + version: '0.8.28', + }, + production: { + version: '0.8.28', + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, + }, + }, + }, + networks: { + hardhatMainnet: { + type: 'edr-simulated', + chainType: 'l1', + }, + hardhatOp: { + type: 'edr-simulated', + chainType: 'op', + }, + sepolia: { + type: 'http', + chainType: 'l1', + url: configVariable('SEPOLIA_RPC_URL'), + accounts: [configVariable('SEPOLIA_PRIVATE_KEY')], + }, + polkadotHubTestnet: { + url: 'https://testnet-passet-hub-eth-rpc.polkadot.io', + chainId: 420420422, + accounts: [configVariable('PRIVATE_KEY')], + }, + }, +}; + +export default config; + +``` + +!!! tip + Learn how to use Hardhat's [Config Variables](https://hardhat.org/docs/learn-more/configuration-variables){target=\_blank} to handle your private keys in a secure way. + +## Create Your Contract + +Replace the default contract in `contracts/Storage.sol`: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +contract Storage { + uint256 private storedNumber; + + function store(uint256 num) public { + storedNumber = num; + } + + function retrieve() public view returns (uint256) { + return storedNumber; + } +} +``` + +## Compile + +```bash +npx hardhat build +``` + +## Set Up Deployment + +Create a deployment module in `ignition/modules/Storage.ts`: + +```typescript title="ignition/modules/Storage.ts" +import { buildModule } from '@nomicfoundation/hardhat-ignition/modules'; + +export default buildModule('StorageModule', (m) => { + const storage = m.contract('Storage'); + return { storage }; +}); +``` + +## Deploy the Contract + +Deploy to Polkadot Hub TestNet: + +```bash +npx hardhat ignition deploy ignition/modules/Storage.ts --network polkadotHubTestnet +``` + +## Where to Go Next + +
+ +- Guide __Verify Your Contract__ + + --- + + Now that you've deployed a basic contract, learn how to verify it with Hardhat. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/dev-environments/hardhat/verify-a-contract/) + +- Guide __Deploy an ERC-20__ + + --- + + Walk through deploying a fully-functional ERC-20 to the Polkadot Hub using Hardhat. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-erc20/hardhat/) + +- Guide __Deploy an NFT__ + + --- + + Walk through deploying a NFT to the Polkadot Hub using Hardhat. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-nft/hardhat/) + +
\ No newline at end of file diff --git a/smart-contracts/cookbook/smart-contracts/deploy-basic/remix.md b/smart-contracts/cookbook/smart-contracts/deploy-basic/remix.md new file mode 100644 index 000000000..2618936b9 --- /dev/null +++ b/smart-contracts/cookbook/smart-contracts/deploy-basic/remix.md @@ -0,0 +1,75 @@ +--- +title: Deploy a Basic Contract with Remix IDE +description: Learn how to deploy a basic smart contract to Polkadot Hub using Remix IDE Ideal for rapid prototyping, learning, and visual development. +categories: Smart Contracts +--- + +# Deploy a Basic Contract with Remix IDE + +## Introduction + +This guide demonstrates how to deploy a basic Solidity smart contract to Polkadot Hub using [Remix IDE](https://remix.ethereum.org/){target=\_blank}, which offers a visual, browser-based environment perfect for rapid prototyping and learning. It requires no local installation and provides an intuitive interface for contract development. + +## Prerequisites + +- Basic understanding of Solidity programming. +- Test tokens for gas fees (available from the [Polkadot faucet](https://faucet.polkadot.io/){target=\_blank}). See the [step-by-step instructions](/smart-contracts/faucet/#get-test-tokens){target=\_blank}. +- A wallet with a private key for signing transactions. + +## Access Remix + +Navigate to [Remix](https://remix.ethereum.org/){target=\_blank} in your web browser. + +The interface will load with a default workspace containing sample contracts. In this interface, you can access a file explorer, edit your code, interact with various plugins for development, and use a terminal. By default, you will see the `contracts` folder with the `Storage.sol` file, which will be used as the example contract throughout this guide. + +![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-01.webp) + +## Compile + +1. Navigate to the **Solidity Compiler** tab, which is the third icon in the left sidebar. +2. Click **Compile Storage.sol** or press `Ctrl+S`. + +![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-02.webp) + +Compilation errors and warnings appear in the terminal panel at the bottom of the screen. + +## Deploy + +1. Navigate to the **Deploy & Run Transactions** tab. +2. Click the **Environment** dropdown and select **Injected Provider - MetaMask** (ensure your MetaMask wallet is connected to Polkadot Hub TestNet). +3. Click **Deploy**. +4. Approve the transaction in your MetaMask wallet. + +![](/images/smart-contracts/cookbook/smart-contracts/deploy-basic/deploy-basic/deploy-basic-03.webp) + +Your deployed contract will appear in the **Deployed Contracts** section, ready for interaction. + +## Where to Go Next + +
+ +- Guide __Verify Your Contract__ + + --- + + Now that you've deployed a basic contract, learn how to verify it with Remix. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/dev-environments/remix/verify-a-contract/) + +- Guide __Deploy an ERC-20__ + + --- + + Walk through deploying a fully-functional ERC-20 to the Polkadot Hub using Remix. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-erc20/remix/) + +- Guide __Deploy an NFT__ + + --- + + Walk through deploying a NFT to the Polkadot Hub using Remix. + + [:octicons-arrow-right-24: Get Started](/smart-contracts/cookbook/smart-contracts/deploy-nft/remix/) + +
\ No newline at end of file