Berachain Docs 中文版
by DocsZH
  • 入门学习
    • 介绍 Berachain
      • 什么是 Berachain
      • 什么是流动性证明
      • 什么是 BeaconKit
      • 连接到 Berachain
      • 如何获得 $BERA
    • Berachain 测试网
      • Berachain 测试网 V1 与 V2
    • PoL 流动性证明
      • 流动性证明概述
      • 流动性证明参与者
      • 奖励金库
      • 激励系统
      • 原生代币系统
        • $BERA
        • $BGT
        • $HONEY
    • 治理模型
      • 治理模型概述
      • 奖励金库白名单
    • 指南
      • 流动性证明常见问题
    • 原生 dApps
      • 测试网水龙头
      • 区块浏览器
      • BEX
      • Bend
      • Berps
      • BGT Station
      • Honey Swap
    • 帮助中心
      • 常见问题
      • 名词解释
  • 开发者文档
    • 面向开发者的 Berachain
      • 流动性证明架构
      • 网络配置
      • 已部署合约
      • 开发者工具
      • 测试网水龙头
      • 测试网区块浏览器
    • 开发者快速入门
      • 智能合约部署
      • 前端部署
    • 开发者指南
      • 使用 Hardhat 部署 HelloWorld 合约
      • 使用 Foundry 部署 ERC20 合约
      • 使用 NextJS & WalletConnect 部署合约
      • 开发者外部资源
      • 非 ERC20 代币流动性证明集成
    • 已部署合约参考
  • 节点运行文档
    • Berachain 节点
      • 节点架构概述
      • BeaconKit 共识层
      • EVM 执行层
      • 节点运行快速入门
      • BeaconKit GitHub 存储库
    • 节点指南
      • 使用 Kurtosis 运行本地开发网
      • 从快照同步节点
由 GitBook 提供支持
在本页
  • 先决条件
  • 创建HelloWorld代码设置
  • 创建HelloWorld合约
  • 测试HelloWorld合约
  • 为Berachain合约部署配置Hardhat
  • 在Berachain部署HelloWorld合约
  • 验证HelloWorld合约
  • 完整代码库
  1. 开发者文档
  2. 开发者指南

使用 Hardhat 部署 HelloWorld 合约

上一页开发者指南下一页使用 Foundry 部署 ERC20 合约

最后更新于6个月前

请在GitHub参阅完整的代码库。

本节将展示如何使用创建新的Solidity合约,配置Berachain网络详细信息,将合约部署到Berachain,以及验证合约。

先决条件

开始之前,请确保你的本地设备上满足以下条件:

  • 持有$BERA代币的钱包(合约部署费用,参阅文档)

  • NVM或Node v18.18.2

  • pnpm, yarn 或 npm

创建HelloWorld代码设置

首先,为HelloWorld创建一个新的文件夹:

mkdir create-helloworld-contract-using-hardhat;
cd create-helloworld-contract-using-hardhat;

然后,启动Hardhat,并创建viem模板:

# FROM ./create-helloworld-contract-using-hardhat;

npx hardhat init;

# [Expected Prompts]:
# 888    888                      888 888               888
# 888    888                      888 888               888
# 888    888                      888 888               888
# 8888888888  8888b.  888d888 .d88888 88888b.   8888b.  888888
# 888    888     "88b 888P"  d88" 888 888 "88b     "88b 888
# 888    888 .d888888 888    888  888 888  888 .d888888 888
# 888    888 888  888 888    Y88b 888 888  888 888  888 Y88b.
# 888    888 "Y888888 888     "Y88888 888  888 "Y888888  "Y888
#
# 👷 Welcome to Hardhat v2.18.3 👷‍
#
# ✔ What do you want to do? · Create a TypeScript project (with Viem)
# ✔ Hardhat project root: · /path/to/create-helloworld-contract-using-hardhat
# ✔ Do you want to add a .gitignore? (Y/n) · y
# ✔ Do you want to install this sample project's dependencies with npm (hardhat @nomicfoundation/#  hardhat-toolbox-viem)? (Y/n) · y

安装dotenv依赖项,以便使用环境变量。

# FROM ./create-helloworld-contract-using-hardhat;

pnpm add -D dotenv;

创建HelloWorld合约

上述操作,Hardhat创建了需要的文件。现在,已经准备好一切,可以创建一个新的Solidity合约了。

