paint-brush
如何使用 Foundry 和 Figment DataHub 构建 NFT 项目by@pnpancholi
1,964
1,964

如何使用 Foundry 和 Figment DataHub 构建 NFT 项目

Twitter 可以说是地球上最强大的社交媒体网络,尽管它在用户方面没有进入全球前十名。该网站的高级搜索功能允许用户搜索每一个可以想到的术语,因此即使您只能记住要查找的推文中的几个词,Twitter 也会帮助您找到它。有很多方法可以在 Twitter 应用程序内外使用列表,或者您可以使用这样的浏览器扩展 [](https://www.google.com/webstore/detail/twitter-bookmarks-search/flkokionhgagpmnhlngldhbfnblmenen)

Companies Mentioned

Mention Thumbnail
Mention Thumbnail

Coins Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - 如何使用 Foundry 和 Figment DataHub 构建 NFT 项目
Pradhumna Pancholi HackerNoon profile picture


GitHub 回购:- https://github.com/PradhumnaPancholi/Figbot


嘿大家!不久前,我正在学习Dapp 工具,因为它具有用于开发和审计智能合约的出色工具。虽然我喜欢这种体验,但我很快就知道它正处于秘密发展阶段。这意味着临时/个人用户不能依赖维护者的支持和更新。


然后我偶然发现了Foundry 。它拥有 Dapp Tools 提供的一切,除了内置的符号执行(这对我来说不是问题,因为我使用Manticor e by Trail of Bits )。这是与审计相关的,因此无论如何都不会成为智能合约开发的障碍。


在与 Foundry 合作了一段时间后,我很享受这段经历,并想与他人分享。因此,这篇文章。


本文将介绍 Foundry 的好处、安装过程、开发 NFT(因为每个人都对此感兴趣)、测试合约以及使用Figment Datahub部署它。




Foundry 是用 Rust 编写的用于以太坊应用程序开发的极快、可移植和模块化的工具包。


Foundry由三个部分组成:


  1. Forge:以太坊测试框架(如 Truffle、Hardhat 和 Dapptools)。
  2. Cast:用于与 EVM 智能合约交互、发送交易和获取链数据的瑞士军刀。
  3. Anvil:本地以太坊节点,类似于 Ganache,Hardhat Network


今天的重点将放在Forge 上。但我将在接下来的几周内发布有关 Caste and Anvil 的深入文章。


为什么选择铸造:

有许多智能合约开发工具,例如 Truffle、Hardhat 和 Brownie。但我首先研究 Dapp Tools 的主要原因之一是原生 Solidity 测试。在 Hardhat 和 Brownie 等框架之间切换时,编写智能合约并不难。它们是带有插件的令人难以置信的工具,但需要精通 JavaScript/TypeScript 和 Python 才能执行测试。


Foundry 允许我们在 Solidity 中本地编写测试。这可以节省大量新开发人员的入职时间,并使流程更加顺畅。根据我帮助人们进入智能合约开发的经验,我了解到初级开发人员参与 DAO/社区维护项目的最佳和最有效的方式是编写测试和了解代码库本身。我记得Scupy Trooples曾经提到他们在Bankless上开发 Alchemix Finance 时使用了相同的方法。


除此之外,内置的模糊测试、作弊码、Cast 和 Anvil 使其成为测试智能合约的可靠套件。很快就会有关于这些组件的更详细的文章。 【易集成静态分析仪】


让我们现在开始构建一个 NFT 项目。


安装:

如果你在 Mac 或 Linux 上,你需要做的就是运行两个命令:

 curl -L https://foundry.paradigm.xyz | bash

foundryup


确保在运行foundryup之前关闭终端。

瞧!你们都完成了。


对于 Windows,您需要安装 Rust,然后:

cargo install --git https://github.com/foundry-rs/foundry --locked


项目设置:

在本文中,我们将创建一个名为 Figbots 的简单 NFT 项目。


首先创建一个名为“Figbots”的目录。进入目录后运行forge init 。此命令将为您创建一个初始化git的铸造项目。


让我们快速看一下文件夹结构。您有三个主要文件夹,即 src、lib 和 test。这里非常不言自明,您在src中编写合约,在 test 中编写test ,并且lib包含您安装的所有库,例如 OpenZeppelin。除此之外,如果您使用过这些框架,您还会获得包含所有配置的foundry.toml ,就像hardhat.config.jsbrownie-config.yaml一样。另一个好东西是 .github,您可以在其中编写您的 Github Actions。我发现在团队中工作时它对测试非常有帮助。


让我们开始建造吧!我们将创建一个名为 Figbot 的简单 NFT,其供应量、成本(用于铸币)和提款都是有限的。通过这种方法,我们可以覆盖不同测试的边缘。首先,将Contract.soltest/Contract.t.sol分别重命名为Figbot.solFigbot.t.sol 。现在,如果没有 Openzeppelin,我们就无法编写智能合约,不是吗?


使用 Foundry 安装库与 Hardhat 和 Brownie 略有不同。我们没有 npm 或 pip 包。我们直接从 Foundry 的源代码(GitHub 存储库)安装库。

forge install Openzeppelin/openzeppelin-contracts


现在我们可以导入 ERC721URIStorage.sol 扩展来创建我们的 NFT。为了检查一切是否正常,我们可以运行命令forge build ,它将编译我们的项目。如果有什么问题,编译器就会对你大喊大叫。否则,您将获得成功的编译。


管理依赖项

就像任何其他包管理器一样,Forge 允许您使用forge install <lib>, forge remove <lib>forge update <lib>来管理您的依赖项。


让我们完成 NFT 合约:

我们将使用 Openzeppelin 的三个合约。计数器、ERC721URIStorage 和 Ownable。是时候使用Pinata将我们的资产上传到 IPFS 了。我们使用 Ownable 合约来设置部署地址的owner ,并且可以访问onlyOwner修饰符以只允许所有者提取资金。 Counters帮助我们处理代币 ID 和ERC721URIStorage ,以保持 NFT 合约的简单性。


  1. 设置状态变量:

    1. MAX_SUPPLY至 100
    2. COST为 0.69 以太币
    3. TOKEN_URI到 CID,我们从 Pinata 收到
  2. 使用 Counter 获取令牌 ID:

    1. using Counters for Counters.Counter;
    2. Counters.Counter private tokenIds;
  3. ERC721 构造函数:

    1. constructor() ERC721(“Figbot”, “FBT”) {}
  4. 薄荷功能:

    1. 检查msg.value是否大于COST
    2. 检查tokenIds.current()是否大于或等于MAX_SUPPLY
    3. 执行_safeMint_setTokenURI
  5. 提现功能:

    1. function withdrawFunds() external onlyOwner { uint256 balance = address(this).balance; require(balance > 0, "No ether left to withdraw"); (bool success, ) = (msg.sender).call{value: balance}(""); require(success, "Withdrawal Failed"); emit Withdraw(msg.sender, balance); }
  6. TotalSupply 函数:

    1. function totalSupply() public view returns (uint256) { return _tokenIds.current(); }


测试合约:

众所周知,测试我们的智能合约非常重要。在本节中,我们将编写一些测试来深入了解forge test并习惯于在原生 Solidity 中编写测试。我们将使用三个Foundry 作弊码(我喜欢它们!)来管理帐户状态以适应我们的测试场景。


我们将针对以下场景进行测试:

  1. 最大供应
  2. 成功的薄荷
  3. 由于余额不足导致铸币失败
  4. 取款(由所有者)


秘籍

因为我们的智能合约中可以有复杂的逻辑。并且它们的行为会根据状态、用于调用的帐户、时间等而有所不同。为了应对这种情况,我们可以使用作弊码来管理区块链的状态。我们可以使用vm实例来使用这些作弊码,它是 Foundry 的Test库的一部分。


我们将在测试中使用三个作弊码:

  1. startPrank :为所有后续调用设置msg.sender ,直到调用stopPrank

  2. stopPrank

    停止由startPrank启动的活动恶作剧,将msg.sendertx.origin重置为调用startPrank之前的值。

  3. deal :将地址提供地址的余额设置为给定余额。

设置

Foundry 带有一个内置的测试库。我们首先导入这个测试库、我们的合约(我们要测试的那个)、定义测试、设置变量和setUp函数。


 pragma solidity ^0.8.13; import"forge-std/Test.sol"; import "../src/Figbot.sol"; contract FigbotTest is Test { Figbot figbot; address owner = address(0x1223); address alice = address(0x1889); address bob = address(0x1778); function setUp() public { vm.startPrank(owner); figbot = new Figbot(); vm.stopPrank(); } }


对于状态变量,我们创建了一个figbot类型的变量Figbot 。这也是我喜欢定义用户帐户的地方。在 Foundry 中,您可以使用语法address(0x1243)来描述地址。您可以为此使用任意四个字母数字字符。我分别创建了名为 owner、Alice 和 bob 的帐户。


现在我们的setUp函数。这是在 Foundry 中编写测试的要求。这是我们进行所有部署和这种性质的事情的地方。我使用作弊码startPrank将用户切换为“所有者”。默认情况下,Foundry 使用特定地址来部署测试合约。但这使得测试具有诸如withdrawFunds等特权的函数变得更加困难。因此,我们切换到此部署的“所有者”帐户。


测试 MaxSupply:

从一个简单的断言测试开始学习 Foundry 约定。按照惯例,所有的测试函数都必须有前缀test 。我们使用assertEq来测试两个值是否相等。

我们调用MaxSupply函数并测试结果值是否为 100,正如我们在合同中描述的那样。我们使用forge test来运行我们的测试。


瞧!我们通过了测试。

测试薄荷:

现在我们已经编写了一个简单的测试,让我们用作弊码编写一个。我们合约的主要功能。

  1. 将用户帐户切换到 Alice。
  2. 将 Alice 的余额设置为 1 个以太币
  3. 调用 mint 函数
  4. 检查balanceOf Alice 是否为 1

测试失败薄荷:

我们有另一个测试函数用于我们预计会失败的测试。用于此类测试的前缀是testFail 。如果调用者资金不足,我们将测试mint函数是否恢复。

  1. 将用户帐户切换到 Bob
  2. 将 Bob 的余额设置为 0.5 ether(我们的 NFT 是 0.69 ether)
  3. 调用 mint 函数(由于资金不足将被还原)
  4. 检查balanceOf Bob 是否为 1

因为 mint 没有通过,Bob 的余额不会是 1。因此,它会失败,这正是我们使用testFail的原因。因此,当您运行forge test时,它将通过。

测试退出:

在这里,我们将测试一个只有“所有者”才能成功执行的功能。对于这个测试,我们将:

  1. 将用户切换到 Bob
  2. 给 Bob 的账户 1 个以太币的余额
  3. 从 Bob 的账户中铸造一个 Figbot(这将使合约的余额为 0.69 以太币)
  4. 将用户切换到所有者帐户
  5. 执行withdrawFunds功能(如果成功,它应该使所有者的余额0.69 ether)
  6. 为了验证,我们断言所有者的余额是否为 0.69 ether

部署:

现在我们已经测试了我们的合约,是时候部署它了。我们需要一个钱包的私钥(带有一些 Rinkeby 测试 ETH)和一个 RPC URL。对于我们的 RPC URL,我们将使用Figment DataHu



Figment DataHub 为我们提供了在 Web 3 上开发的基础设施。它支持多个链,如 Ethereum、Celo、Solana、Terra 等。


设置 Figment DataHub:

  1. Figment DataHub上创建一个帐户。
  2. 点击“创建新应用”。
  3. 填写应用名称。
  4. 为环境选择“暂存”。
  5. 从提供的选项中选择“以太坊”。


您可以从“协议”选项卡下获取 Rinkeby 的 RPC URL。

打开您的终端以将这两个内容作为环境变量输入。


 export FIG_RINKEBY_URL=<Your RPC endpoint> export PVT_KEY=<Your wallets private key>


一旦我们有了环境变量,我们就可以部署了


forge create Figbot --rpc-url=$FIG_RINKEBY_URL --private-key=$PVT_KEY


确认:

我们差不多完成了。到目前为止,我们已经使用 Foundry 和 Figment DataHub 编写、测试和部署了智能合约。但我们还没有完全完成。我们现在要验证我们的合同。我们需要为此设置我们的Etherscan API 密钥。

export ETHERSCAN_API=<Your Etherscan API Key>


现在我们可以验证我们的智能合约了。

forge verify-contract --chain-id <Chain-Id> --num-of-optimizations 200 --compiler-version <Compiler Version> src/<Contract File>:<Contract> $ETHERSCAN_API

恭喜!现在,您可以使用 Foundry 编写、测试和部署智能合约。我希望你喜欢这篇文章并从中学习。我确实很喜欢写这个。随时让我知道您对此的想法。