如何在 Arbitrum Nova 上部署智能合约

本文介绍了Arbitrum Nova,一个通过AnyTrust协议提供低交易成本和高安全性的区块链。文章详细讲解了Arbitrum Nova的工作原理,包括AnyTrust协议和数据可用性委员会(DAC),并指导开发者如何使用QuickNode和Hardhat等工具在Arbitrum Nova上构建、部署和交互简单的存储智能合约。

概述

本指南介绍了 Arbitrum Nova,这是一个通过 AnyTrust 协议提供低交易成本和高安全性的区块链。用户将学习如何使用 QuickNode 和 Hardhat 等知名开发工具在 Arbitrum Nova 上构建、部署和交互一个简单的存储智能合约。

你需要的

你将做什么

  • 了解 Arbitrum Nova 链
  • 构建一个简单的存储智能合约
  • 在 Arbitrum Nova 上部署存储合约
  • 与你部署的存储合约交互

什么是 Arbitrum Nova?

Arbitrum Nova 是 Arbitrum 提供的区块链,它提供超低的交易成本和高安全性。该链采用了一种称为 AnyTrust 的技术,它是 Arbitrum Nitro 技术的一种变体,它接受轻微的信任假设,以换取最终用户的低费用。

让我们简要地介绍一下 AnyTrust 的工作原理。

AnyTrust 协议

AnyTrust 构建在 Arbitrum Nitro 技术之上,是对“经典”Arbitrum 的升级。AnyTrust 通过实施一种称为数据可用性委员会(Data Availability Committee,又名 DAC)的协议,显著降低了最终用户的费用。

现在让我们来介绍一下这些信任假设是如何运作的,以及数据可用性委员会 (DAC) 如何参与其中。

数据可用性委员会(DAC)

数据可用性委员会的目标是确保最终用户的数据可用性。业内一些最好的公司齐聚一堂,组成了 Nova 的数据可用性委员会(如 Google Cloud、QuickNode 和 Reddit)。DAC 成员必须运行数据可用性服务器(Data Availability Server,DAS)软件,该软件包括一个 Sequencer API,用于将数据块提交到 DAS 进行存储,以及一个 REST API,用于查询块数据。

信任假设是委员会由 N 名成员组成,AnyTrust 假设其中至少有两名是诚实的。这意味着,如果 N-1 名委员会成员承诺提供对某些数据的访问权限,那么至少有一名承诺方必须是诚实的,以确保数据可用且协议可以继续运行。

假设委员会成员无法为 AnyTrust 的运行提供所需的数据。在这种情况下,委员会失去共识,Nova 链将使用 Arbitrum Rollup 协议作为后备方案(即,将交易数据存储在以太坊链上),直到 DAC 委员会重新获得共识。

为什么选择 Arbitrum Nova?

通过利用 AnyTrust 技术和 Nitro 的共享代码库,Nova 提供了卓越的速度、安全性和以太坊互操作性。Nova 上的交易费用比以太坊便宜高达 90%,且挖矿速度更快,同时使用相同的安全性。

对于交易量大的用户或项目,例如游戏开发者、社交项目和区块链应用(如 NFT 和 DeFi),Nova 可能是有利的。

现在我们已经更好地了解了为什么有人会使用 Arbitrum Nova,让我们继续本指南的技术部分,该部分将演示如何使用 QuickNodeHardhat 等知名开发者工具在 Arbitrum Nova 上部署智能合约。

开发者设置

使用 QuickNode 访问 Arbitrum Nova

你需要一个 API 端点来与 Arbitrum Nova 链通信。你可以随意使用公共节点或部署和管理你自己的基础设施;但是,如果你想要快 8 倍的响应时间,你可以把繁重的工作留给我们。在此处注册一个帐户:here

登录后,单击 Create Endpoint,然后选择 Arbitrum Nova mainnet 链。

QuickNode 节点

创建端点后,请妥善保管 HTTP Provider URL,因为你将在部署部分需要它。

Torus 钱包

你可以使用许多加密钱包来部署智能合约。在本指南中,我们将使用 Torus Wallet,它是一个非托管钱包,具有多链和网络可用性(例如,以太坊、Arbitrum One、Arbitrum Nova 和其他 EVM 相关链)。

请注意,由于本指南涵盖了在 Arbitrum Nova Mainnet 上的部署,因此你需要真实的资金(即 ETH)来支付交易费用。但是,这应该非常便宜,并且不应超过 0.25 美元。ETH 可以在去中心化交易所(如 Uniswap)或托管交易所(如 Coinbase)上获得。