首先,将Hardhat创建的文件重命名为HelloWorld.sol:

# FROM ./create-helloworld-contract-using-hardhat;

# Renames `Lock.sol` to `HelloWorld.sol`
mv contracts/Lock.sol contracts/HelloWorld.sol;

然后,替换重命名的HelloWorld.sol文件中的现有代码。

文件位置:./contract/HelloWorld.sol,运行以下代码:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

contract HelloWorld {
    // Events that allows for emitting a message
    event NewGreeting(address sender, string message);

    // Variables
    string greeting;

    // Main constructor run at deployment
    constructor(string memory _greeting) {
        greeting = _greeting;
        emit NewGreeting(msg.sender, _greeting);
    }

    // Get function
    function getGreeting() public view returns (string memory) {
        return greeting;
    }

    // Set function
    function setGreeting(string memory _greeting) public {
        greeting = _greeting;
        emit NewGreeting(msg.sender, _greeting);
    }
}

我们已经创建了一个新的Solidity合约,接下来测试合约能否成功编译:

# FROM ./create-helloworld-contract-using-hardhat;

npx hardhat compile;

# [Expected Output]:
# Compiled 1 Solidity file successfully (evm target: paris).

你还可以通过对package.json文件进行一些修改,简化编译步骤。

文件位置:./package.json,运行以下代码:

{
  "name": "create-helloworld-contract-using-hardhat",
  "scripts": {

    "compile": "./node_modules/.bin/hardhat compile"
  }, 
  "devDependencies": {
    "@nomicfoundation/hardhat-toolbox-viem": "^1.0.0",
    "dotenv": "^16.3.1",
    "hardhat": "^2.18.3"
  }
}

现在,可以使用下方代码编译合约:

# FROM ./create-helloworld-contract-using-hardhat;

pnpm compile; # npm run compile or yarn run compil;

# [Expected Output]:
# Nothing to compile

测试HelloWorld合约

合约成功创建后,需要通过编写一些测试程序来确保合约能正常运行。

首先,重命名Hardhat在/test目录中创建的测试文件:

# FROM ./create-helloworld-contract-using-hardhat;

# Renames `Lock.ts` to `HelloWorld.test.ts`
mv test/Lock.ts test/HellWorld.test.ts;

然后,替换重命名的HelloWorld.test.ts文件中的现有代码。

文件位置:./test/HelloWorld.test.ts,运行以下代码:

// Imports
// ========================================================
import { loadFixture } from "@nomicfoundation/hardhat-toolbox-viem/network-helpers";
import { expect } from "chai";
import hre from "hardhat";

// Tests
// ========================================================
describe("HelloWorld", function () {
  // We define a fixture to reuse the same setup in every test.
  // We use loadFixture to run this setup once, snapshot that state,
  // and reset Hardhat Network to that snapshot in every test.
  async function deployFixture() {
    // Contracts are deployed using the first signer/account by default
    const [owner, otherAccount] = await hre.viem.getWalletClients();

    const contract = await hre.viem.deployContract("HelloWorld", [
      "Test Message",
    ]);
    const publicClient = await hre.viem.getPublicClient();

    return {
      owner,
      otherAccount,
      publicClient,
      contract,
    };
  }

  /**
   *
   */
  describe("Deployment", function () {
    /**
     *
     */
    it("Should deploy with original message", async function () {
      // Setup
      const { contract } = await loadFixture(deployFixture);

      // Init + Expectations
      expect(await contract.read.getGreeting()).to.equal("Test Message");
    });

    /**
     *
     */
    it("Should set a new message", async function () {
      // Setup
      const { contract, owner } = await loadFixture(deployFixture);

      // Init
      await contract.write.setGreeting(["Hello There"]);

      // Expectations
      expect(await contract.read.getGreeting()).to.equal("Hello There");
    });
  });
});

接下来,运行下方代码以运行测试程序:

# FROM ./create-helloworld-contract-using-hardhat;

npx hardhat test;

# [Expected Output]:
#   HelloWorld
#     Deployment
#       ✔ Should deploy with original message (2723ms)
#       ✔ Should set a new message
#
#
#   2 passing (3s)

你还可以通过对package.json文件进行一些修改,以便更轻松地运行pnpm test测试程序。

文件位置:./package.json,运行以下代码:

