GitHub 回购:- https://github.com/PradhumnaPancholi/Figbot 嘿大家!不久前,我正在学习 ,因为它具有用于开发和审计智能合约的出色工具。虽然我喜欢这种体验,但我很快就知道它正处于秘密发展阶段。这意味着临时/个人用户不能依赖维护者的支持和更新。 Dapp 工具 然后我偶然发现了 。它拥有 Dapp Tools 提供的一切,除了内置的符号执行(这对我来说不是问题,因为我使用 e by Trail of Bits )。这是与审计相关的,因此无论如何都不会成为智能合约开发的障碍。 Foundry Manticor 在与 Foundry 合作了一段时间后,我很享受这段经历,并想与他人分享。因此,这篇文章。 本文将介绍 Foundry 的好处、安装过程、开发 NFT(因为每个人都对此感兴趣)、测试合约以及使用 部署它。 Figment Datahub Foundry 是用 Rust 编写的用于以太坊应用程序开发的极快、可移植和模块化的工具包。 Foundry由三个部分组成: 以太坊测试框架(如 Truffle、Hardhat 和 Dapptools)。 Forge: 用于与 EVM 智能合约交互、发送交易和获取链数据的瑞士军刀。 Cast: 本地以太坊节点,类似于 Ganache,Hardhat Network Anvil: 今天的重点将放在 但我将在接下来的几周内发布有关 Caste and Anvil 的深入文章。 Forge 上。 为什么选择铸造: 有许多智能合约开发工具,例如 Truffle、Hardhat 和 Brownie。但我首先研究 Dapp Tools 的主要原因之一是原生 Solidity 测试。在 Hardhat 和 Brownie 等框架之间切换时,编写智能合约并不难。它们是带有插件的令人难以置信的工具,但需要精通 JavaScript/TypeScript 和 Python 才能执行测试。 Foundry 允许我们在 Solidity 中本地编写测试。这可以节省大量新开发人员的入职时间,并使流程更加顺畅。根据我帮助人们进入智能合约开发的经验,我了解到初级开发人员参与 DAO/社区维护项目的最佳和最有效的方式是编写测试和了解代码库本身。我记得 曾经提到他们在 上开发 Alchemix Finance 时使用了相同的方法。 Scupy Trooples Bankless 除此之外,内置的模糊测试、作弊码、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。这里非常不言自明,您在 中编写合约,在 test 中编写 ,并且 包含您安装的所有库,例如 OpenZeppelin。除此之外,如果您使用过这些框架,您还会获得包含所有配置的 ,就像 和 一样。另一个好东西是 .github,您可以在其中编写您的 Github Actions。我发现在团队中工作时它对测试非常有帮助。 src test lib foundry.toml hardhat.config.js brownie-config.yaml 让我们开始建造吧!我们将创建一个名为 Figbot 的简单 NFT,其供应量、成本(用于铸币)和提款都是有限的。通过这种方法,我们可以覆盖不同测试的边缘。首先,将 和 分别重命名为 和 。现在,如果没有 Openzeppelin,我们就无法编写智能合约,不是吗? Contract.sol test/Contract.t.sol Figbot.sol Figbot.t.sol 使用 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。是时候使用 将我们的 上传到 IPFS 了。我们使用 Ownable 合约来设置部署地址的 ,并且可以访问 修饰符以只允许所有者提取资金。 帮助我们处理代币 ID 和 ,以保持 NFT 合约的简单性。 Pinata 资产 owner onlyOwner Counters ERC721URIStorage 设置状态变量: 至 100 MAX_SUPPLY 为 0.69 以太币 COST 到 CID,我们从 Pinata 收到 TOKEN_URI 使用 Counter 获取令牌 ID: using Counters for Counters.Counter; Counters.Counter private tokenIds; ERC721 构造函数: constructor() ERC721(“Figbot”, “FBT”) {} 薄荷功能: 检查 是否大于 msg.value COST 检查 是否大于或等于 tokenIds.current() MAX_SUPPLY 执行 和 _safeMint _setTokenURI 提现功能: 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); } TotalSupply 函数: function totalSupply() public view returns (uint256) { return _tokenIds.current(); } 测试合约: 众所周知,测试我们的智能合约非常重要。在本节中,我们将编写一些测试来深入了解 并习惯于在原生 Solidity 中编写测试。我们将使用三个 (我喜欢它们!)来管理帐户状态以适应我们的测试场景。 forge test Foundry 作弊码 我们将针对以下场景进行测试: 最大供应 成功的薄荷 由于余额不足导致铸币失败 取款(由所有者) 秘籍 因为我们的智能合约中可以有复杂的逻辑。并且它们的行为会根据状态、用于调用的帐户、时间等而有所不同。为了应对这种情况,我们可以使用作弊码来管理区块链的状态。我们可以使用 实例来使用这些作弊码,它是 Foundry 的 库的一部分。 vm Test 我们将在测试中使用三个作弊码: :为所有后续调用设置 ,直到调用 。 startPrank msg.sender stopPrank : stopPrank 停止由 启动的活动恶作剧,将 和 重置为调用 之前的值。 startPrank msg.sender tx.origin startPrank :将地址提供地址的余额设置为给定余额。 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(); } } 对于状态变量,我们创建了一个 类型的变量 。这也是我喜欢定义用户帐户的地方。在 Foundry 中,您可以使用语法 来描述地址。您可以为此使用任意四个字母数字字符。我分别创建了名为 owner、Alice 和 bob 的帐户。 figbot Figbot address(0x1243) 现在我们的 函数。这是在 Foundry 中编写测试的要求。这是我们进行所有部署和这种性质的事情的地方。我使用作弊码 将用户切换为“所有者”。默认情况下,Foundry 使用特定地址来部署测试合约。但这使得测试具有诸如 等特权的函数变得更加困难。因此,我们切换到此部署的“所有者”帐户。 setUp startPrank withdrawFunds 测试 MaxSupply: 从一个简单的断言测试开始学习 Foundry 约定。按照惯例,所有的测试函数都必须有前缀 。我们使用 来测试两个值是否相等。 test assertEq 我们调用 函数并测试结果值是否为 100,正如我们在合同中描述的那样。我们使用 来运行我们的测试。 MaxSupply forge test 瞧!我们通过了测试。 测试薄荷: 现在我们已经编写了一个简单的测试,让我们用作弊码编写一个。我们合约的主要功能。 将用户帐户切换到 Alice。 将 Alice 的余额设置为 1 个以太币 调用 mint 函数 检查 Alice 是否为 1 balanceOf 测试失败薄荷: 我们有另一个测试函数用于我们预计会失败的测试。用于此类测试的前缀是 。如果调用者资金不足,我们将测试 函数是否恢复。 testFail mint 将用户帐户切换到 Bob 将 Bob 的余额设置为 0.5 ether(我们的 NFT 是 0.69 ether) 调用 mint 函数(由于资金不足将被还原) 检查 Bob 是否为 1 balanceOf 因为 mint 没有通过,Bob 的余额不会是 1。因此,它会失败,这正是我们使用 的原因。因此,当您运行 时,它将通过。 testFail forge test 测试退出: 在这里,我们将测试一个只有“所有者”才能成功执行的功能。对于这个测试,我们将: 将用户切换到 Bob 给 Bob 的账户 1 个以太币的余额 从 Bob 的账户中铸造一个 Figbot(这将使合约的余额为 0.69 以太币) 将用户切换到所有者帐户 执行 功能(如果成功,它应该使所有者的余额0.69 ether) withdrawFunds 为了验证,我们断言所有者的余额是否为 0.69 ether 部署: 现在我们已经测试了我们的合约,是时候部署它了。我们需要一个钱包的私钥(带有一些 Rinkeby 测试 ETH)和一个 RPC URL。对于我们的 RPC URL,我们将使用 。 Figment DataHu Figment DataHub 为我们提供了在 Web 3 上开发的基础设施。它支持多个链,如 Ethereum、Celo、Solana、Terra 等。 设置 Figment DataHub: 在 上创建一个帐户。 Figment DataHub 点击“创建新应用”。 填写应用名称。 为环境选择“暂存”。 从提供的选项中选择“以太坊”。 您可以从“协议”选项卡下获取 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 编写、测试和部署了智能合约。但我们还没有完全完成。我们现在要验证我们的合同。我们需要为此设置我们的 API 密钥。 Etherscan 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 编写、测试和部署智能合约。我希望你喜欢这篇文章并从中学习。我确实很喜欢写这个。随时让我知道您对此的想法。