导航到 Torus 并完成工作流程以生成私钥。

Torus钱包

在开始本指南的技术部分之前,请确保你的 Arbitrum Nova 主网地址上有足够的资金来支付合约部署和交互费用。

Hardhat

Hardhat 是一个流行的与 EVM 相关的区块链开发框架。它由不同的组件组成,从编译、调试、测试和部署智能合约。你可以使用 SolidityYulAssembly 在 Hardhat 上部署智能合约。你可以在 此处 找到关于 Hardhat 的更多信息。

在下一节中,我们将开始使用 Hardhat 开发我们的智能合约。

设置项目

要设置项目,我们必须创建一个名为 StorageContract 的文件夹并安装所需的依赖项。

为此,请运行以下终端命令集:

mkdir StorageContract && cd StorageContract
npm init -y
npm install --save-dev hardhat
npm i dotenv
npm i @nomicfoundation/hardhat-toolbox
npx hardhat

当 Hardhat 提示你想要创建的项目类型时,选择 Create an empty hardhat.config.js 选项。

创建 Hardhat 项目后,我们将运行以下终端命令集,为我们的智能合约创建一个有组织的开发环境。

mkdir contracts
mkdir test
mkdir scripts
echo > .env

然后,我们将配置 hardhat.config.js 文件,使其具有以下代码:

require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();

module.exports = {
  solidity: "0.8.17",
  networks: {
    nova: {
      url: process.env.RPC_URL,
      accounts: [process.env.PRIVATE_KEY]
    }
  }
};

最后,打开 .env 文件并粘贴以下环境变量。

PRIVATE_KEY=<FILLME>
RPC_URL=<FILLME>

用你的私钥和你在上一节中创建的 RPC URL 填充这些值。请记住保存你到目前为止编辑的文件。

在 Arbitrum Nova 上构建智能合约

是时候开始构建了!如果你还没有任何 Solidity 经验,请花点时间查看 如何使用 Solidity 创建“Hello World”智能合约 指南中的 Solidity 101 部分。

准备好后,在你的 contracts 文件夹中创建一个名为 SimpleStorage.sol 的文件:

echo > contracts/SimpleStorage.sol

打开该文件并输入以下代码:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract SimpleStorage {
    address public owner;  // Public variable to store the address of the owner of the contract
    uint public value;     // Public variable to store the value

    event NewValueSet(uint value);    // Event emitted when the value is set
    event OwnerChanged(address newOwner); // Event emitted when the owner is changed

    constructor() {
        owner = msg.sender;  // Initialize the owner as the address that deployed the contract
    }

    // Modifier to check if the msg.sender is the owner before execution
    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can perform this action.");
        _;
    }

    /**
     * @dev Function to read the current value stored in the contract
     * @return uint - the value stored in the contract
     */
    function readValue() public view returns (uint) {
        return value;
    }

    /**
     * @dev Function to set a new value in the contract
     * @param _value - the new value to be set
     */
    function setValue(uint _value) public onlyOwner {
        value = _value;
        emit NewValueSet(value);
    }

    /**
     * @dev Function to read the current owner stored in the contract
     * @return address - the value stored in the contract
     */
    function getOwner() public view returns (address) {
        return owner;
    }

    /**
     * @dev Function to change the owner of the contract
     * @param _newOwner - the new owner of the contract
     */
    function changeOwner(address _newOwner) public onlyOwner {
        require(_newOwner != address(0), "The new owner address cannot be 0x0");
        owner = _newOwner;
        emit OwnerChanged(owner);
    }
}

在继续下一节之前,花几分钟时间阅读代码注释,以更好地理解存储合约的逻辑。该代码使用了 solidity 概念,例如事件、require 语句、修饰符和其他 solidity 最佳实践。

在部署之前测试智能合约

在我们部署这个基本的存储合约之前,我们希望确保合约的行为符合预期。我们可以通过运行一些测试来做到这一点。在你的 test 文件夹中,使用以下命令创建一个名为 storageTest.js 的文件:

echo > test/storageTest.js

然后,在你的代码编辑器中打开该文件并输入以下代码:

const { expect } = require("chai");