{
  "name": "create-helloworld-contract-using-hardhat",
  "scripts": {
    "compile": "./node_modules/.bin/hardhat compile",
    "test": "./node_modules/.bin/hardhat test"
  },
  "devDependencies": {
    "@nomicfoundation/hardhat-toolbox-viem": "^1.0.0",
    "dotenv": "^16.3.1",
    "hardhat": "^2.18.3"
  }
}

为Berachain合约部署配置Hardhat

通过Hardhat创建viem模板的方式部署的合约,目前尚未完全支持开箱即用的自定义链,但在 Berachain主网启动后将会支持。

首先,为了正确设置hardhat.config.ts,需要使用dotenv安装包创建一个.env文件,用于声明环境变量,供配置读取。

# FROM ./create-helloworld-contract-using-hardhat;

touch .env;

然后,在新建的.env文件中,运行以下代码,文件位置:./.env。

# Chain Configurations
CHAIN_ID=80084
NETWORK_NAME="berachainbArtio"
CURRENCY_DECIMALS=18
CURRENCY_NAME="BERA Token"
CURRENCY_SYMBOL="BERA"

# API key for Beratrail Block Explorer, can be any value for now
BLOCK_EXPLORER_NAME=Beratrail Block Explorer
BLOCK_EXPLORER_API_KEY=xxxxx
BLOCK_EXPLORER_API_URL=https://api.routescan.io/v2/network/testnet/evm/80084/etherscan/api/
BLOCK_EXPLORER_URL=https://bartio.beratrail.io/

# Wallet + RPC configurations
RPC_URL=https://bartio.rpc.berachain.com/
# Private key generated from Hardhat local - replace with Berachain
# NEVER SHARE THIS WITH ANYONE AND AVOID COMMITTING THIS WITH YOUR GIT REPOSITORY
WALLET_PRIVATE_KEY=0xYOUR_WALLET_PRIVATE_KEY

代币合约参数支持自定义,总体配置步骤是相同的。

设置好环境变量后,需要将它们加载到hardhat.config.ts文件。

文件位置:./hardhat.config.ts,运行以下代码:

// Imports
// ========================================================
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox-viem";
import dotenv from "dotenv";

// Load Environment Variables
// ========================================================
dotenv.config();

// Main Hardhat Config
// ========================================================
const config: HardhatUserConfig = {
  solidity: "0.8.19",
  networks: {
    // For localhost network
    hardhat: {
      chainId: 1337,
    },
    // NOTE: hardhat viem currently doesn't yet support this method for custom chains through Hardhat config ↴
    berachainTestnet: {
      chainId: parseInt(`${process.env.CHAIN_ID}`),
      url: `${process.env.RPC_URL || ""}`,
      accounts: process.env.WALLET_PRIVATE_KEY
        ? [`${process.env.WALLET_PRIVATE_KEY}`]
        : [],
    },
  },
};

// Exports
// ========================================================
export default config;

在Berachain部署HelloWorld合约

我们已经完成了所有配置设置,现在尝试运行一个本地节点,并将其部署到本地环境。

首先,通过对package.json文件进行一些修改,让部署运行更轻松。

文件位置: ./package.json,运行以下代码:

{
  "name": "create-helloworld-contract-using-hardhat",
  "scripts": {
    "compile": "./node_modules/.bin/hardhat compile",
    "node": "./node_modules/.bin/hardhat node", 
    "deploy:localhost": "./node_modules/.bin/hardhat run scripts/deploy.ts --network localhost", 
    "deploy:berachain": "./node_modules/.bin/hardhat run scripts/deploy.ts --network berachainTestnet", 
    "test": "./node_modules/.bin/hardhat test"
  },
  "devDependencies": {
    "@nomicfoundation/hardhat-toolbox-viem": "^1.0.0",
    "dotenv": "^16.3.1",
    "hardhat": "^2.18.3"
  }
}

接下来,配置./scripts/deploy.ts脚本,以确保合约正确部署。

文件位置: ./scripts/deploy.ts,运行以下代码:

// Imports
// ========================================================
import hre from "hardhat";

// Main Deployment Script
// ========================================================
async function main() {
  const contract = await hre.viem.deployContract("HelloWorld", [
    "Hello from the contract!",
  ]);
  console.log(`HelloWorld deployed to ${contract.address}`);
}

// Init
// ========================================================
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

部署脚本配置好后,我们可以在一个终端运行本地节点,并在另一个终端部署合约。

终端 1:部署合约

# FROM ./create-helloworld-contract-using-hardhat;

pnpm node;

# [Expected Output]:
# Started HTTP and WebSocket JSON-RPC server at http://127.0.0.1:8545/
#
# Accounts
# ========
#
# WARNING: These accounts, and their private keys, are publicly known.
# Any funds sent to them on Mainnet or any other live network WILL BE LOST.
#
# Account #0: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 (10000 ETH)
# Private Key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80bash

使用上方代码中提供的私钥Private Key,替换.env 文件中的WALLET_PRIVATE_KEY。

文件位置:./.env,运行以下代码:

WALLET_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80

终端 2:运行本地节点

# FROM ./create-helloworld-contract-using-hardhat;

pnpm deploy:localhost;
# [Expected Similar Output]:
# HelloWorld deployed to 0x5fbdb2315678afecb367f032d93f642f64180aa3

现在,合约已成功部署到本地节点,接下来配置部署脚本,以便合约直接部署到Berachain网络。

要使viem支持自定义链,需要进行额外配置,下方代码展示了如何为Berachain设置额外配置。当Berachain主网上线时,这些额外配置可能不再需要。

文件位置:./scripts/deploy.ts,运行以下代码:

// Imports
// ========================================================
import hre from "hardhat";
import fs from "fs"; 
import { defineChain } from "viem"; 
import { privateKeyToAccount } from "viem/accounts"; 

// Config Needed For Custom Chain
// ========================================================
const chainConfiguration = defineChain({

  id: parseInt(`${process.env.CHAIN_ID}`), 
  name: `${process.env.NETWORK_NAME}`, 
  network: `${process.env.NETWORK_NAME}`, 
  nativeCurrency: {

    decimals: parseInt(`${process.env.CURRENCY_DECIMALS}`), 
    name: `${process.env.CURRENCY_NAME}`, 
    symbol: `${process.env.CURRENCY_SYMBOL}`, 
  }, 
  rpcUrls: {

    default: {

      http: [`${process.env.RPC_URL}`], 
    }, 
    public: {

      http: [`${process.env.RPC_URL}`], 
    }, 
  }, 
  blockExplorers: {

    default: {
      name: `${process.env.BLOCK_EXPLORER_NAME}`,
      url: `${process.env.BLOCK_EXPLORER_URL}`,
    }, 
  }, 
}); 

// Main Deployment Script
// ========================================================
async function main() {
  // NOTE: hardhat with viem currently doesn't support custom chains so there needs to be some custom functionality ↴
  if (hre.network.name === "berachainTestnet") {

    // Retrieve contract artifact ABI & Bytecode
    const contractName = "HelloWorld"; 
    const artifactFile = fs.readFileSync(
      `${hre.artifacts._artifactsPath}/contracts/${contractName}.sol/${contractName}.json`
    ); 
    const artifactJSON = JSON.parse(artifactFile.toString()) as any; 

    // Configure wallet client
    const walletClient = await hre.viem.getWalletClient(

      // wallet account
      privateKeyToAccount(hre.network.config.accounts?.[0] as `0x${string}`), 
      // configured chain
      {

        chain: chainConfiguration, 
      } 
    ); 

    // Deploy contract
    const hash = await walletClient.deployContract({

      abi: artifactJSON.abi, 
      bytecode: artifactJSON.bytecode, 
      args: ["Hello From Deployed Contract"], 
    }); 
    console.log({ hash }); 

    // Retrieve deployed contract address
    const publicClient = await hre.viem.getPublicClient({

      chain: chainConfiguration, 
    }); 
    const receipt = await publicClient.waitForTransactionReceipt({ hash }); 
    console.log(`${contractName} deployed to ${receipt?.contractAddress}`); 
  } else {

    const contract = await hre.viem.deployContract("HelloWorld", [
      "Hello from the contract!",
    ]);
    console.log(`HelloWorld deployed to ${contract.address}`);
  } 
}

// Init
// ========================================================
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

文件位置:./.env,运行以下代码:

WALLET_PRIVATE_KEY=0xYOUR_WALLET_PRIVATE_KEY

现在,可以直接将合约部署到Berachain了。

# FROM ./create-helloworld-contract-using-hardhat;

pnpm deploy:berachain;