describe("Storage Contract Test", function () {
    let owner;

    beforeEach(async function () {
        // Retrieve the default account from ethers
        [owner] = await ethers.getSigners();

        // A helper to get the contracts instance and deploy it locally
        const SimpleStorage = await ethers.getContractFactory("SimpleStorage");
        simpleStorage = await SimpleStorage.deploy();
    });

    it("should set and get value correctly", async () => {
        // Set a new value
        const newValue = 12345;
        await simpleStorage.setValue(newValue);

        // Read the value and expect it to be 12345
        const value = await simpleStorage.readValue();
        expect(value).to.equal(newValue);
    });

    it('should return the address of the contract owner', async () => {
        // Get the owner address stored in the contract
        const contractOwner = await simpleStorage.getOwner();

        // Expect the contract owner to be the address that deployed the contract
        expect(contractOwner).to.equal(owner.address);
    });

    it("should change the owner correctly", async () => {
        // Change ownership to a new address
        await simpleStorage.changeOwner("0x95222290DD7278Aa3Ddd389Cc1E1d165CC4BAfe5");
        const updatedOwner = await simpleStorage.getOwner();

        // Expect the contract owner to be the new address
        expect(updatedOwner).to.equal("0x95222290DD7278Aa3Ddd389Cc1E1d165CC4BAfe5");
    });

});

花几分钟时间阅读代码注释并理解代码

要运行测试,请导航到你的主目录(例如,StorageContract)并运行以下终端命令:

npx hardhat test

你应该看到类似于以下的输出:

Hardhat 测试

在 Arbitrum Nova 上部署智能合约

本节将在 Arbitrum Nova 主网上部署智能合约。

在你的 scripts 文件夹中,创建一个名为 deploy.js 的文件:

echo > scripts/deploy.js

此文件将包含将我们的合约部署到 Arbitrum Nova 主网所需的逻辑。打开该文件并输入以下代码:

const hre = require("hardhat");

async function deploy() {
    // Deploy the contract
    const SimpleStorage = await hre.ethers.getContractFactory("SimpleStorage");
    const simpleStorage = await SimpleStorage.deploy();

    // Print the deployed contracts address
    console.log("SimpleStorage contract deployed at:", simpleStorage.address);
}

deploy()
    .then(() => console.log("Deployment complete"))
    .catch((error) => console.error("Error deploying contract:", error));

要部署合约,请在你的终端中运行以下 hardhat 命令:

npx hardhat run --network nova scripts/deploy.js

你应该会看到一个包含你已部署的合约地址的输出。

在 Arbitrum Nova 上与智能合约交互

导航到 Arbitrum Nova 的 区块浏览器,通过输入上面部署脚本返回的地址来验证是否已部署智能合约。

要与存储合约交互,请在你的 scripts 目录中创建一个名为 interactStorage.js 的附加脚本:

echo > scripts/interactStorage.js

然后打开该文件并输入以下代码:

const hre = require("hardhat");

async function main() {
    // Get contract factory for the SimpleStorage contract
    const SimpleStorage = await ethers.getContractFactory("SimpleStorage");

    // Attach to deployed contract at the specified address
    const simpleStorage = await SimpleStorage.attach(
      "DEPLOYED_CONTRACT_ADDRESS" // Your deployed contract address
    );

    // Call the readValue function to get the current value
    let getValue = await simpleStorage.readValue();
    console.log("currentValue: ", getValue)

    // Call the setValue function to update the value
    let setValueTx = await simpleStorage.setValue(420)
    console.log("setValue function call. Waiting for confirmation...")

    // Wait 3 blocks for the transaction to be confirmed
    await setValueTx.wait(confirm=3);

    // Call the readValue function again to get the latest value
    let latestValue = await simpleStorage.readValue();
    console.log("latestValue: ", latestValue)
}

// Start the script and handle any errors
main()
    .then(() => console.log("Script complete"))
    .catch((error) => console.error("Error running script:", error));

上面的脚本将通过调用 setValue 函数来测试在我们的存储合约中设置一个值。它还将调用 readValue 函数来获取存储中的当前值。要运行该脚本,请使用以下 hardhat 命令:

npx hardhat run --network nova scripts/interactStorage.js

就这样!你已经使用 Hardhat 和 QuickNode 在 Arbitrum Nova 上创建了一个智能合约!

Arbitrum 生态系统

既然你已经在 Arbitrum Nova 上部署了你的第一个智能合约,请探索 Arbitrum Nova 链提供的一些资源:

额外资源

如果你想继续学习关于 Arbitrum Nova 和智能合约的知识,请查看这些资源:

最后的想法

恭喜!你现在更了解 Arbitrum Nova 以及如何部署智能合约!你使用 Arbitrum Nova 做什么?我们很想看看你在创造什么!在 DiscordTwitter 上与我们分享你的应用程序。如果你对本指南有任何反馈或问题,我们很乐意听取你的意见!

  • 原文链接: quicknode.com/guides/arb...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
QuickNode
QuickNode
江湖只有他的大名,没有他的介绍。