# [Expected Similar Output]:
# {
#   hash: '0x3ff0120c126b20d9f286657521c9d2d1edbb38f60dcd5fc6b95638a192588182'
# }
# HelloWorld deployed to 0x38f8423cc4390938c01616d7a9f761972e7f116a

你可以运行下方代码,在Berachain Beratrail区块浏览器中查看部署的合约:

open https://bartio.beratrail.io/address/0x38f8423cc4390938c01616d7a9f761972e7f116a

# [Expected Result Should Open Your Browser]

你会看到合约已经成功部署,但未被验证,因为它仍显示合约字节码,接下来需要验证合约。

验证HelloWorld合约

为了验证合约,需要在hardhat.config.ts文件中添加一个额外配置。

文件位置:./hardhat.config.ts,运行以下代码:

// Imports
// ========================================================
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox-viem";
import dotenv from "dotenv";

// Load Environment Variables
// ========================================================
dotenv.config();

// Main Hardhat Config
// ========================================================
const config: HardhatUserConfig = {
  solidity: "0.8.19",
  networks: {
    hardhat: {
      chainId: 1337,
    },
    // NOTE: hardhat viem currently doesn't yet support this method for custom chains through Hardhat config ↴
    berachainTestnet: {
      chainId: parseInt(`${process.env.CHAIN_ID}`),
      url: `${process.env.RPC_URL || ""}`,
      accounts: process.env.WALLET_PRIVATE_KEY
        ? [`${process.env.WALLET_PRIVATE_KEY}`]
        : [],
    },
  }, 
  // For Contract Verification
  etherscan: {

    apiKey: `${process.env.BLOCK_EXPLORER_API_KEY}`, 
    customChains: [

      {

        network: "Berachain Testnet", 
        chainId: parseInt(`${process.env.CHAIN_ID}`), 
        urls: {

          apiURL: `${process.env.BLOCK_EXPLORER_API_URL}`, 
          browserURL: `${process.env.BLOCK_EXPLORER_URL}`, 
        }, 
      }, 
    ], 
  }, 
};

// Exports
// ========================================================
export default config;

完成额外配置后,通过向package.json添加 run 命令来查看更改。

文件位置:./package.json,运行以下代码:

{
  "name": "create-helloworld-contract-using-hardhat",
  "scripts": {
    "compile": "./node_modules/.bin/hardhat compile",
    "node": "./node_modules/.bin/hardhat node",
    "deploy:localhost": "./node_modules/.bin/hardhat run scripts/deploy.ts --network localhost",
    "deploy:berachain": "./node_modules/.bin/hardhat run scripts/deploy.ts --network berachainTestnet",
    "test": "./node_modules/.bin/hardhat test",
    "verify": "./node_modules/.bin/hardhat verify --network berachainTestnet"
  },
  "devDependencies": {
    "@nomicfoundation/hardhat-toolbox-viem": "^1.0.0",
    "dotenv": "^16.3.1",
    "hardhat": "^2.18.3"
  }
}

最后,使用合约部署地址和初始参数Hello From Deployed Contract,运行下方代码验证合约。

# FROM ./create-helloworld-contract-using-hardhat;

# Equivalent to: npx hardhat verify 0x38f8423cc4390938c01616d7a9f761972e7f116a "Hello From Deployed Contract"
pnpm verify 0x38f8423cc4390938c01616d7a9f761972e7f116a "Hello From Deployed Contract";

# [Expected Output]:
#
# Successfully submitted source code for contract
# contracts/HelloWorld.sol:HelloWorld at 0x38f8423cc4390938c01616d7a9f761972e7f116a
# for verification on the block explorer. Waiting for verification result...
#
# Successfully verified contract HelloWorld on the block explorer.
# https://bartio.beratrail.io/address/0x38f8423cc4390938c01616d7a9f761972e7f116a#code

在Beratail可以看到,合约已成功验证,并且可以查看到合约Solidity代码。

完整代码库

接下来,将WALLET_PRIVATE_KEY替换为一个拥有$BERA代币的钱包,可以从获取测试网$BERA代币。

本节完整代码库,可在 - 中查看。

hardhat-viem-helloworld
Hardhat
Berachain测试网水龙头
Berachain测试网水龙头
Github - Berachain Guides
hardhat-viem-helloworld
guides/apps/hardhat-viem-helloworld at main · berachain/guidesGitHub
Logo